Snap for 10839468 from 850f40aa27db542f88521a70f1149a0a4eb1b3cc to studio-iguana-release

Change-Id: Ieb228e722c22fb4a96ecde49fad8527e9510f242
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 6e2f51b..12cef78 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -154,6 +154,7 @@
       <module fileurl="file://$PROJECT_DIR$/apkanalyzer/intellij.android.apkanalyzer.iml" filepath="$PROJECT_DIR$/apkanalyzer/intellij.android.apkanalyzer.iml" />
       <module fileurl="file://$PROJECT_DIR$/app-quality-insights/api/intellij.android.app-quality-insights.api.iml" filepath="$PROJECT_DIR$/app-quality-insights/api/intellij.android.app-quality-insights.api.iml" />
       <module fileurl="file://$PROJECT_DIR$/app-quality-insights/ide/intellij.android.app-quality-insights.ide.iml" filepath="$PROJECT_DIR$/app-quality-insights/ide/intellij.android.app-quality-insights.ide.iml" />
+      <module fileurl="file://$PROJECT_DIR$/app-quality-insights/ide/gradle/intellij.android.app-quality-insights.ide.gradle.iml" filepath="$PROJECT_DIR$/app-quality-insights/ide/gradle/intellij.android.app-quality-insights.ide.gradle.iml" />
       <module fileurl="file://$PROJECT_DIR$/app-quality-insights/ide/intellij.android.app-quality-insights.ide.tests.iml" filepath="$PROJECT_DIR$/app-quality-insights/ide/intellij.android.app-quality-insights.ide.tests.iml" />
       <module fileurl="file://$PROJECT_DIR$/app-quality-insights/play-vitals/ide/intellij.android.app-quality-insights.play-vitals.ide.iml" filepath="$PROJECT_DIR$/app-quality-insights/play-vitals/ide/intellij.android.app-quality-insights.play-vitals.ide.iml" />
       <module fileurl="file://$PROJECT_DIR$/app-quality-insights/play-vitals/ide/intellij.android.app-quality-insights.play-vitals.ide.tests.iml" filepath="$PROJECT_DIR$/app-quality-insights/play-vitals/ide/intellij.android.app-quality-insights.play-vitals.ide.tests.iml" />
diff --git a/.idea/runConfigurations/ASfP.xml b/.idea/runConfigurations/ASfP.xml
index 8f4ecf1..5a887ab 100644
--- a/.idea/runConfigurations/ASfP.xml
+++ b/.idea/runConfigurations/ASfP.xml
@@ -8,7 +8,7 @@
     <option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
     <module name="asfp.studio" />
     <shortenClasspath name="ARGS_FILE" />
-    <option name="VM_PARAMETERS" value="@$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/default_user_jvm_args.txt @$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/required_jvm_args.txt -ea -Dapple.laf.useScreenMenuBar=true -Dsun.awt.disablegrab=true -Didea.jre.check=true -Didea.is.internal=true -Didea.debug.mode=true -Didea.paths.selector=AndroidStudioForPlatformDev -Didea.force.use.core.classloader=true -Dplugin.path=$PROJECT_DIR$/../../../prebuilts/tools/common/ide-perf-plugin/ide-perf -javaagent:$PROJECT_DIR$/../../../bazel-bin/tools/base/threading-agent/threading_agent.jar -Dpty4j.preferred.native.folder=$PROJECT_DIR$/../../../prebuilts/studio/intellij-sdk/AI/$SDK_PLATFORM$/lib/pty4j" />
+    <option name="VM_PARAMETERS" value="@$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/default_user_jvm_args.txt @$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/required_jvm_args.txt -ea -Dapple.laf.useScreenMenuBar=true -Dsun.awt.disablegrab=true -Didea.jre.check=true -Didea.is.internal=true -Didea.debug.mode=true -Dkotlinx.coroutines.debug=on -Didea.paths.selector=AndroidStudioForPlatformDev -Didea.force.use.core.classloader=true -Dplugin.path=$PROJECT_DIR$/../../../prebuilts/tools/common/ide-perf-plugin/ide-perf -javaagent:$PROJECT_DIR$/../../../bazel-bin/tools/base/threading-agent/threading_agent.jar -Dpty4j.preferred.native.folder=$PROJECT_DIR$/../../../prebuilts/studio/intellij-sdk/AI/$SDK_PLATFORM$/lib/pty4j" />
     <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/../../.." />
     <method v="2">
       <option name="Make" enabled="true" />
diff --git a/.idea/runConfigurations/ASwB.xml b/.idea/runConfigurations/ASwB.xml
index 310a5e5..25915ba 100644
--- a/.idea/runConfigurations/ASwB.xml
+++ b/.idea/runConfigurations/ASwB.xml
@@ -8,7 +8,7 @@
     <option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
     <module name="aswb.jcgdi.blaze.plugin.aswb" />
     <shortenClasspath name="ARGS_FILE" />
-    <option name="VM_PARAMETERS" value="@$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/default_user_jvm_args.txt @$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/required_jvm_args.txt -ea -Xms5G -Xmx8G -XX:+FlightRecorder -Didea.is.internal=true -Didea.force.use.core.classloader=true -Dapple.laf.useScreenMenuBar=true -Dsun.awt.disablegrab=true -Didea.jre.check=true -Didea.debug.mode=true -Didea.paths.selector=AndroidStudioWithBlazeDev -Dplugin.path=$PROJECT_DIR$/../../../prebuilts/tools/common/ide-perf-plugin/ide-perf -Ddisable.android.first.run=true -Dcaches.indexerThreadsCount=16 -Dstudio.projectview=true -Didea.classpath.index.enabled=false -Dandroid.sdk.custom.url=file:///google/src/head/depot/google3/third_party/android/sdk_repo/repository.xml -Dide.index.image.max.size=0 -Dide.old.project.model=true -Ddesign.tools.project.system.class.loader.cache.max.size=1000000000 -Dpty4j.preferred.native.folder=$PROJECT_DIR$/../../../prebuilts/studio/intellij-sdk/AI/$SDK_PLATFORM$/lib/pty4j" />
+    <option name="VM_PARAMETERS" value="@$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/default_user_jvm_args.txt @$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/required_jvm_args.txt -ea -Xms5G -Xmx8G -XX:+FlightRecorder -Didea.is.internal=true -Didea.force.use.core.classloader=true -Dapple.laf.useScreenMenuBar=true -Dsun.awt.disablegrab=true -Didea.jre.check=true -Didea.debug.mode=true -Dkotlinx.coroutines.debug=on -Didea.paths.selector=AndroidStudioWithBlazeDev -Dplugin.path=$PROJECT_DIR$/../../../prebuilts/tools/common/ide-perf-plugin/ide-perf -Ddisable.android.first.run=true -Dcaches.indexerThreadsCount=16 -Dstudio.projectview=true -Didea.classpath.index.enabled=false -Dandroid.sdk.custom.url=file:///google/src/head/depot/google3/third_party/android/sdk_repo/repository.xml -Dide.index.image.max.size=0 -Dide.old.project.model=true -Ddesign.tools.project.system.class.loader.cache.max.size=1000000000 -Dpty4j.preferred.native.folder=$PROJECT_DIR$/../../../prebuilts/studio/intellij-sdk/AI/$SDK_PLATFORM$/lib/pty4j" />
     <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/../../.." />
     <method v="2">
       <option name="Make" enabled="true" />
diff --git a/.idea/runConfigurations/Android_Studio.xml b/.idea/runConfigurations/Android_Studio.xml
index f08da96..9b56f8d 100644
--- a/.idea/runConfigurations/Android_Studio.xml
+++ b/.idea/runConfigurations/Android_Studio.xml
@@ -8,7 +8,7 @@
     <option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
     <module name="studio" />
     <shortenClasspath name="ARGS_FILE" />
-    <option name="VM_PARAMETERS" value="@$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/default_user_jvm_args.txt @$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/required_jvm_args.txt -ea -Dapple.laf.useScreenMenuBar=true -Dsun.awt.disablegrab=true -Didea.jre.check=true -Didea.is.internal=true -Didea.debug.mode=true -Didea.paths.selector=AndroidStudioDev -Daida.api.set.client=ANDROID_STUDIO_TESTERS -Didea.force.use.core.classloader=true -Dplugin.path=$PROJECT_DIR$/../../../prebuilts/tools/common/ide-perf-plugin/ide-perf -javaagent:$PROJECT_DIR$/../../../bazel-bin/tools/base/threading-agent/threading_agent.jar -Dpty4j.preferred.native.folder=$PROJECT_DIR$/../../../prebuilts/studio/intellij-sdk/AI/$SDK_PLATFORM$/lib/pty4j" />
+    <option name="VM_PARAMETERS" value="@$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/default_user_jvm_args.txt @$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/required_jvm_args.txt -ea -Dapple.laf.useScreenMenuBar=true -Dsun.awt.disablegrab=true -Didea.jre.check=true -Didea.is.internal=true -Didea.debug.mode=true -Dkotlinx.coroutines.debug=on -Didea.paths.selector=AndroidStudioDev -Daida.api.set.client=ANDROID_STUDIO_TESTERS -Didea.force.use.core.classloader=true -Dplugin.path=$PROJECT_DIR$/../../../prebuilts/tools/common/ide-perf-plugin/ide-perf -javaagent:$PROJECT_DIR$/../../../bazel-bin/tools/base/threading-agent/threading_agent.jar -Dpty4j.preferred.native.folder=$PROJECT_DIR$/../../../prebuilts/studio/intellij-sdk/AI/$SDK_PLATFORM$/lib/pty4j" />
     <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/../../.." />
     <method v="2">
       <option name="Make" enabled="true" />
diff --git a/.idea/runConfigurations/Game_Tools.xml b/.idea/runConfigurations/Game_Tools.xml
index 8675b9f..1ab8d2f 100644
--- a/.idea/runConfigurations/Game_Tools.xml
+++ b/.idea/runConfigurations/Game_Tools.xml
@@ -10,7 +10,7 @@
     <module name="android.game-tools.main" />
     <option name="PROGRAM_PARAMETERS" value="game-tools --mode APP --app-window PROFILER" />
     <shortenClasspath name="ARGS_FILE" />
-    <option name="VM_PARAMETERS" value="-ea -Xms512m -Xmx1024m -XX:ReservedCodeCacheSize=240m -XX:+UseG1GC -XX:SoftRefLRUPolicyMSPerMB=50 -XX:MaxJavaStackTraceDepth=10000 -Didea.is.internal=true -Didea.force.use.core.classloader=true -Didea.platform.prefix=AndroidGameDevelopmentTools -Dsun.awt.disablegrab=true -Dawt.useSystemAAFontSettings=lcd -Dsun.io.useCanonCaches=false -Djava.net.preferIPv4Stack=true -Didea.jre.check=true -Didea.debug.mode=true -Dsun.java2d.renderer=sun.java2d.marlin.MarlinRenderingEngine -Didea.load.plugins=false -Didea.initially.ask.config=force-not -Djava.system.class.loader=com.intellij.util.lang.PathClassLoader -Didea.vendor.name=Google -Didea.paths.selector=GameToolsDev -Didea.ui.icons.svg.disk.cache=false -Djna.boot.library.path=$PROJECT_DIR$/../../../prebuilts/studio/intellij-sdk/AI/$SDK_PLATFORM$/lib/jna/amd64/ --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.ref=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.base/jdk.internal.vm=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/sun.nio.fs=ALL-UNNAMED --add-opens=java.base/sun.security.ssl=ALL-UNNAMED --add-opens=java.base/sun.security.util=ALL-UNNAMED --add-opens=java.desktop/com.apple.eawt=ALL-UNNAMED --add-opens=java.desktop/com.apple.eawt.event=ALL-UNNAMED --add-opens=java.desktop/com.apple.laf=ALL-UNNAMED --add-opens=java.desktop/java.awt=ALL-UNNAMED --add-opens=java.desktop/java.awt.dnd.peer=ALL-UNNAMED --add-opens=java.desktop/java.awt.event=ALL-UNNAMED --add-opens=java.desktop/java.awt.image=ALL-UNNAMED --add-opens=java.desktop/java.awt.peer=ALL-UNNAMED --add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED --add-opens=java.desktop/javax.swing=ALL-UNNAMED --add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED --add-opens=java.desktop/javax.swing.text.html=ALL-UNNAMED --add-opens=java.desktop/sun.awt.datatransfer=ALL-UNNAMED --add-opens=java.desktop/sun.awt.image=ALL-UNNAMED --add-opens=java.desktop/sun.awt=ALL-UNNAMED --add-opens=java.desktop/sun.font=ALL-UNNAMED --add-opens=java.desktop/sun.java2d=ALL-UNNAMED --add-opens=java.desktop/sun.lwawt=ALL-UNNAMED --add-opens=java.desktop/sun.lwawt.macosx=ALL-UNNAMED --add-opens=java.desktop/sun.swing=ALL-UNNAMED --add-opens=jdk.attach/sun.tools.attach=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-opens=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED --add-opens=jdk.jdi/com.sun.tools.jdi=ALL-UNNAMED --add-opens=java.desktop/sun.awt.windows=ALL-UNNAMED" />
+    <option name="VM_PARAMETERS" value="-ea -Xms512m -Xmx1024m -XX:ReservedCodeCacheSize=240m -XX:+UseG1GC -XX:SoftRefLRUPolicyMSPerMB=50 -XX:MaxJavaStackTraceDepth=10000 -Didea.is.internal=true -Didea.force.use.core.classloader=true -Didea.platform.prefix=AndroidGameDevelopmentTools -Dsun.awt.disablegrab=true -Dawt.useSystemAAFontSettings=lcd -Dsun.io.useCanonCaches=false -Djava.net.preferIPv4Stack=true -Didea.jre.check=true -Didea.debug.mode=true -Dkotlinx.coroutines.debug=on -Dsun.java2d.renderer=sun.java2d.marlin.MarlinRenderingEngine -Didea.load.plugins=false -Didea.initially.ask.config=force-not -Djava.system.class.loader=com.intellij.util.lang.PathClassLoader -Didea.vendor.name=Google -Didea.paths.selector=GameToolsDev -Didea.ui.icons.svg.disk.cache=false -Djna.boot.library.path=$PROJECT_DIR$/../../../prebuilts/studio/intellij-sdk/AI/$SDK_PLATFORM$/lib/jna/amd64/ --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.ref=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.base/jdk.internal.vm=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/sun.nio.fs=ALL-UNNAMED --add-opens=java.base/sun.security.ssl=ALL-UNNAMED --add-opens=java.base/sun.security.util=ALL-UNNAMED --add-opens=java.desktop/com.apple.eawt=ALL-UNNAMED --add-opens=java.desktop/com.apple.eawt.event=ALL-UNNAMED --add-opens=java.desktop/com.apple.laf=ALL-UNNAMED --add-opens=java.desktop/java.awt=ALL-UNNAMED --add-opens=java.desktop/java.awt.dnd.peer=ALL-UNNAMED --add-opens=java.desktop/java.awt.event=ALL-UNNAMED --add-opens=java.desktop/java.awt.image=ALL-UNNAMED --add-opens=java.desktop/java.awt.peer=ALL-UNNAMED --add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED --add-opens=java.desktop/javax.swing=ALL-UNNAMED --add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED --add-opens=java.desktop/javax.swing.text.html=ALL-UNNAMED --add-opens=java.desktop/sun.awt.datatransfer=ALL-UNNAMED --add-opens=java.desktop/sun.awt.image=ALL-UNNAMED --add-opens=java.desktop/sun.awt=ALL-UNNAMED --add-opens=java.desktop/sun.font=ALL-UNNAMED --add-opens=java.desktop/sun.java2d=ALL-UNNAMED --add-opens=java.desktop/sun.lwawt=ALL-UNNAMED --add-opens=java.desktop/sun.lwawt.macosx=ALL-UNNAMED --add-opens=java.desktop/sun.swing=ALL-UNNAMED --add-opens=jdk.attach/sun.tools.attach=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-opens=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED --add-opens=jdk.jdi/com.sun.tools.jdi=ALL-UNNAMED --add-opens=java.desktop/sun.awt.windows=ALL-UNNAMED" />
     <method v="2">
       <option name="Make" enabled="true" />
       <option name="BuildArtifacts" enabled="true" />
diff --git a/.idea/runConfigurations/K2.xml b/.idea/runConfigurations/K2.xml
index 2fe45dc..119bb56 100644
--- a/.idea/runConfigurations/K2.xml
+++ b/.idea/runConfigurations/K2.xml
@@ -8,7 +8,7 @@
     <option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
     <module name="studio" />
     <shortenClasspath name="ARGS_FILE" />
-    <option name="VM_PARAMETERS" value="@$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/default_user_jvm_args.txt @$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/required_jvm_args.txt -ea -Dapple.laf.useScreenMenuBar=true -Dsun.awt.disablegrab=true -Didea.jre.check=true -Didea.is.internal=true -Didea.debug.mode=true -Didea.paths.selector=AndroidStudioDev -Didea.force.use.core.classloader=true -Didea.kotlin.plugin.use.k2=true -Dplugin.path=$PROJECT_DIR$/../../../prebuilts/tools/common/ide-perf-plugin/ide-perf -javaagent:$PROJECT_DIR$/../../../bazel-bin/tools/base/threading-agent/threading_agent.jar -Dpty4j.preferred.native.folder=$PROJECT_DIR$/../../../prebuilts/studio/intellij-sdk/AI/$SDK_PLATFORM$/lib/pty4j" />
+    <option name="VM_PARAMETERS" value="@$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/default_user_jvm_args.txt @$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/required_jvm_args.txt -ea -Dapple.laf.useScreenMenuBar=true -Dsun.awt.disablegrab=true -Didea.jre.check=true -Didea.is.internal=true -Didea.debug.mode=true -Dkotlinx.coroutines.debug=on -Didea.paths.selector=AndroidStudioDev -Didea.force.use.core.classloader=true -Didea.kotlin.plugin.use.k2=true -Dplugin.path=$PROJECT_DIR$/../../../prebuilts/tools/common/ide-perf-plugin/ide-perf -javaagent:$PROJECT_DIR$/../../../bazel-bin/tools/base/threading-agent/threading_agent.jar -Dpty4j.preferred.native.folder=$PROJECT_DIR$/../../../prebuilts/studio/intellij-sdk/AI/$SDK_PLATFORM$/lib/pty4j" />
     <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/../../.." />
     <method v="2">
       <option name="Make" enabled="true" />
diff --git a/.idea/runConfigurations/_template__of_JUnit.xml b/.idea/runConfigurations/_template__of_JUnit.xml
index 562b392..c21891a 100644
--- a/.idea/runConfigurations/_template__of_JUnit.xml
+++ b/.idea/runConfigurations/_template__of_JUnit.xml
@@ -9,7 +9,7 @@
     <option name="MAIN_CLASS_NAME" value="" />
     <option name="METHOD_NAME" value="" />
     <option name="TEST_OBJECT" value="class" />
-    <option name="VM_PARAMETERS" value="@$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/default_user_jvm_args.txt @$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/required_jvm_args.txt -ea -Duser.home=$PROJECT_DIR$/test-temp/user/home -Didea.config.path=$PROJECT_DIR$/test-temp/config -Didea.force.use.core.classloader=true -Didea.system.path=$PROJECT_DIR$/test-temp/system -Didea.plugins.path=$PROJECT_DIR$/test-temp/plugins -Didea.log.config.file=$PROJECT_DIR$/adt-testutils/test-log.xml -Dkotlin.script.classpath=" />
+    <option name="VM_PARAMETERS" value="@$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/default_user_jvm_args.txt @$PROJECT_DIR$/../../../bazel-bin/tools/adt/idea/studio/required_jvm_args.txt -ea -Dkotlinx.coroutines.debug=on -Duser.home=$PROJECT_DIR$/test-temp/user/home -Didea.config.path=$PROJECT_DIR$/test-temp/config -Didea.force.use.core.classloader=true -Didea.system.path=$PROJECT_DIR$/test-temp/system -Didea.plugins.path=$PROJECT_DIR$/test-temp/plugins -Didea.log.config.file=$PROJECT_DIR$/adt-testutils/test-log.xml -Dkotlin.script.classpath=" />
     <option name="PARAMETERS" value="" />
     <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/../../.." />
     <option name="PASS_PARENT_ENVS" value="false" />
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index fd1f24c..b7d4f9b 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -2,7 +2,7 @@
 [Builtin Hooks]
 ktfmt = true
 [Builtin Hooks Options]
-ktfmt = --include-dirs=app-inspection,app-quality-insights,assistant,compose-designer,dagger,designer,device-manager-v2,glance-designer,preview-designer,rendering,android-lint/src,android-lint/testSrc,lint/src,lint/tests/testSrc,layout-inspector,layout-ui,intellij.android.avdmanager.tests --google-style
+ktfmt = --include-dirs=app-inspection,app-quality-insights,assistant,compose-designer,dagger,designer,device-manager-v2,glance-designer,preview-designer,rendering,android-lint/src,android-lint/testSrc,lint/src,lint/tests/testSrc,layout-inspector,layout-ui,intellij.android.avdmanager.tests,compose-ide-plugin,nav/safeargs --google-style
 [Tool Paths]
 ktfmt = ${REPO_ROOT}/prebuilts/tools/common/ktfmt/ktfmt
 
diff --git a/adt-ui/src/main/java/com/android/tools/adtui/actions/EnableSwingProfilerAction.java b/adt-ui/src/main/java/com/android/tools/adtui/actions/EnableSwingProfilerAction.java
index e23122c..5d64ce2 100644
--- a/adt-ui/src/main/java/com/android/tools/adtui/actions/EnableSwingProfilerAction.java
+++ b/adt-ui/src/main/java/com/android/tools/adtui/actions/EnableSwingProfilerAction.java
@@ -16,6 +16,7 @@
 package com.android.tools.adtui.actions;
 
 import com.intellij.ide.BrowserUtil;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.PathManager;
@@ -45,6 +46,12 @@
   }
 
   @Override
+  @NotNull
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
+  @Override
   public boolean isSelected(@NotNull AnActionEvent e) {
     return SERVICE_KEY.isIn(ApplicationManager.getApplication());
   }
diff --git a/android-adb/src/com/android/tools/idea/adb/StudioAdbLibSCacheJdwpSessionPipeline.kt b/android-adb/src/com/android/tools/idea/adb/StudioAdbLibSCacheJdwpSessionPipeline.kt
index a8c6617..a0f8c90 100644
--- a/android-adb/src/com/android/tools/idea/adb/StudioAdbLibSCacheJdwpSessionPipeline.kt
+++ b/android-adb/src/com/android/tools/idea/adb/StudioAdbLibSCacheJdwpSessionPipeline.kt
@@ -16,16 +16,16 @@
 package com.android.tools.idea.adb
 
 import com.android.adblib.AdbSession
-import com.android.adblib.thisLogger
+import com.android.adblib.adbLogger
 import com.android.adblib.tools.debugging.JdwpSessionPipeline
 import com.android.adblib.tools.debugging.SharedJdwpSessionMonitor
-import com.android.adblib.tools.debugging.utils.SynchronizedChannel
-import com.android.adblib.tools.debugging.utils.SynchronizedReceiveChannel
-import com.android.adblib.tools.debugging.utils.SynchronizedSendChannel
 import com.android.adblib.tools.debugging.packets.JdwpPacketView
 import com.android.adblib.tools.debugging.packets.writeToBuffer
 import com.android.adblib.tools.debugging.receiveAllPacketsCatching
 import com.android.adblib.tools.debugging.sendPacket
+import com.android.adblib.tools.debugging.utils.SynchronizedChannel
+import com.android.adblib.tools.debugging.utils.SynchronizedReceiveChannel
+import com.android.adblib.tools.debugging.utils.SynchronizedSendChannel
 import com.android.adblib.tools.debugging.utils.receiveAllCatching
 import com.android.adblib.utils.ResizableBuffer
 import com.android.jdwpscache.SCacheResponse
@@ -41,7 +41,7 @@
   private val sessionMonitor: SharedJdwpSessionMonitor?,
   private val debuggerPipeline: JdwpSessionPipeline,
 ) : JdwpSessionPipeline {
-  private val logger = thisLogger(session)
+  private val logger = adbLogger(session)
 
   /**
    * The actual SCache implementation.
diff --git a/android-adb/src/com/android/tools/idea/adb/wireless/PairDevicesUsingWiFiAction.kt b/android-adb/src/com/android/tools/idea/adb/wireless/PairDevicesUsingWiFiAction.kt
index bc140c5..56f7465 100644
--- a/android-adb/src/com/android/tools/idea/adb/wireless/PairDevicesUsingWiFiAction.kt
+++ b/android-adb/src/com/android/tools/idea/adb/wireless/PairDevicesUsingWiFiAction.kt
@@ -16,20 +16,19 @@
 package com.android.tools.idea.adb.wireless
 
 import com.android.annotations.concurrency.UiThread
+import com.intellij.openapi.actionSystem.ActionUpdateThread
 import com.intellij.openapi.actionSystem.AnAction
 import com.intellij.openapi.actionSystem.AnActionEvent
 import icons.StudioIcons
 
 /** The action to show the [WiFiPairingDialog] window. */
 class PairDevicesUsingWiFiAction : AnAction(StudioIcons.Avd.PAIR_OVER_WIFI) {
-  @UiThread
   override fun update(e: AnActionEvent) {
-    super.update(e)
-    e.presentation.isEnabledAndVisible = false
-    val project = e.project ?: return
-    e.presentation.isEnabledAndVisible = true
+    e.presentation.isEnabledAndVisible = e.project != null
   }
 
+  override fun getActionUpdateThread() = ActionUpdateThread.BGT
+
   @UiThread
   override fun actionPerformed(event: AnActionEvent) {
     val project = event.project ?: return
diff --git a/android-adb/src/com/android/tools/idea/ddms/actions/GetAdbAction.java b/android-adb/src/com/android/tools/idea/ddms/actions/GetAdbAction.java
index 837a788..e1ec6a2 100644
--- a/android-adb/src/com/android/tools/idea/ddms/actions/GetAdbAction.java
+++ b/android-adb/src/com/android/tools/idea/ddms/actions/GetAdbAction.java
@@ -25,6 +25,7 @@
 import com.intellij.notification.Notification;
 import com.intellij.notification.NotificationType;
 import com.intellij.notification.Notifications;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.project.Project;
@@ -45,6 +46,12 @@
     e.getPresentation().setEnabled(adb != null && adb.exists());
   }
 
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
   @Override
   public void actionPerformed(@NotNull AnActionEvent e) {
     Notifications.Bus.notify(new Notification("Android", "ADB", "ADB requested.", NotificationType.INFORMATION));
diff --git a/android-common/src/com/android/tools/idea/flags/StudioFlags.java b/android-common/src/com/android/tools/idea/flags/StudioFlags.java
index f1726b3..fa97cd3 100644
--- a/android-common/src/com/android/tools/idea/flags/StudioFlags.java
+++ b/android-common/src/com/android/tools/idea/flags/StudioFlags.java
@@ -251,17 +251,17 @@
   public static final Flag<Boolean> NELE_ATF_FOR_COMPOSE = Flag.create(
     NELE, "atf.for.compose", "Enable ATF checks for Compose",
     "Allow running accessibility checks for Compose using ATF.",
-    false);
+    true);
 
   public static final Flag<Boolean> NELE_COMPOSE_UI_CHECK_MODE = Flag.create(
     NELE, "compose.ui.check.mode", "Enable UI Check mode for Compose preview",
     "Enable UI Check mode in Compose preview for running ATF checks and Visual Linting",
-    false);
+    true);
 
   public static final Flag<Boolean> NELE_COMPOSE_VISUAL_LINT_RUN = Flag.create(
     NELE, "compose.visual.lint.run", "Enable visual lint for Compose Preview",
     "Enable so that visual lint runs on previews in the Compose Preview.",
-    false);
+    true);
 
   public static final Flag<Boolean> NELE_CLASS_PRELOADING_DIAGNOSTICS = Flag.create(
     NELE, "preview.class.preloading.diagnostics", "Enable class preloading overlay",
@@ -1436,6 +1436,14 @@
       "Enable FTL DirectAccess",
       false);
 
+  public static final Flag<Boolean> USE_UXR_202309_FILTER =
+    Flag.create(
+      FIREBASE_TEST_LAB,
+      "direct.access.uxr202309",
+      "UXR 202309 Device Filter",
+      "Use custom device filter (for 2023-09 UXR study)",
+      false);
+
   public static final Flag<Boolean> DIRECT_ACCESS_ADD_DEVICE =
     Flag.create(
       FIREBASE_TEST_LAB,
@@ -1533,11 +1541,15 @@
                 "Revamped App Links Assistant (new surfaces and navigation between surfaces).", true);
   public static final Flag<Boolean> WEBSITE_ASSOCIATION_GENERATOR_V2 =
     Flag.create(APP_LINKS_ASSISTANT, "website.association.generator.v2", "Website Association Generator V2",
-                "Improvements to Website Association Generator.", false);
+                "Improvements to Website Association Generator.", true);
   public static final Flag<String> DEEPLINKS_GRPC_SERVER =
     Flag.create(APP_LINKS_ASSISTANT, "deeplinks.grpc.server", "Deep links gRPC server address",
                 "Deep links gRPC server address. Use a non-default value for testing purposes.",
                 "deeplinkassistant-pa.googleapis.com");
+
+  public static final Flag<Boolean> CREATE_APP_LINKS_V2 =
+    Flag.create(APP_LINKS_ASSISTANT, "create.app.links.v2", "Create App Links V2",
+                "Improvements to the Create App Links functionalities.", false);
   // endregion App Links Assistant
 
   // region GOOGLE_PLAY_SDK_INDEX
diff --git a/device-manager/testSrc/com/android/tools/idea/devicemanager/CountDownLatchAssert.java b/android-common/test/com/android/tools/idea/concurrency/CountDownLatchAssert.java
similarity index 95%
rename from device-manager/testSrc/com/android/tools/idea/devicemanager/CountDownLatchAssert.java
rename to android-common/test/com/android/tools/idea/concurrency/CountDownLatchAssert.java
index 368b049..a7601fe 100644
--- a/device-manager/testSrc/com/android/tools/idea/devicemanager/CountDownLatchAssert.java
+++ b/android-common/test/com/android/tools/idea/concurrency/CountDownLatchAssert.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.tools.idea.devicemanager;
+package com.android.tools.idea.concurrency;
 
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
diff --git a/device-manager/testSrc/com/android/tools/idea/devicemanager/CountDownLatchFutureCallback.java b/android-common/test/com/android/tools/idea/concurrency/CountDownLatchFutureCallback.java
similarity index 96%
rename from device-manager/testSrc/com/android/tools/idea/devicemanager/CountDownLatchFutureCallback.java
rename to android-common/test/com/android/tools/idea/concurrency/CountDownLatchFutureCallback.java
index 9f7d2c7..3307b12 100644
--- a/device-manager/testSrc/com/android/tools/idea/devicemanager/CountDownLatchFutureCallback.java
+++ b/android-common/test/com/android/tools/idea/concurrency/CountDownLatchFutureCallback.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.tools.idea.devicemanager;
+package com.android.tools.idea.concurrency;
 
 import com.google.common.util.concurrent.FutureCallback;
 import java.util.concurrent.CountDownLatch;
diff --git a/android-lang/src/com/android/tools/idea/lang/proguardR8/ProguardR8CompletionContributor.kt b/android-lang/src/com/android/tools/idea/lang/proguardR8/ProguardR8CompletionContributor.kt
index 9a9555e..44008ff 100644
--- a/android-lang/src/com/android/tools/idea/lang/proguardR8/ProguardR8CompletionContributor.kt
+++ b/android-lang/src/com/android/tools/idea/lang/proguardR8/ProguardR8CompletionContributor.kt
@@ -45,7 +45,7 @@
 import com.intellij.util.ProcessingContext
 
 /**
- * Provides code completion for key words for proguardR8 files
+ * Provides code completion for keywords for proguardR8 files
  *
  * Provides code completion for flags, java keywords and proguardR8 specific wildcards
  */
@@ -234,7 +234,7 @@
       flagCompletionProvider
     )
 
-    // Add completion for java key words ("private", "public" ...) inside class specification body
+    // Add completion for java keywords ("private", "public" ...) inside class specification body
     extend(
       CompletionType.BASIC,
       or(startOfNewJavaRule, afterFieldOrMethodModifier, insideClassSpecification.afterLeaf("!")),
@@ -312,7 +312,7 @@
 
   override fun beforeCompletion(context: CompletionInitializationContext) {
     if (context.file is ProguardR8PsiFile) {
-      // We need lower case identifier because original ("IntellijIdeaRulezzz") breaks lexer for flags (flags can be only lowercase).
+      // We need lower case identifier because original ("IntellijIdeaRule") breaks lexer for flags (flags can be only lowercase).
       context.dummyIdentifier = lowerCaseIdentifier
     }
     super.beforeCompletion(context)
diff --git a/android-lang/src/com/android/tools/idea/lang/proguardR8/psi/ProguardR8PsiImplUtil.kt b/android-lang/src/com/android/tools/idea/lang/proguardR8/psi/ProguardR8PsiImplUtil.kt
index 6565127..ecd1b4b 100644
--- a/android-lang/src/com/android/tools/idea/lang/proguardR8/psi/ProguardR8PsiImplUtil.kt
+++ b/android-lang/src/com/android/tools/idea/lang/proguardR8/psi/ProguardR8PsiImplUtil.kt
@@ -29,6 +29,7 @@
 import com.intellij.psi.PsiPrimitiveType
 import com.intellij.psi.PsiReference
 import com.intellij.psi.PsiType
+import com.intellij.psi.PsiTypes
 import com.intellij.psi.impl.source.PsiClassReferenceType
 import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference
 import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet
@@ -54,7 +55,7 @@
       object : JavaClassReferenceSet(str, position, offsetInPosition, false, this) {
         // If true allows inner classes to be separated by a dollar sign "$", e.g.java.lang.Thread$State
         // We can't just use ALLOW_DOLLAR_NAMES flag because to make JavaClassReferenceSet work in the way we want
-        // language of PsiElement that we parse should be instance of XMLLanguage.
+        // language of PsiElement that we parse should be an instance of XMLLanguage.
         override fun isAllowDollarInNames() = treatDollarAsSeparator
 
       }.allReferences as Array<PsiReference>
@@ -89,7 +90,7 @@
 }
 
 /**
- * Returns all resolvable psiClasses found in header, excluding classes that specified after "extends"/"implements" key words.
+ * Returns all resolvable psiClasses found in header, excluding classes that specified after "extends"/"implements" keywords.
  *
  * Example: for "-keep myClass1, myClass2 extends myClass3" returns "myClass1", "myClass2"
  */
@@ -98,7 +99,7 @@
 }
 
 /**
- * Returns classes in header that specified after "extends"/"implements" key words.
+ * Returns classes in header that specified after "extends"/"implements" keywords.
  */
 fun resolveSuperPsiClasses(classSpecificationHeader: ProguardR8ClassSpecificationHeader): List<PsiClass> {
   return classSpecificationHeader.superClassNameList.mapNotNull { it.qualifiedName.resolveToPsiClass() }
@@ -107,15 +108,15 @@
 fun getPsiPrimitive(proguardR8JavaPrimitive: ProguardR8JavaPrimitive): PsiPrimitiveType? {
   val primitive = proguardR8JavaPrimitive.node.firstChildNode
   return when (primitive.elementType) {
-    ProguardR8PsiTypes.BOOLEAN -> PsiPrimitiveType.BOOLEAN
-    ProguardR8PsiTypes.BYTE -> PsiPrimitiveType.BYTE
-    ProguardR8PsiTypes.CHAR -> PsiPrimitiveType.CHAR
-    ProguardR8PsiTypes.SHORT -> PsiPrimitiveType.SHORT
-    ProguardR8PsiTypes.INT -> PsiPrimitiveType.INT
-    ProguardR8PsiTypes.LONG -> PsiPrimitiveType.LONG
-    ProguardR8PsiTypes.FLOAT -> PsiPrimitiveType.FLOAT
-    ProguardR8PsiTypes.DOUBLE -> PsiPrimitiveType.DOUBLE
-    ProguardR8PsiTypes.VOID -> PsiPrimitiveType.VOID
+    ProguardR8PsiTypes.BOOLEAN -> PsiTypes.booleanType()
+    ProguardR8PsiTypes.BYTE -> PsiTypes.byteType()
+    ProguardR8PsiTypes.CHAR -> PsiTypes.charType()
+    ProguardR8PsiTypes.SHORT -> PsiTypes.shortType()
+    ProguardR8PsiTypes.INT -> PsiTypes.intType()
+    ProguardR8PsiTypes.LONG -> PsiTypes.longType()
+    ProguardR8PsiTypes.FLOAT -> PsiTypes.floatType()
+    ProguardR8PsiTypes.DOUBLE -> PsiTypes.doubleType()
+    ProguardR8PsiTypes.VOID -> PsiTypes.voidType()
     else -> {
       assert(false) { "Couldn't match ProguardR8JavaPrimitive \"${primitive.text}\" to PsiPrimitive" }
       null
@@ -126,7 +127,7 @@
 /**
  * Returns number of dimensions or 0 if there is error
  *
- * Examnple: For int[][][] it returns 3
+ * Example: For int[][][] it returns 3
  */
 fun getNumberOfDimensions(array: ProguardR8ArrayType): Int {
   if (PsiTreeUtil.hasErrorElements(array)) return 0
@@ -152,8 +153,8 @@
   return when {
     type.javaPrimitive != null -> type.javaPrimitive!!.psiPrimitive == typeToMatch
     type.qualifiedName != null && typeToMatch is PsiClassReferenceType -> type.qualifiedName!!.resolveToPsiClass() == typeToMatch.resolve()
-    // "%" matches any primitive type ("boolean", "int", etc, but not "void").
-    type.anyPrimitiveType != null -> typeToMatch is PsiPrimitiveType && typeToMatch != PsiPrimitiveType.VOID
+    // "%" matches any primitive type ("boolean", "int", etc., but not "void").
+    type.anyPrimitiveType != null -> typeToMatch is PsiPrimitiveType && typeToMatch != PsiTypes.voidType()
     type.anyNotPrimitiveType != null -> typeToMatch is PsiClassReferenceType
     type.anyType != null -> true
     else -> false
@@ -163,7 +164,7 @@
 /**
  * Returns true if ProguardR8Parameters doesn't have errors and matches given "other" PsiParameterList otherwise returns false
  *
- * In general it checks if every type within ProguardR8Parameters [matchesPsiType] type in PsiParameterList at the same position.
+ * In general, it checks if every type within ProguardR8Parameters [matchesPsiType] type in PsiParameterList at the same position.
  * Tricky case is when ProguardR8Parameters ends with '...' (matches any number of arguments of any type). In this case we need to check
  * that all types at positions before '...' match and after if there are still some types remain at PsiParameterList, we just ignore them.
  */
diff --git a/android-lang/testSrc/com/android/tools/idea/lang/multiDexKeep/MultiDexKeepReferenceTest.kt b/android-lang/testSrc/com/android/tools/idea/lang/multiDexKeep/MultiDexKeepReferenceTest.kt
index 9c491fa..9a57371 100644
--- a/android-lang/testSrc/com/android/tools/idea/lang/multiDexKeep/MultiDexKeepReferenceTest.kt
+++ b/android-lang/testSrc/com/android/tools/idea/lang/multiDexKeep/MultiDexKeepReferenceTest.kt
@@ -16,6 +16,7 @@
 package com.android.tools.idea.lang.multiDexKeep
 
 import com.android.tools.idea.testing.caret
+import com.android.tools.tests.AdtTestProjectDescriptors
 import com.google.common.truth.Truth.assertThat
 import com.intellij.psi.PsiClass
 import com.intellij.testFramework.PsiTestUtil
@@ -23,6 +24,12 @@
 
 class MultiDexKeepReferenceTest : AndroidTestCase() {
   override fun setUp() {
+    // These tests check if classes listed in multidex keep file are indeed kept.
+    // Inputs are .class files, and thus technically neither java nor kotlin.
+    // But using kotlin descriptor includes Kotlin stdlib, hence java instead.
+    // TODO(b/300170256): Remove this once 2023.3 merges
+    myProjectDescriptor = AdtTestProjectDescriptors.java()
+
     super.setUp()
     PsiTestUtil.addLibrary(myModule, "mylib", "", myFixture.testDataPath + "/maven/myjar/myjar-1.0.jar")
 
diff --git a/android-lang/testSrc/com/android/tools/idea/lang/proguardR8/ProguardR8CompletionContributorTest.kt b/android-lang/testSrc/com/android/tools/idea/lang/proguardR8/ProguardR8CompletionContributorTest.kt
index ba16ace..c6be40f 100644
--- a/android-lang/testSrc/com/android/tools/idea/lang/proguardR8/ProguardR8CompletionContributorTest.kt
+++ b/android-lang/testSrc/com/android/tools/idea/lang/proguardR8/ProguardR8CompletionContributorTest.kt
@@ -19,6 +19,8 @@
 import com.android.tools.idea.projectsystem.CodeShrinker
 import com.android.tools.idea.projectsystem.getModuleSystem
 import com.android.tools.idea.testing.caret
+import com.android.tools.tests.AdtTestProjectDescriptor
+import com.android.tools.tests.AdtTestProjectDescriptors
 import com.google.common.truth.Truth.assertThat
 import com.intellij.codeInsight.completion.JavaPsiClassReferenceElement
 import com.intellij.codeInsight.lookup.Lookup
@@ -26,6 +28,13 @@
 
 class ProguardR8CompletionContributorTest : ProguardR8TestCase() {
 
+  override fun getProjectDescriptor(): AdtTestProjectDescriptor {
+    // Proguard / R8 config file is neither jar nor kotlin.
+    // Having Kotlin stdlib makes [ProguardR8CompletionContributor] suggest all classes from stdlib whenever possible.
+    // TODO(b/300170256): Remove this once 2023.3 merges
+    return AdtTestProjectDescriptors.java()
+  }
+
   fun testFlagCompletion() {
 
     myFixture.configureByText(ProguardR8FileType.INSTANCE, """
@@ -220,7 +229,7 @@
 
     keys = myFixture.completeBasic()
 
-    // don't suggests after type
+    // don't suggest after type
     assertThat(keys.map { it.lookupString }.toList()).containsNoneOf("public", "private", "protected",
                                                                      "static", "synchronized", "native", "abstract", "strictfp",
                                                                      "volatile", "transient", "final")
@@ -573,7 +582,7 @@
 
 class ProguardR8FlagsCodeCompletion : AndroidTestCase() {
 
-  fun testFlagSuggestionRegardinShrinkerType() {
+  fun testFlagSuggestionRegardingShrinkerType() {
     (myModule.getModuleSystem() as DefaultModuleSystem).codeShrinker = CodeShrinker.R8
 
     val justProguardFlag = PROGUARD_FLAGS.minus(R8_FLAGS).first()
diff --git a/android-npw/src/com/android/tools/idea/npw/actions/AndroidNewProjectAction.kt b/android-npw/src/com/android/tools/idea/npw/actions/AndroidNewProjectAction.kt
index 10a31b8..a5988f7 100644
--- a/android-npw/src/com/android/tools/idea/npw/actions/AndroidNewProjectAction.kt
+++ b/android-npw/src/com/android/tools/idea/npw/actions/AndroidNewProjectAction.kt
@@ -24,6 +24,7 @@
 import com.android.tools.idea.wizard.ui.StudioWizardDialogBuilder
 import com.intellij.icons.AllIcons
 import com.intellij.idea.ActionsBundle.actionText
+import com.intellij.openapi.actionSystem.ActionUpdateThread
 import com.intellij.openapi.actionSystem.AnAction
 import com.intellij.openapi.actionSystem.AnActionEvent
 import com.intellij.openapi.project.DumbAware
@@ -32,6 +33,11 @@
 
 @Suppress("ComponentNotRegistered")
 class AndroidNewProjectAction @JvmOverloads constructor(text: String = actionText("NewDirectoryProject")) : AnAction(text), DumbAware {
+
+  override fun getActionUpdateThread(): ActionUpdateThread {
+    return ActionUpdateThread.BGT
+  }
+
   override fun update(e: AnActionEvent) {
     if (NewWelcomeScreen.isNewWelcomeScreen(e)) {
       e.presentation.icon = AllIcons.Welcome.CreateNewProjectTab
diff --git a/android-npw/src/com/android/tools/idea/npw/module/recipes/androidProject/androidProjectGradleSettings.kt b/android-npw/src/com/android/tools/idea/npw/module/recipes/androidProject/androidProjectGradleSettings.kt
index 5af1e68..a36e08a 100644
--- a/android-npw/src/com/android/tools/idea/npw/module/recipes/androidProject/androidProjectGradleSettings.kt
+++ b/android-npw/src/com/android/tools/idea/npw/module/recipes/androidProject/androidProjectGradleSettings.kt
@@ -31,7 +31,13 @@
     """
 pluginManagement {
   repositories {$injectedRepositories
-    google()
+    google {
+      content {
+        includeGroupByRegex("com\\.android.*")
+        includeGroupByRegex("com\\.google.*")
+        includeGroupByRegex("androidx.*")
+      }
+    }
     mavenCentral()
     gradlePluginPortal()
   }
diff --git a/android-npw/src/com/android/tools/idea/npw/platform/AndroidVersionsInfo.kt b/android-npw/src/com/android/tools/idea/npw/platform/AndroidVersionsInfo.kt
index bbfa975..659552b 100644
--- a/android-npw/src/com/android/tools/idea/npw/platform/AndroidVersionsInfo.kt
+++ b/android-npw/src/com/android/tools/idea/npw/platform/AndroidVersionsInfo.kt
@@ -35,7 +35,7 @@
 import com.android.sdklib.repository.meta.DetailsTypes.SysImgDetailsType
 import com.android.sdklib.repository.targets.SystemImage
 import com.android.tools.adtui.device.FormFactor
-import com.android.tools.idea.gradle.npw.project.GradleBuildSettings.getRecommendedBuildToolsRevision
+import com.android.tools.idea.npw.platform.GradleBuildSettings.getRecommendedBuildToolsRevision
 import com.android.tools.idea.npw.invokeLater
 import com.android.tools.idea.sdk.AndroidSdks
 import com.android.tools.idea.sdk.IdeSdks
diff --git a/android/src/com/android/tools/idea/gradle/npw/project/GradleBuildSettings.java b/android-npw/src/com/android/tools/idea/npw/platform/GradleBuildSettings.java
similarity index 90%
rename from android/src/com/android/tools/idea/gradle/npw/project/GradleBuildSettings.java
rename to android-npw/src/com/android/tools/idea/npw/platform/GradleBuildSettings.java
index 2024186..3d18b5c 100644
--- a/android/src/com/android/tools/idea/gradle/npw/project/GradleBuildSettings.java
+++ b/android-npw/src/com/android/tools/idea/npw/platform/GradleBuildSettings.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.tools.idea.gradle.npw.project;
+package com.android.tools.idea.npw.platform;
 
 import com.android.repository.Revision;
 import com.android.repository.api.ProgressIndicator;
@@ -28,7 +28,8 @@
   /**
    * Gets the recommended gradle tools {@link Revision}. If there is no "stable" installed version, it will use the latest installed
    * "preview" version.
-   * If no stable or preview version is installed, or they are to older than the recommend version, it returns last known recommend version
+   * If no stable or preview version is installed, or they are older than the recommended version, it returns the last known
+   * recommended version
    *
    * @param sdkHandler The installed Android SDK handler
    * @param progress a progress indicator
diff --git a/android-npw/src/com/android/tools/idea/npw/project/ConfigureAndroidProjectStep.java b/android-npw/src/com/android/tools/idea/npw/project/ConfigureAndroidProjectStep.java
index 53bf4bd..ed456be 100644
--- a/android-npw/src/com/android/tools/idea/npw/project/ConfigureAndroidProjectStep.java
+++ b/android-npw/src/com/android/tools/idea/npw/project/ConfigureAndroidProjectStep.java
@@ -59,6 +59,7 @@
 import com.android.tools.idea.sdk.wizard.LicenseAgreementModel;
 import com.android.tools.idea.sdk.wizard.LicenseAgreementStep;
 import com.android.tools.idea.ui.validation.validators.PathValidator;
+import com.android.tools.idea.ui.validation.validators.StringPathValidator;
 import com.android.tools.idea.wizard.model.ModelWizard;
 import com.android.tools.idea.wizard.model.ModelWizardStep;
 import com.android.tools.idea.wizard.template.BuildConfigurationLanguageForNewProject;
@@ -82,8 +83,6 @@
 import com.intellij.util.ModalityUiUtil;
 import com.intellij.util.containers.ContainerUtil;
 import java.io.File;
-import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
@@ -177,7 +176,7 @@
     TextProperty locationText = new TextProperty(myProjectLocation.getTextField());
     BoolProperty isLocationSynced = new BoolValueProperty(true);
     myBindings.bind(locationText, computedLocation, isLocationSynced);
-    myBindings.bind(myProjectModel.getProjectLocation(), locationText);
+    myBindings.bind(myProjectModel.getProjectLocation(), locationText.trim());
     myListeners.listen(locationText, value -> isLocationSynced.set(value.equals(computedLocation.get())));
 
     OptionalProperty<VersionItem> androidSdkInfo = getModel().androidSdkInfo();
@@ -221,8 +220,8 @@
 
     myValidatorPanel.registerValidator(myProjectModel.getApplicationName(), new ProjectNameValidator());
 
-    Expression<Path> locationFile = myProjectModel.getProjectLocation().transform(Paths::get);
-    myValidatorPanel.registerValidator(locationFile, PathValidator.createDefault("project location"));
+    myValidatorPanel.registerValidator(myProjectModel.getProjectLocation(),
+                                       new StringPathValidator(PathValidator.createDefault("Save location")));
 
     myValidatorPanel.registerValidator(myProjectModel.getPackageName(),
                                        value -> Validator.Result.fromNullableMessage(AndroidUtils.validatePackageName(value)));
diff --git a/android-plugin/BUILD b/android-plugin/BUILD
index 56acefd..1fefd49 100644
--- a/android-plugin/BUILD
+++ b/android-plugin/BUILD
@@ -16,6 +16,7 @@
     runtime_deps = [
         "//tools/adt/idea/android-plugin/descriptor:intellij.android.plugin.descriptor",
         "//tools/adt/idea/layout-inspector:intellij.android.layout-inspector.gradle",
+        "//tools/adt/idea/app-quality-insights/ide/gradle:intellij.android.app-quality-insights.ide.gradle",
     ],
     # do not sort: must match IML order
     deps = [
diff --git a/android-plugin/descriptor/resources/META-INF/plugin.xml b/android-plugin/descriptor/resources/META-INF/plugin.xml
index d5a41d7..e5c0393 100644
--- a/android-plugin/descriptor/resources/META-INF/plugin.xml
+++ b/android-plugin/descriptor/resources/META-INF/plugin.xml
@@ -26,6 +26,7 @@
   <xi:include href="/META-INF/android-dagger.xml" xpointer="xpointer(/idea-plugin/*)"/>
   <xi:include href="/META-INF/app-insights-api.xml" xpointer="xpointer(/idea-plugin/*)"/>
   <xi:include href="/META-INF/app-insights.xml" xpointer="xpointer(/idea-plugin/*)"/>
+  <xi:include href="/META-INF/app-insights-gradle.xml" xpointer="xpointer(/idea-plugin/*)"/>
   <xi:include href="/META-INF/databinding.xml" xpointer="xpointer(/idea-plugin/*)"/>
   <xi:include href="/META-INF/mlkit.xml" xpointer="xpointer(/idea-plugin/*)"/>
   <xi:include href="/META-INF/sdk-updates.xml" xpointer="xpointer(/idea-plugin/*)"/>
diff --git a/android-plugin/intellij.android.plugin.iml b/android-plugin/intellij.android.plugin.iml
index 00a54af..364b2ed 100644
--- a/android-plugin/intellij.android.plugin.iml
+++ b/android-plugin/intellij.android.plugin.iml
@@ -58,5 +58,6 @@
     <orderEntry type="module" module-name="intellij.android.kotlin.extensions" />
     <orderEntry type="module" module-name="intellij.android.kotlin.idea" />
     <orderEntry type="module" module-name="intellij.android.layout-inspector.gradle" scope="RUNTIME" />
+    <orderEntry type="module" module-name="intellij.android.app-quality-insights.ide.gradle" scope="RUNTIME" />
   </component>
 </module>
\ No newline at end of file
diff --git a/android-templates/testData/golden/testNewBasicActivityMaterial3/Template test module/src/main/java/template/test/pkg/MainActivity.kt b/android-templates/testData/golden/testNewBasicActivityMaterial3/Template test module/src/main/java/template/test/pkg/MainActivity.kt
index 3eef53b..25b3cf1 100644
--- a/android-templates/testData/golden/testNewBasicActivityMaterial3/Template test module/src/main/java/template/test/pkg/MainActivity.kt
+++ b/android-templates/testData/golden/testNewBasicActivityMaterial3/Template test module/src/main/java/template/test/pkg/MainActivity.kt
@@ -31,7 +31,8 @@
 
         binding.fab.setOnClickListener { view ->
             Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
-                    .setAction("Action", null).show()
+                    .setAction("Action", null)
+                    .setAnchorView(R.id.fab).show()
         }
     }
 
diff --git a/android-templates/testData/golden/testNewNavigationDrawerActivity/Template test module/src/main/java/template/test/pkg/MainActivity.java b/android-templates/testData/golden/testNewNavigationDrawerActivity/Template test module/src/main/java/template/test/pkg/MainActivity.java
index 534123f..ed1ebcf 100644
--- a/android-templates/testData/golden/testNewNavigationDrawerActivity/Template test module/src/main/java/template/test/pkg/MainActivity.java
+++ b/android-templates/testData/golden/testNewNavigationDrawerActivity/Template test module/src/main/java/template/test/pkg/MainActivity.java
@@ -33,7 +33,8 @@
             @Override
             public void onClick(View view) {
                 Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
-                        .setAction("Action", null).show();
+                        .setAction("Action", null)
+                        .setAnchorView(R.id.fab).show();
             }
         });
         DrawerLayout drawer = binding.drawerLayout;
diff --git a/android-templates/testData/golden/testNewNavigationDrawerActivityWithKotlin/Template test module/src/main/java/template/test/pkg/MainActivity.kt b/android-templates/testData/golden/testNewNavigationDrawerActivityWithKotlin/Template test module/src/main/java/template/test/pkg/MainActivity.kt
index 022cd80..2d08794 100644
--- a/android-templates/testData/golden/testNewNavigationDrawerActivityWithKotlin/Template test module/src/main/java/template/test/pkg/MainActivity.kt
+++ b/android-templates/testData/golden/testNewNavigationDrawerActivityWithKotlin/Template test module/src/main/java/template/test/pkg/MainActivity.kt
@@ -28,7 +28,8 @@
 
         binding.appBarMain.fab.setOnClickListener { view ->
             Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
-                    .setAction("Action", null).show()
+                    .setAction("Action", null)
+                    .setAnchorView(R.id.fab).show()
         }
         val drawerLayout: DrawerLayout = binding.drawerLayout
         val navView: NavigationView = binding.navView
diff --git a/android-templates/testData/golden/testNewScrollingActivity/Template test module/src/main/java/template/test/pkg/ScrollingActivity.java b/android-templates/testData/golden/testNewScrollingActivity/Template test module/src/main/java/template/test/pkg/ScrollingActivity.java
index 34ff859..e8d3519 100644
--- a/android-templates/testData/golden/testNewScrollingActivity/Template test module/src/main/java/template/test/pkg/ScrollingActivity.java
+++ b/android-templates/testData/golden/testNewScrollingActivity/Template test module/src/main/java/template/test/pkg/ScrollingActivity.java
@@ -37,7 +37,8 @@
             @Override
             public void onClick(View view) {
                 Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
-                        .setAction("Action", null).show();
+                        .setAction("Action", null)
+                        .setAnchorView(R.id.fab).show();
             }
         });
     }
diff --git a/android-templates/testData/golden/testNewScrollingActivityWithKotlin/Template test module/src/main/java/template/test/pkg/ScrollingActivity.kt b/android-templates/testData/golden/testNewScrollingActivityWithKotlin/Template test module/src/main/java/template/test/pkg/ScrollingActivity.kt
index 9f0da4a..bffb558 100644
--- a/android-templates/testData/golden/testNewScrollingActivityWithKotlin/Template test module/src/main/java/template/test/pkg/ScrollingActivity.kt
+++ b/android-templates/testData/golden/testNewScrollingActivityWithKotlin/Template test module/src/main/java/template/test/pkg/ScrollingActivity.kt
@@ -23,7 +23,8 @@
         binding.toolbarLayout.title = title
         binding.fab.setOnClickListener { view ->
             Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
-                    .setAction("Action", null).show()
+                    .setAction("Action", null)
+                    .setAnchorView(R.id.fab).show()
         }
     }
 
diff --git a/android-templates/testData/golden/testNewTabbedActivity/Template test module/src/main/java/template/test/pkg/MainActivity.java b/android-templates/testData/golden/testNewTabbedActivity/Template test module/src/main/java/template/test/pkg/MainActivity.java
index fd5f9dd..0aae17d 100644
--- a/android-templates/testData/golden/testNewTabbedActivity/Template test module/src/main/java/template/test/pkg/MainActivity.java
+++ b/android-templates/testData/golden/testNewTabbedActivity/Template test module/src/main/java/template/test/pkg/MainActivity.java
@@ -38,7 +38,8 @@
             @Override
             public void onClick(View view) {
                 Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
-                        .setAction("Action", null).show();
+                        .setAction("Action", null)
+                        .setAnchorView(R.id.fab).show();
             }
         });
     }
diff --git a/android-templates/testData/golden/testNewTabbedActivityWithKotlin/Template test module/src/main/java/template/test/pkg/MainActivity.kt b/android-templates/testData/golden/testNewTabbedActivityWithKotlin/Template test module/src/main/java/template/test/pkg/MainActivity.kt
index 1657075..c07c325 100644
--- a/android-templates/testData/golden/testNewTabbedActivityWithKotlin/Template test module/src/main/java/template/test/pkg/MainActivity.kt
+++ b/android-templates/testData/golden/testNewTabbedActivityWithKotlin/Template test module/src/main/java/template/test/pkg/MainActivity.kt
@@ -30,7 +30,8 @@
 
         fab.setOnClickListener { view ->
             Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
-                    .setAction("Action", null).show()
+                    .setAction("Action", null)
+                    .setAnchorView(R.id.fab).show()
         }
     }
 }
\ No newline at end of file
diff --git a/android-templates/testData/golden/testResponsiveActivity/Template test module/src/main/java/template/test/pkg/MainActivity.java b/android-templates/testData/golden/testResponsiveActivity/Template test module/src/main/java/template/test/pkg/MainActivity.java
index 696fad5..59a22fc 100644
--- a/android-templates/testData/golden/testResponsiveActivity/Template test module/src/main/java/template/test/pkg/MainActivity.java
+++ b/android-templates/testData/golden/testResponsiveActivity/Template test module/src/main/java/template/test/pkg/MainActivity.java
@@ -32,7 +32,7 @@
         setSupportActionBar(binding.appBarMain.toolbar);
         if (binding.appBarMain.fab != null) {
             binding.appBarMain.fab.setOnClickListener(view -> Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
-                    .setAction("Action", null).show());
+                    .setAction("Action", null).setAnchorView(R.id.fab).show());
         }
         NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment_content_main);
         assert navHostFragment != null;
diff --git a/android-templates/testData/golden/testResponsiveActivityWithKotlin/Template test module/src/main/java/template/test/pkg/MainActivity.kt b/android-templates/testData/golden/testResponsiveActivityWithKotlin/Template test module/src/main/java/template/test/pkg/MainActivity.kt
index 68686f1..ae463d7 100644
--- a/android-templates/testData/golden/testResponsiveActivityWithKotlin/Template test module/src/main/java/template/test/pkg/MainActivity.kt
+++ b/android-templates/testData/golden/testResponsiveActivityWithKotlin/Template test module/src/main/java/template/test/pkg/MainActivity.kt
@@ -27,7 +27,8 @@
 
         binding.appBarMain.fab?.setOnClickListener { view ->
             Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
-                    .setAction("Action", null).show()
+                    .setAction("Action", null)
+                    .setAnchorView(R.id.fab).show()
         }
 
         val navHostFragment =
diff --git a/android-test-framework/testSrc/com/android/tools/idea/projectsystem/TestProjectSystem.kt b/android-test-framework/testSrc/com/android/tools/idea/projectsystem/TestProjectSystem.kt
index 18f6504..0d01f8f 100644
--- a/android-test-framework/testSrc/com/android/tools/idea/projectsystem/TestProjectSystem.kt
+++ b/android-test-framework/testSrc/com/android/tools/idea/projectsystem/TestProjectSystem.kt
@@ -88,6 +88,7 @@
   var namespace: String? = null
   var manifestOverrides = ManifestOverrides()
   var useAndroidX: Boolean = false
+  var usesCompose: Boolean = false
 
   init {
     val sortedHighToLowDeps = availableDependencies.sortedWith(GradleCoordinate.COMPARE_PLUS_HIGHER).reversed()
@@ -250,6 +251,9 @@
 
       override val moduleDependencies: ModuleDependencies
         get() = StudioModuleDependencies(module)
+
+      override val usesCompose: Boolean
+        get() = this@TestProjectSystem.usesCompose
     }
 
     return TestAndroidModuleSystemImpl()
diff --git a/android-test-framework/testSrc/com/android/tools/idea/testing/AndroidGradleTestUtils.kt b/android-test-framework/testSrc/com/android/tools/idea/testing/AndroidGradleTestUtils.kt
index e0d8825..eccd782 100644
--- a/android-test-framework/testSrc/com/android/tools/idea/testing/AndroidGradleTestUtils.kt
+++ b/android-test-framework/testSrc/com/android/tools/idea/testing/AndroidGradleTestUtils.kt
@@ -126,6 +126,7 @@
 import com.android.tools.idea.projectsystem.getHolderModule
 import com.android.tools.idea.projectsystem.getProjectSystem
 import com.android.tools.idea.projectsystem.gradle.GradleHolderProjectPath
+import com.android.tools.idea.projectsystem.gradle.GradleModuleSystem
 import com.android.tools.idea.projectsystem.gradle.GradleProjectPath
 import com.android.tools.idea.projectsystem.gradle.GradleProjectSystem
 import com.android.tools.idea.projectsystem.gradle.GradleSourceSetProjectPath
@@ -133,8 +134,10 @@
 import com.android.tools.idea.projectsystem.gradle.getGradleProjectPath
 import com.android.tools.idea.projectsystem.gradle.resolveIn
 import com.android.tools.idea.projectsystem.gradle.toSourceSetPath
+import com.android.tools.idea.res.ProjectLightResourceClassService
 import com.android.tools.idea.run.ApkProvider
 import com.android.tools.idea.run.ApplicationIdProvider
+import com.android.tools.idea.run.GradleApplicationIdProvider
 import com.android.tools.idea.run.ValidationError
 import com.android.tools.idea.sdk.IdeSdks
 import com.android.tools.idea.stats.ProjectSizeUsageTrackerListener
@@ -1307,60 +1310,13 @@
     error("There is already more than one module in the test project.")
   }
 
-  val gradleProjectSystem = GradleProjectSystem(project)
-  ProjectSystemService.getInstance(project).replaceProjectSystemForTests(object : AndroidProjectSystem {
+  ProjectSystemService.getInstance(project).replaceProjectSystemForTests(object : GradleProjectSystem(project) {
     // Many tests that invoke `compileProject` work with timestamps. To avoid flaky tests we inject a millisecond delay each time
     // build is requested.
     private val buildManager = TestProjectSystemBuildManager(ensureClockAdvancesWhileBuilding = true)
     override fun getBuildManager(): ProjectSystemBuildManager = buildManager
 
-    override fun getPsiElementFinders(): Collection<PsiElementFinder> = gradleProjectSystem.getPsiElementFinders()
-
-    override fun getLightResourceClassService(): LightResourceClassService = gradleProjectSystem.getLightResourceClassService()
-
-    override fun getSourceProvidersFactory(): SourceProvidersFactory = gradleProjectSystem.getSourceProvidersFactory()
-
-    override fun getClassJarProvider(): ClassJarProvider = gradleProjectSystem.getClassJarProvider()
-
-    override fun getAndroidFacetsWithPackageName(project: Project, packageName: String): Collection<AndroidFacet> =
-      gradleProjectSystem.getAndroidFacetsWithPackageName(project, packageName)
-
-    override fun isNamespaceOrParentPackage(packageName: String): Boolean =
-      gradleProjectSystem.isNamespaceOrParentPackage(packageName)
-
-    override fun getBootClasspath(module: Module): Collection<String> {
-      return emptyList()
-    }
-
-    override fun getDefaultApkFile(): VirtualFile? = gradleProjectSystem.getDefaultApkFile()
-
-    override fun getPathToAapt(): Path = gradleProjectSystem.getPathToAapt()
-
-    override fun allowsFileCreation(): Boolean = gradleProjectSystem.allowsFileCreation()
-
-    override fun getModuleSystem(module: Module): AndroidModuleSystem = gradleProjectSystem.getModuleSystem(module)
-
-    override fun getApplicationIdProvider(runConfiguration: RunConfiguration): ApplicationIdProvider? =
-      gradleProjectSystem.getApplicationIdProvider(runConfiguration)
-
-    override fun getApkProvider(runConfiguration: RunConfiguration): ApkProvider? = gradleProjectSystem.getApkProvider(runConfiguration)
-
-    override fun getSyncManager(): ProjectSystemSyncManager = gradleProjectSystem.getSyncManager()
-
-    override fun validateRunConfiguration(runConfiguration: RunConfiguration): List<ValidationError> {
-      return gradleProjectSystem.validateRunConfiguration(runConfiguration)
-    }
-
-    override fun getBuildConfigurationSourceProvider(): BuildConfigurationSourceProvider? =
-      gradleProjectSystem.getBuildConfigurationSourceProvider()
-
-    override fun getKnownApplicationIds(): Set<String> = gradleProjectSystem.getKnownApplicationIds()
-
-    override fun findModulesWithApplicationId(applicationId: String): Collection<Module> =
-      gradleProjectSystem.findModulesWithApplicationId(applicationId)
-
-    override fun supportsProfilingMode(): Boolean = gradleProjectSystem.supportsProfilingMode()
-
+    override fun getBootClasspath(module: Module): Collection<String> = emptyList()
   })
   setupTestProjectFromAndroidModelCore(project, rootProjectBasePath, moduleBuilders, setupAllVariants, cacheExistingVariants = false)
 }
diff --git a/android-transport/src/com/android/tools/idea/transport/manager/TransportStreamManager.kt b/android-transport/src/com/android/tools/idea/transport/manager/TransportStreamManager.kt
index f1634f6..beb81da 100644
--- a/android-transport/src/com/android/tools/idea/transport/manager/TransportStreamManager.kt
+++ b/android-transport/src/com/android/tools/idea/transport/manager/TransportStreamManager.kt
@@ -16,39 +16,43 @@
 package com.android.tools.idea.transport.manager
 
 import com.android.annotations.concurrency.AnyThread
+import com.android.tools.idea.concurrency.AndroidCoroutineScope
+import com.android.tools.idea.transport.TransportClient
+import com.android.tools.idea.transport.TransportService
 import com.android.tools.profiler.proto.Common
 import com.android.tools.profiler.proto.Transport.GetEventGroupsRequest
 import com.android.tools.profiler.proto.Transport.GetEventGroupsResponse
 import com.android.tools.profiler.proto.TransportServiceGrpc
+import com.intellij.openapi.Disposable
+import com.intellij.openapi.components.Service
+import java.util.concurrent.atomic.AtomicBoolean
 import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.flow.flatMap
 import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.shareIn
 import kotlinx.coroutines.flow.takeWhile
 import kotlinx.coroutines.flow.transform
-import java.util.concurrent.atomic.AtomicBoolean
+import org.jetbrains.annotations.VisibleForTesting
 
 const val DELAY_MILLIS = 100L
 
-/**
- * Represents stream connection activity.
- */
+/** Represents stream connection activity. */
 sealed class StreamActivity(val streamChannel: TransportStreamChannel)
 
-/**
- * Represents a stream connect activity.
- */
+/** Represents a stream connect activity. */
 class StreamConnected(streamChannel: TransportStreamChannel) : StreamActivity(streamChannel)
 
-/**
- * Represents a stream disconnect activity.
- */
+/** Represents a stream disconnect activity. */
 class StreamDisconnected(streamChannel: TransportStreamChannel) : StreamActivity(streamChannel)
 
-/**
- * This simply wraps [Common.Event] and represents an event from a stream channel.
- */
+/** This simply wraps [Common.Event] and represents an event from a stream channel. */
 class StreamEvent(val event: Common.Event)
 
 private fun TransportServiceGrpc.TransportServiceBlockingStub.eventGroupFlow(
@@ -61,55 +65,71 @@
   }
 }
 
-/**
- * Listens to and manages STREAM events from the transport pipeline. Users can subscribe to the activity flow to listen in on new streams.
- *
- * Streams are provided in the form of [TransportStreamChannel], which provides users the ability to register their own listeners while
- * automatically associating them with the stream.
- */
-@AnyThread
-class TransportStreamManager private constructor(
-  private val client: TransportServiceGrpc.TransportServiceBlockingStub,
-  private val dispatcher: CoroutineDispatcher
-) {
-  fun streamActivityFlow(): Flow<StreamActivity> {
-    val streams = mutableMapOf<Long, TransportStreamChannel>()
-    return flow {
-      while (true) {
-        StreamQueryUtils.queryForDevices(client).forEach { stream ->
-          if (stream.device.state == Common.Device.State.ONLINE) {
-            if (!streams.containsKey(stream.streamId)) {
-              val streamChannel = TransportStreamChannel(stream, client, dispatcher)
-              emit(StreamConnected(streamChannel))
-              streams[stream.streamId] = streamChannel
-            }
-          }
-          else {
-            streams.remove(stream.streamId)?.let { channel ->
-              channel.cleanUp()
-              emit(StreamDisconnected(channel))
-            }
-          }
-        }
-        delay(DELAY_MILLIS)
-      }
-    }.flowOn(dispatcher)
+@Service(Service.Level.APP)
+class TransportStreamManagerService : Disposable {
+  private val client: TransportClient
+  init {
+    // Initialize transport gRpc machinery.
+    TransportService.getInstance()
+    client = TransportClient(TransportService.channelName)
   }
 
-  companion object {
-    private val managers = mutableListOf<TransportStreamManager>()
+  val streamManager =
+    TransportStreamManager(
+      TransportClient(TransportService.channelName).transportStub,
+      AndroidCoroutineScope(this, Dispatchers.IO)
+    )
 
-    fun createManager(
-      client: TransportServiceGrpc.TransportServiceBlockingStub,
-      dispatcher: CoroutineDispatcher
-    ): TransportStreamManager {
-      val manager = TransportStreamManager(client, dispatcher)
-      managers.add(manager)
-      return manager
-    }
+  override fun dispose() = Unit
+}
 
-    fun unregisterManager(manager: TransportStreamManager) {
-      managers.remove(manager)
+/**
+ * Listens to and manages STREAM events from the transport pipeline. Users can subscribe to the
+ * activity flow to listen in on new streams.
+ *
+ * Streams are provided in the form of [TransportStreamChannel], which provides users the ability to
+ * register their own listeners while automatically associating them with the stream.
+ *
+ * Please use [TransportStreamManagerService] to obtain instance of [TransportStreamManager] in
+ * production code.
+ */
+class TransportStreamManager
+@VisibleForTesting
+constructor(
+  private val client: TransportServiceGrpc.TransportServiceBlockingStub,
+  scope: CoroutineScope
+) {
+
+  private val streamState =
+    flow {
+        while (true) {
+          emit(StreamQueryUtils.queryForDevices(client))
+          delay(DELAY_MILLIS)
+        }
+      }
+      .shareIn(scope, SharingStarted.Lazily, 1)
+
+  /**
+   * Collects the current state of connected devices in the form of a flow of [StreamActivity]
+   * events.
+   */
+  fun streamActivityFlow(): Flow<StreamActivity> = flow {
+    val streams = mutableMapOf<Long, TransportStreamChannel>()
+    streamState.collect { streamState ->
+      streamState.forEach { stream ->
+        if (stream.device.state == Common.Device.State.ONLINE) {
+          if (!streams.containsKey(stream.streamId)) {
+            val streamChannel = TransportStreamChannel(stream, client, Dispatchers.IO)
+            emit(StreamConnected(streamChannel))
+            streams[stream.streamId] = streamChannel
+          }
+        } else {
+          streams.remove(stream.streamId)?.let { channel ->
+            channel.cleanUp()
+            emit(StreamDisconnected(channel))
+          }
+        }
+      }
     }
   }
 }
@@ -125,21 +145,19 @@
   val client: TransportServiceGrpc.TransportServiceBlockingStub,
   private val dispatcher: CoroutineDispatcher
 ) {
-
   private val isClosed = AtomicBoolean(false)
 
-  /**
-   * Creates and returns a flow based on the filtering criteria indicated by [query].
-   */
+  /** Creates and returns a flow based on the filtering criteria indicated by [query]. */
   fun eventFlow(query: StreamEventQuery): Flow<StreamEvent> {
     var lastTimeStamp = query.startTime?.invoke() ?: Long.MIN_VALUE
     return client
       .eventGroupFlow {
-        val builder = GetEventGroupsRequest.newBuilder()
-          .setStreamId(stream.streamId)
-          .setKind(query.eventKind)
-          .setFromTimestamp(lastTimeStamp)
-          .setToTimestamp(query.endTime())
+        val builder =
+          GetEventGroupsRequest.newBuilder()
+            .setStreamId(stream.streamId)
+            .setKind(query.eventKind)
+            .setFromTimestamp(lastTimeStamp)
+            .setToTimestamp(query.endTime())
         query.processId?.invoke()?.let { builder.pid = it }
         query.groupId?.invoke()?.let { builder.groupId = it }
         builder.build()
@@ -147,10 +165,11 @@
       .takeWhile { !isClosed.get() }
       .transform { response ->
         if (response != GetEventGroupsResponse.getDefaultInstance()) {
-          val filtered = response.groupsList
-            .flatMap { group -> group.eventsList }
-            .sortedWith(query.sortOrder)
-            .filter { event -> event.timestamp >= lastTimeStamp && query.filter(event) }
+          val filtered =
+            response.groupsList
+              .flatMap { group -> group.eventsList }
+              .sortedWith(query.sortOrder)
+              .filter { event -> event.timestamp >= lastTimeStamp && query.filter(event) }
           filtered.forEach { event -> emit(StreamEvent(event)) }
           val maxTimeEvent = filtered.maxByOrNull { it.timestamp }
           maxTimeEvent?.let { lastTimeStamp = kotlin.math.max(lastTimeStamp, it.timestamp + 1) }
@@ -164,39 +183,44 @@
     doQuery: suspend () -> List<Common.Process> = {
       StreamQueryUtils.queryForProcesses(client, stream.streamId, filter)
     }
-  ): Flow<Common.Process> {
-    return flow<Common.Process> {
-      val processes = mutableMapOf<Int, Common.Process>()
-      while (true) {
-        // The query will return a list of all processes the transport pipeline is aware of, whether they
-        // are alive or dead. Therefore, in order to check for updates to the processes' states, we need
-        // to reconcile it with the cached state from a previous query.
-        val queryResult = doQuery()
-        val queriedPids = queryResult.map { it.pid }.toSet()
-        val deadProcesses = processes.filterNot { it.key in queriedPids }.values
+  ) =
+    flow<Common.Process> {
+        val processes = mutableMapOf<Int, Common.Process>()
+        while (true) {
+          // The query will return a list of all processes the transport pipeline is aware of,
+          // whether they
+          // are alive or dead. Therefore, in order to check for updates to the processes' states,
+          // we need
+          // to reconcile it with the cached state from a previous query.
+          val queryResult = doQuery()
+          val queriedPids = queryResult.map { it.pid }.toSet()
+          val deadProcesses = processes.filterNot { it.key in queriedPids }.values
 
-        // Due to the nature of polling, we might miss DEAD process updates because, for example, the process
-        // was restarted. We check for this case by looking for known pids that have disappeared from the
-        // current query result.
-        deadProcesses.forEach { process -> emit(process.toBuilder().setState(Common.Process.State.DEAD).build()) }
-
-        // Emit updates in the order they were received
-        queryResult.forEach { process ->
-          if (process.state != processes[process.pid]?.state || process.pid !in processes.keys) {
-            emit(process)
+          // Due to the nature of polling, we might miss DEAD process updates because, for example,
+          // the process
+          // was restarted. We check for this case by looking for known pids that have disappeared
+          // from the
+          // current query result.
+          deadProcesses.forEach { process ->
+            emit(process.toBuilder().setState(Common.Process.State.DEAD).build())
           }
-        }
 
-        processes.clear()
-        processes.putAll(queryResult.associateBy { it.pid })
-        delay(DELAY_MILLIS)
+          // Emit updates in the order they were received
+          queryResult.forEach { process ->
+            if (process.state != processes[process.pid]?.state || process.pid !in processes.keys) {
+              emit(process)
+            }
+          }
+
+          processes.clear()
+          processes.putAll(queryResult.associateBy { it.pid })
+          delay(DELAY_MILLIS)
+        }
       }
-    }
-      .flowOn(dispatcher)
       .takeWhile { !isClosed.get() }
-  }
+      .flowOn(dispatcher)
 
   internal fun cleanUp() {
     isClosed.set(true)
   }
-}
\ No newline at end of file
+}
diff --git a/android-transport/testSrc/com/android/tools/idea/transport/manager/TransportStreamManagerRule.kt b/android-transport/testSrc/com/android/tools/idea/transport/manager/TransportStreamManagerRule.kt
new file mode 100644
index 0000000..6c8f49a
--- /dev/null
+++ b/android-transport/testSrc/com/android/tools/idea/transport/manager/TransportStreamManagerRule.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.transport.manager
+
+import com.android.tools.idea.transport.TransportClient
+import com.android.tools.idea.transport.faketransport.FakeGrpcServer
+import kotlin.coroutines.EmptyCoroutineContext
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.cancel
+import org.junit.rules.ExternalResource
+
+class TransportStreamManagerRule(private val fakeGrpcServer: FakeGrpcServer) : ExternalResource() {
+  lateinit var streamManager: TransportStreamManager
+  private lateinit var scope: CoroutineScope
+  private lateinit var client: TransportClient
+
+  override fun before() {
+    scope = CoroutineScope(EmptyCoroutineContext)
+    client = TransportClient(fakeGrpcServer.name)
+    streamManager =
+      TransportStreamManager(client.transportStub, scope)
+  }
+
+  override fun after() {
+    client.shutdown()
+    scope.cancel()
+  }
+}
diff --git a/android-transport/testSrc/com/android/tools/idea/transport/manager/TransportStreamManagerTest.kt b/android-transport/testSrc/com/android/tools/idea/transport/manager/TransportStreamManagerTest.kt
index 31811e2..ab2150a 100644
--- a/android-transport/testSrc/com/android/tools/idea/transport/manager/TransportStreamManagerTest.kt
+++ b/android-transport/testSrc/com/android/tools/idea/transport/manager/TransportStreamManagerTest.kt
@@ -16,74 +16,57 @@
 package com.android.tools.idea.transport.manager
 
 import com.android.tools.adtui.model.FakeTimer
-import com.android.tools.idea.transport.TransportClient
 import com.android.tools.idea.transport.faketransport.FakeGrpcServer
 import com.android.tools.idea.transport.faketransport.FakeTransportService
 import com.android.tools.profiler.proto.Common
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.CompletableDeferred
-import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.asCoroutineDispatcher
-import kotlinx.coroutines.cancel
 import kotlinx.coroutines.channels.Channel
 import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.collectIndexed
 import kotlinx.coroutines.flow.take
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
-import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
-import java.util.concurrent.ExecutorService
-import java.util.concurrent.Executors
+import org.junit.rules.RuleChain
 
 @ExperimentalCoroutinesApi
 class TransportStreamManagerTest {
   private val timer = FakeTimer()
   private val transportService = FakeTransportService(timer, false)
-  private val fakeDevice2 = FakeTransportService.FAKE_DEVICE.toBuilder().setDeviceId(FakeTransportService.FAKE_DEVICE_ID + 1).build()
+  private val fakeDevice2 =
+    FakeTransportService.FAKE_DEVICE.toBuilder()
+      .setDeviceId(FakeTransportService.FAKE_DEVICE_ID + 1)
+      .build()
   private val offlineFakeDevice2 =
-    FakeTransportService.FAKE_OFFLINE_DEVICE.toBuilder().setDeviceId(FakeTransportService.FAKE_DEVICE_ID + 1).build()
-  private val fakeProcess2 = FakeTransportService.FAKE_PROCESS.toBuilder().setDeviceId(fakeDevice2.deviceId).build()
-  private lateinit var executorService: ExecutorService
-  private lateinit var dispatcher: CoroutineDispatcher
+    FakeTransportService.FAKE_OFFLINE_DEVICE.toBuilder()
+      .setDeviceId(FakeTransportService.FAKE_DEVICE_ID + 1)
+      .build()
+  private val fakeProcess2 =
+    FakeTransportService.FAKE_PROCESS.toBuilder().setDeviceId(fakeDevice2.deviceId).build()
 
-  @get:Rule
-  val grpcServerRule = FakeGrpcServer.createFakeGrpcServer("AppInspectionDiscoveryTest", transportService)
+  private val grpcServerRule =
+    FakeGrpcServer.createFakeGrpcServer("AppInspectionDiscoveryTest", transportService)
+  private val streamManagerRule = TransportStreamManagerRule(grpcServerRule)
 
-  @Before
-  fun setUp() {
-    executorService = Executors.newSingleThreadExecutor()
-    dispatcher = executorService.asCoroutineDispatcher()
-  }
-
-  fun tearDown() {
-    dispatcher.cancel()
-    executorService.shutdownNow()
-  }
+  @get:Rule val ruleChain = RuleChain.outerRule(grpcServerRule).around(streamManagerRule)
 
   @Test
   fun discoverNewStream() = runBlocking {
-    val manager =
-      TransportStreamManager
-        .createManager(TransportClient(grpcServerRule.name).transportStub, dispatcher)
-
     val streamReadyDeferred = CompletableDeferred<Unit>()
     val streamDeadDeferred = CompletableDeferred<Unit>()
 
     launch {
-      manager.streamActivityFlow()
-        .take(2)
-        .collect {
-          if (it is StreamConnected) {
-            assertThat(it.streamChannel.stream.device).isEqualTo(FakeTransportService.FAKE_DEVICE)
-            streamReadyDeferred.complete(Unit)
-          }
-          else if (it is StreamDisconnected) {
-            streamDeadDeferred.complete(Unit)
-          }
+      streamManagerRule.streamManager.streamActivityFlow().take(2).collect {
+        if (it is StreamConnected) {
+          assertThat(it.streamChannel.stream.device).isEqualTo(FakeTransportService.FAKE_DEVICE)
+          streamReadyDeferred.complete(Unit)
+        } else if (it is StreamDisconnected) {
+          streamDeadDeferred.complete(Unit)
         }
+      }
     }
 
     transportService.addDevice(FakeTransportService.FAKE_DEVICE)
@@ -98,29 +81,22 @@
 
   @Test
   fun rediscoverStream() = runBlocking {
-    val manager =
-      TransportStreamManager
-        .createManager(TransportClient(grpcServerRule.name).transportStub, dispatcher)
-
     val streamReadyDeferred = CompletableDeferred<Unit>()
     val streamReadyAgainDeferred = CompletableDeferred<Unit>()
     val streamDeadDeferred = CompletableDeferred<Unit>()
     launch {
-      manager.streamActivityFlow()
-        .take(3)
-        .collectIndexed { index, activity ->
-          if (activity is StreamConnected) {
-            if (index == 0) {
-              streamReadyDeferred.complete(Unit)
-            }
-            else {
-              streamReadyAgainDeferred.complete(Unit)
-            }
+      streamManagerRule.streamManager.streamActivityFlow().take(3).collectIndexed { index, activity
+        ->
+        if (activity is StreamConnected) {
+          if (index == 0) {
+            streamReadyDeferred.complete(Unit)
+          } else {
+            streamReadyAgainDeferred.complete(Unit)
           }
-          else if (activity is StreamDisconnected) {
-            streamDeadDeferred.complete(Unit)
-          }
+        } else if (activity is StreamDisconnected) {
+          streamDeadDeferred.complete(Unit)
         }
+      }
     }
 
     transportService.addDevice(FakeTransportService.FAKE_DEVICE)
@@ -140,25 +116,19 @@
 
   @Test
   fun discoverMultipleStreams() = runBlocking {
-    val manager =
-      TransportStreamManager
-        .createManager(TransportClient(grpcServerRule.name).transportStub, dispatcher)
-
     val devicesDetected = CompletableDeferred<Unit>()
     launch {
-      manager.streamActivityFlow()
-        .take(4)
-        .collectIndexed { index, activity ->
-          if (index < 2) {
-            assertThat(activity).isInstanceOf(StreamConnected::class.java)
-          }
-          else {
-            assertThat(activity).isInstanceOf(StreamDisconnected::class.java)
-          }
-          if (index == 1) {
-            devicesDetected.complete(Unit)
-          }
+      streamManagerRule.streamManager.streamActivityFlow().take(4).collectIndexed { index, activity
+        ->
+        if (index < 2) {
+          assertThat(activity).isInstanceOf(StreamConnected::class.java)
+        } else {
+          assertThat(activity).isInstanceOf(StreamDisconnected::class.java)
         }
+        if (index == 1) {
+          devicesDetected.complete(Unit)
+        }
+      }
     }
 
     transportService.addDevice(FakeTransportService.FAKE_DEVICE)
@@ -177,19 +147,15 @@
   // Tests stream manager does not ignore stream events from a device that has a slower clock.
   @Test
   fun streamsWithDifferentClocks() = runBlocking {
-    val manager =
-      TransportStreamManager.createManager(TransportClient(grpcServerRule.name).transportStub, dispatcher)
-
     launch {
-      manager.streamActivityFlow()
-        .take(2)
-        .collect { activity ->
-          launch {
-            activity.streamChannel.eventFlow(StreamEventQuery(Common.Event.Kind.PROCESS))
-              .take(1)
-              .collect()
-          }
+      streamManagerRule.streamManager.streamActivityFlow().take(2).collect { activity ->
+        launch {
+          activity.streamChannel
+            .eventFlow(StreamEventQuery(Common.Event.Kind.PROCESS))
+            .take(1)
+            .collect()
         }
+      }
     }
 
     // Start stream 1 and stream 2
@@ -207,24 +173,18 @@
 
   @Test
   fun streamDisconnect_closesFlows() = runBlocking {
-    val manager =
-      TransportStreamManager.createManager(TransportClient(grpcServerRule.name).transportStub, dispatcher)
-
     val streamReadyDeferred = CompletableDeferred<Unit>()
     launch {
-      manager.streamActivityFlow()
-        .take(2)
-        .collect { activity ->
-          if (activity is StreamConnected) {
-            launch {
-              activity.streamChannel.eventFlow(StreamEventQuery(Common.Event.Kind.PROCESS))
-                .collect {
-                  // Collection should be cancelled when stream is disconnected.
-                }
+      streamManagerRule.streamManager.streamActivityFlow().take(2).collect { activity ->
+        if (activity is StreamConnected) {
+          launch {
+            activity.streamChannel.eventFlow(StreamEventQuery(Common.Event.Kind.PROCESS)).collect {
+              // Collection should be cancelled when stream is disconnected.
             }
-            streamReadyDeferred.complete(Unit)
           }
+          streamReadyDeferred.complete(Unit)
         }
+      }
     }
 
     transportService.addDevice(FakeTransportService.FAKE_DEVICE)
@@ -238,36 +198,34 @@
 
   @Test
   fun `add and remove processes`() = runBlocking {
-    val manager =
-      TransportStreamManager
-        .createManager(TransportClient(grpcServerRule.name).transportStub, dispatcher)
-
     transportService.addDevice(FakeTransportService.FAKE_DEVICE)
 
     val queryChannel = Channel<List<Common.Process>>(capacity = 1)
 
-    manager.streamActivityFlow()
-      .take(1)
-      .collect { activity ->
-        queryChannel.send(listOf(FakeTransportService.FAKE_PROCESS, FakeTransportService.FAKE_PROFILEABLE_PROCESS))
-        activity.streamChannel.processesFlow({ _, _ -> true }) {
-          queryChannel.receive()
-        }
-          .take(4)
-          .collectIndexed { index, process ->
-            when (index) {
-              0 -> assertThat(process).isEqualTo(FakeTransportService.FAKE_PROCESS)
-              1 -> {
-                assertThat(process).isEqualTo(FakeTransportService.FAKE_PROFILEABLE_PROCESS)
-                queryChannel.send(listOf(FakeTransportService.FAKE_OFFLINE_PROCESS))
-              }
-
-              2 -> assertThat(process).isEqualTo(
-                FakeTransportService.FAKE_PROFILEABLE_PROCESS.toBuilder().setState(Common.Process.State.DEAD).build())
-
-              3 -> assertThat(process).isEqualTo(FakeTransportService.FAKE_OFFLINE_PROCESS)
+    streamManagerRule.streamManager.streamActivityFlow().take(1).collect { activity ->
+      queryChannel.send(
+        listOf(FakeTransportService.FAKE_PROCESS, FakeTransportService.FAKE_PROFILEABLE_PROCESS)
+      )
+      activity.streamChannel
+        .processesFlow({ _, _ -> true }) { queryChannel.receive() }
+        .take(4)
+        .collectIndexed { index, process ->
+          when (index) {
+            0 -> assertThat(process).isEqualTo(FakeTransportService.FAKE_PROCESS)
+            1 -> {
+              assertThat(process).isEqualTo(FakeTransportService.FAKE_PROFILEABLE_PROCESS)
+              queryChannel.send(listOf(FakeTransportService.FAKE_OFFLINE_PROCESS))
             }
+            2 ->
+              assertThat(process)
+                .isEqualTo(
+                  FakeTransportService.FAKE_PROFILEABLE_PROCESS.toBuilder()
+                    .setState(Common.Process.State.DEAD)
+                    .build()
+                )
+            3 -> assertThat(process).isEqualTo(FakeTransportService.FAKE_OFFLINE_PROCESS)
           }
-      }
+        }
+    }
   }
-}
\ No newline at end of file
+}
diff --git a/android-uitests/BUILD b/android-uitests/BUILD
index f5bd34c..c3115c6 100644
--- a/android-uitests/BUILD
+++ b/android-uitests/BUILD
@@ -3260,9 +3260,7 @@
     name = "JavaToKotlinConversionTest",
     size = "enormous",
     timeout = "long",
-    data = COMMON_DATA + glob([
-        "testData/SimpleApplication/**",
-    ]),
+    data = COMMON_DATA,
     jvm_flags = ["-Dtest.suite.class=com.android.tools.idea.tests.gui.kotlin.JavaToKotlinConversionTest"],
     tags = COMMON_TAGS + [
         "no_mac",
diff --git a/android-uitests/testSrc/com/android/tools/idea/tests/gui/kotlin/JavaToKotlinConversionTest.java b/android-uitests/testSrc/com/android/tools/idea/tests/gui/kotlin/JavaToKotlinConversionTest.java
index bd6302d..ba3de8d 100644
--- a/android-uitests/testSrc/com/android/tools/idea/tests/gui/kotlin/JavaToKotlinConversionTest.java
+++ b/android-uitests/testSrc/com/android/tools/idea/tests/gui/kotlin/JavaToKotlinConversionTest.java
@@ -172,9 +172,26 @@
     ideFrame.requestProjectSyncAndWaitForSyncToFinish();
     guiTest.waitForAllBackgroundTasksToBeCompleted();
 
-   //Invoking project make.
+    // TODO(devtools-engprod): remove this step once b/300329659 is fixed
+    // Starting form Iguana release onwards, kotlinOptions is added in the build.gradle
+    // on configuring kotlin in java project. Above bug is raise to update the
+    // correct version of jvmTarget in kotlinOptions.
+    editor.open("app/build.gradle")
+      .select("jvmTarget.*(17)")
+      .enterText("1.8");
+
+    guiTest.waitForAllBackgroundTasksToBeCompleted();
+
+    // TODO(devtools-engprod): Remove this once all libraries are migrated to kotlin-stdlib
+    // More details for this issue is found here b/278545487
+    // and here https://youtrack.jetbrains.com/issue/KT-55297
+    editor.open("app/build.gradle")
+      .moveBetween("dependencies {", "")
+      .enterText("\nimplementation platform('org.jetbrains.kotlin:kotlin-bom:1.8.0')");
+
+    //Invoking project make.
     ideFrame.invokeAndWaitForBuildAction(Wait.seconds(300),
                                          "Build", "Rebuild Project");
     guiTest.waitForAllBackgroundTasksToBeCompleted();
   }
-}
+}
\ No newline at end of file
diff --git a/android-uitests/testSrc/com/android/tools/idea/tests/gui/projectstructure/AndroidLibsDepTest.java b/android-uitests/testSrc/com/android/tools/idea/tests/gui/projectstructure/AndroidLibsDepTest.java
index 34f35e8..16958c9 100644
--- a/android-uitests/testSrc/com/android/tools/idea/tests/gui/projectstructure/AndroidLibsDepTest.java
+++ b/android-uitests/testSrc/com/android/tools/idea/tests/gui/projectstructure/AndroidLibsDepTest.java
@@ -34,7 +34,7 @@
 @RunWith(GuiTestRemoteRunner.class)
 public class AndroidLibsDepTest {
 
-  @Rule public final GuiTestRule guiTest = new GuiTestRule().withTimeout(10, TimeUnit.MINUTES);
+  @Rule public final GuiTestRule guiTest = new GuiTestRule().withTimeout(15, TimeUnit.MINUTES);
 
   private static final String LIB_NAME_1 = "modulea";
   private static final String LIB_NAME_2 = "moduleb";
diff --git a/android/agpIntegrationTestSrc/com/android/tools/idea/run/UnsignedApkQuickFixTest.kt b/android/agpIntegrationTestSrc/com/android/tools/idea/run/UnsignedApkQuickFixTest.kt
index 489bbf1..30fee5f 100644
--- a/android/agpIntegrationTestSrc/com/android/tools/idea/run/UnsignedApkQuickFixTest.kt
+++ b/android/agpIntegrationTestSrc/com/android/tools/idea/run/UnsignedApkQuickFixTest.kt
@@ -15,17 +15,22 @@
  */
 package com.android.tools.idea.run
 
+import com.android.testutils.MockitoKt
 import com.android.tools.idea.gradle.dsl.api.ProjectBuildModel
 import com.android.tools.idea.testing.AndroidGradleProjectRule
 import com.android.tools.idea.testing.TestProjectPaths
 import com.google.common.truth.Truth.assertThat
 import com.intellij.openapi.actionSystem.DataContext
+import com.intellij.openapi.module.Module
+import junit.framework.TestCase.*
 import org.junit.Rule
 import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
 
+@RunWith(JUnit4::class)
 class UnsignedApkQuickFixTest {
-  @get:Rule
-  val projectRule = AndroidGradleProjectRule()
+  @get:Rule val projectRule = AndroidGradleProjectRule()
 
   @Test
   fun updatesBuildWithSelectedConfig() {
@@ -39,21 +44,94 @@
     assertThat(signingConfigs[0].name()).isEqualTo("debug")
 
     // Fake a selector that picks the default debug signing config.
-    val fakeSelector = object : SigningConfigSelector {
-      override fun showAndGet() = true
-      override fun selectedConfig() = signingConfigs[0]
-    }
+    val fakeSelector =
+      object : SigningConfigSelector {
+        override fun showAndGet() = true
+        override fun selectedConfig() = signingConfigs[0]
+      }
 
     // Release build doesn't have a signing config assigned.
-    val releaseBuildSigningConfig = buildModel.android().buildTypes().find { it.name() == "release" }?.signingConfig()
+    val releaseBuildSigningConfig =
+      buildModel.android().buildTypes().find { it.name() == "release" }?.signingConfig()
     assertThat(releaseBuildSigningConfig?.valueAsString()).isNull()
 
-    val unsignedApkQuickFix = UnsignedApkQuickFix(module, "release") { fakeSelector }
+    val unsignedApkQuickFix = UnsignedApkQuickFix(module, "release", null) { fakeSelector }
     unsignedApkQuickFix.applyFix(DataContext.EMPTY_CONTEXT)
     val updatedBuildModel = ProjectBuildModel.get(projectRule.project).getModuleBuildModel(module)!!
 
     // Release build is now assigned the debug signing config.
-    val expectedSigningConfig = updatedBuildModel.android().buildTypes().find { it.name() == "release" }?.signingConfig()
+    val expectedSigningConfig =
+      updatedBuildModel.android().buildTypes().find { it.name() == "release" }?.signingConfig()
     assertThat(expectedSigningConfig?.valueAsString()).contains("debug")
   }
-}
\ No newline at end of file
+
+  @Test
+  fun differentModuleReCaches() {
+    val module = MockitoKt.mock<Module>()
+    UnsignedApkQuickFix.unsignedApkQuickFix = UnsignedApkQuickFix(module, "release", null)
+
+    val module2 = MockitoKt.mock<Module>()
+    val quickFix = UnsignedApkQuickFix.create(module2, "release", null)
+
+    assertEquals(module2, quickFix!!.module)
+  }
+
+  @Test
+  fun differentBuildTypeReCaches() {
+    val module = MockitoKt.mock<Module>()
+    UnsignedApkQuickFix.unsignedApkQuickFix = UnsignedApkQuickFix(module, "release", null)
+
+    val quickFix = UnsignedApkQuickFix.create(module, "debug", null)
+
+    assertEquals("debug", quickFix!!.selectedBuildTypeName)
+  }
+
+  /**
+   * Tests the case where validation has been run already, but then the {@code
+   * AndroidRunConfigurationEditor} is opened, creating a new QuickFix where the callback would
+   * trigger the editor revalidation.
+   */
+  @Test
+  fun nonNullCallbackReCachesIfCurrentlyNull() {
+    val module = MockitoKt.mock<Module>()
+    UnsignedApkQuickFix.unsignedApkQuickFix = UnsignedApkQuickFix(module, "release", null)
+
+    val callback = MockitoKt.mock<Runnable>()
+    val quickFix = UnsignedApkQuickFix.create(module, "release", callback)
+
+    assertEquals(callback, quickFix!!.callback)
+  }
+
+  /**
+   * Tests the case where the {@code AndroidRunConfigurationEditor} has already set a revalidation
+   * callback, but a different validation request would have created a new QuickFix. In this case,
+   * we do not want to overwrite the cache.
+   */
+  @Test
+  fun nullCallbackDoesNotReCache() {
+    val module = MockitoKt.mock<Module>()
+    val callback = MockitoKt.mock<Runnable>()
+    UnsignedApkQuickFix.unsignedApkQuickFix = UnsignedApkQuickFix(module, "release", callback)
+
+    val quickFix = UnsignedApkQuickFix.create(module, "release", null)
+
+    assertEquals(callback, quickFix!!.callback)
+  }
+
+  /**
+   * Tests the case where a different callback is requested, e.g. if the {@code
+   * AndroidRunConfigurationEditor} dialog is opened again, meaning the new dialog would need to
+   * receive the revalidation request.
+   */
+  @Test
+  fun differentCallbackReCaches() {
+    val module = MockitoKt.mock<Module>()
+    val callback = MockitoKt.mock<Runnable>()
+    UnsignedApkQuickFix.unsignedApkQuickFix = UnsignedApkQuickFix(module, "release", callback)
+
+    val callback2 = MockitoKt.mock<Runnable>()
+    val quickFix = UnsignedApkQuickFix.create(module, "release", callback2)
+
+    assertEquals(callback2, quickFix!!.callback)
+  }
+}
diff --git a/android/editors/testSrc/com/android/tools/idea/editors/GradleImplicitPropertyUsageProviderTest.java b/android/editors/testSrc/com/android/tools/idea/editors/GradleImplicitPropertyUsageProviderTest.java
index a385ec4..1bea436 100644
--- a/android/editors/testSrc/com/android/tools/idea/editors/GradleImplicitPropertyUsageProviderTest.java
+++ b/android/editors/testSrc/com/android/tools/idea/editors/GradleImplicitPropertyUsageProviderTest.java
@@ -55,4 +55,16 @@
       }
     }
   }
+
+  // Regression test for b/298540715
+  public void testResourcesProperties() {
+    VirtualFile vFile = myFixture.createFile("resources.properties", "unqualifiedResLocale=en-US");
+    PsiFile file = PsiManager.getInstance(getProject()).findFile(vFile);
+    assertNotNull(file);
+    PropertiesFile propertiesFile = (PropertiesFile) file;
+    GradleImplicitPropertyUsageProvider provider = new GradleImplicitPropertyUsageProvider();
+    IProperty unqualifiedResLocale = propertiesFile.getProperties().get(0);
+    String name = unqualifiedResLocale.getName();
+    assertTrue(name, provider.isUsed((Property) unqualifiedResLocale));
+  }
 }
\ No newline at end of file
diff --git a/android/gradle/testSrc/com/android/tools/idea/gradle/plugin/AgpVersionsTest.kt b/android/gradle/testSrc/com/android/tools/idea/gradle/plugin/AgpVersionsTest.kt
index 7226230..1b098e5 100644
--- a/android/gradle/testSrc/com/android/tools/idea/gradle/plugin/AgpVersionsTest.kt
+++ b/android/gradle/testSrc/com/android/tools/idea/gradle/plugin/AgpVersionsTest.kt
@@ -100,4 +100,27 @@
       .inOrder()
   }
 
+
+  @Test
+  fun `test get new project wizard versions with dev available`() {
+    val availableVersions = listOf(
+      "8.1.2",
+      "8.2.0-beta01", "8.2.0-beta02", "8.2.0-dev", // Incompatible dev version is ignored
+      "8.3.0-alpha01", "8.3.0-alpha02", "8.3.0-dev",
+    ).map { AgpVersion.parse(it) }.toSet()
+    assertThat(AgpVersions.getNewProjectWizardVersions(
+      latestKnown = AgpVersion.parse("8.3.0-dev"),
+      availableVersions = availableVersions
+    ).map { it.toString() })
+      .containsExactly("8.3.0-dev", "8.3.0-alpha02", "8.2.0-beta02", "8.1.2")
+      .inOrder()
+
+    assertThat(AgpVersions.getNewProjectWizardVersions(
+      latestKnown = AgpVersion.parse("8.3.0-alpha01"),
+      availableVersions = availableVersions
+    ).map { it.toString() })
+      .containsExactly("8.3.0-dev", "8.3.0-alpha01", "8.1.2")
+      .inOrder()
+  }
+
 }
\ No newline at end of file
diff --git a/android/imports/testSrc/com/android/tools/idea/imports/MavenClassRegistryTest.kt b/android/imports/testSrc/com/android/tools/idea/imports/MavenClassRegistryTest.kt
index 2bb8daf..7e4d439 100644
--- a/android/imports/testSrc/com/android/tools/idea/imports/MavenClassRegistryTest.kt
+++ b/android/imports/testSrc/com/android/tools/idea/imports/MavenClassRegistryTest.kt
@@ -21,6 +21,7 @@
 import com.android.tools.idea.imports.MavenClassRegistryBase.LibraryImportData
 import com.google.common.truth.Truth.assertThat
 import com.intellij.openapi.util.Disposer
+import org.jetbrains.kotlin.name.FqName
 import org.junit.Assert.assertThrows
 import org.junit.Test
 import java.nio.charset.StandardCharsets.UTF_8
@@ -52,6 +53,10 @@
                 },
                 {
                   "fqn": "androidx.activity.FakeFunctionKt.FakeFunction"
+                },
+                {
+                  "xfqn": "androidx.activity.FakeFunctionKt.FakeFunction",
+                  "rcvr": "with.a.Receiver"
                 }
               ]
             },
@@ -126,7 +131,7 @@
 
     assertThat(mavenClassRegistry.lookup.topLevelFunctionsMap).containsExactlyEntriesIn(
       mapOf(
-        "PickVisualMediaRequest" to listOf(
+        FunctionSpecifier("PickVisualMediaRequest", null) to listOf(
           LibraryImportData(
             artifact = "androidx.activity:activity",
             importedItemFqName = "androidx.activity.result.PickVisualMediaRequest",
@@ -134,7 +139,7 @@
             version = "1.1.0"
           )
         ),
-        "FakeFunction" to listOf(
+        FunctionSpecifier("FakeFunction", null) to listOf(
           LibraryImportData(
             artifact = "androidx.activity:activity",
             importedItemFqName = "androidx.activity.FakeFunction",
@@ -148,7 +153,15 @@
             version = "1.1.0"
           )
         ),
-        "AnnotationFunction" to listOf(
+        FunctionSpecifier("FakeFunction", FqName("with.a.Receiver")) to listOf(
+          LibraryImportData(
+            artifact = "androidx.activity:activity",
+            importedItemFqName = "androidx.activity.FakeFunction",
+            importedItemPackageName = "androidx.activity",
+            version = "1.1.0"
+          ),
+        ),
+        FunctionSpecifier("AnnotationFunction", null) to listOf(
           LibraryImportData(
             artifact = "androidx.annotation:annotation",
             importedItemFqName = "androidx.annotation.AnnotationFunction",
@@ -361,6 +374,10 @@
                 },
                 {
                   "has_no_fqn": "should be ignored"
+                },
+                {
+                  "xfqn": "foo.bar.baz.FacadeFileKt.someExtensionFunction",
+                  "rcvr": "amazingReceiver"
                 }
               ]
             }
@@ -373,12 +390,18 @@
 
     assertThat(mavenClassRegistry.lookup.topLevelFunctionsMap).containsExactlyEntriesIn(
       mapOf(
-        "someFqn" to listOf(LibraryImportData(
+        FunctionSpecifier("someFqn", null) to listOf(LibraryImportData(
           artifact = "group3:artifact3",
           importedItemFqName = "someFqn",
           importedItemPackageName = "",
           version = "1"
-        ))
+        )),
+        FunctionSpecifier("someExtensionFunction", FqName("amazingReceiver")) to listOf(LibraryImportData(
+        artifact = "group3:artifact3",
+        importedItemFqName = "foo.bar.baz.someExtensionFunction",
+        importedItemPackageName = "foo.bar.baz",
+        version = "1"
+      ))
       )
     )
   }
@@ -541,24 +564,38 @@
 
   @Test
   fun kotlinTopLevelFunction_fromJvmQualifiedName() {
+    with(KotlinTopLevelFunction.fromJvmQualifiedName("com.example.FileFacadeKt.foo", "com.example.Receiver")) {
+      assertThat(simpleName).isEqualTo("foo")
+      assertThat(packageName).isEqualTo("com.example")
+      assertThat(kotlinFqName.asString()).isEqualTo("com.example.foo")
+      assertThat(receiverFqName?.asString()).isEqualTo("com.example.Receiver")
+    }
+  }
+
+  @Test
+  fun kotlinTopLevelFunction_fromJvmQualifiedName_withNullReceiver() {
     with(KotlinTopLevelFunction.fromJvmQualifiedName("com.example.FileFacadeKt.foo")) {
       assertThat(simpleName).isEqualTo("foo")
       assertThat(packageName).isEqualTo("com.example")
       assertThat(kotlinFqName.asString()).isEqualTo("com.example.foo")
+      assertThat(receiverFqName).isNull()
     }
   }
 
   @Test
   fun kotlinTopLevelFunction_fromJvmQualifiedName_noPackageName() {
-    with(KotlinTopLevelFunction.fromJvmQualifiedName("FileFacadeKt.foo")) {
+    with(KotlinTopLevelFunction.fromJvmQualifiedName("FileFacadeKt.foo", "com.example.Receiver")) {
       assertThat(simpleName).isEqualTo("foo")
       assertThat(packageName).isEqualTo("")
       assertThat(kotlinFqName.asString()).isEqualTo("foo")
+      assertThat(receiverFqName?.asString()).isEqualTo("com.example.Receiver")
     }
   }
 
   @Test
   fun kotlinTopLevelFunction_fromJvmQualifiedName_noFacadeFile() {
-    assertThrows(IllegalArgumentException::class.java) { KotlinTopLevelFunction.fromJvmQualifiedName("foo") }
+    assertThrows(IllegalArgumentException::class.java) {
+      KotlinTopLevelFunction.fromJvmQualifiedName("foo", "com.example.Receiver")
+    }
   }
 }
diff --git a/android/jetbrains/testSrc/org/jetbrains/android/exportSignedPackage/ApkStepTest.kt b/android/jetbrains/testSrc/org/jetbrains/android/exportSignedPackage/ApkStepTest.kt
index 1541d7c..03fd67c 100644
--- a/android/jetbrains/testSrc/org/jetbrains/android/exportSignedPackage/ApkStepTest.kt
+++ b/android/jetbrains/testSrc/org/jetbrains/android/exportSignedPackage/ApkStepTest.kt
@@ -15,14 +15,22 @@
  */
 package org.jetbrains.android.exportSignedPackage
 
+import com.android.testutils.MockitoKt.argumentCaptor
 import com.android.testutils.MockitoKt.whenever
 import com.android.tools.idea.help.AndroidWebHelpProvider
 import com.google.common.truth.Truth
 import com.intellij.ide.util.PropertiesComponent
 import com.intellij.openapi.roots.ModuleRootManager
 import com.intellij.testFramework.LightPlatformTestCase
+import org.jetbrains.android.exportSignedPackage.ApkStep.RUN_PROGUARD_PROPERTY
+import org.jetbrains.android.facet.AndroidFacet
+import org.jetbrains.android.facet.AndroidFacetConfiguration
+import org.jetbrains.android.facet.AndroidFacetProperties
 import org.jetbrains.kotlin.konan.file.File
 import org.mockito.Mockito
+import org.mockito.Mockito.verify
+import java.nio.file.Files.isSameFile
+import kotlin.io.path.Path
 
 class ApkStepTest : LightPlatformTestCase() {
   private val myWizard = Mockito.mock(ExportSignedPackageWizard::class.java)
@@ -56,4 +64,31 @@
     // Clean up properties after tests
     properties.setValue(apkPathPropertyName, null)
   }
+
+  fun testApkDestinationEndsWhiteSpace() {
+    val apkStep = ApkStep(myWizard)
+    val properties = PropertiesComponent.getInstance(project)
+    val destinationPath = "${this.homePath}${File.separator}Apk "
+    val testFacet = Mockito.mock(AndroidFacet::class.java)
+    whenever(testFacet.module).thenReturn(module)
+    val facetConfiguration = Mockito.mock(AndroidFacetConfiguration::class.java)
+    val facetProperties = AndroidFacetProperties()
+    facetProperties.RUN_PROGUARD = false
+    whenever(facetConfiguration.state).thenReturn(facetProperties)
+    whenever(testFacet.configuration).thenReturn(facetConfiguration)
+    whenever(myWizard.facet).thenReturn(testFacet)
+    properties.setValue(apkStep.getApkPathPropertyName(module.name), destinationPath)
+    properties.setValue(RUN_PROGUARD_PROPERTY, "false")
+
+    val apkDir = java.io.File(destinationPath)
+    if (!apkDir.exists()) {
+      Truth.assertThat(apkDir.mkdirs()).isTrue()
+    }
+
+    apkStep._init(testFacet)
+    val captor = argumentCaptor<String>()
+    apkStep._commit(false)
+    verify(myWizard).setApkPath(captor.capture())
+    Truth.assertThat(isSameFile(Path(captor.value), Path(destinationPath))).isTrue()
+  }
 }
\ No newline at end of file
diff --git a/android/jetbrains/testSrc/org/jetbrains/android/exportSignedPackage/GradleSignStepTest.kt b/android/jetbrains/testSrc/org/jetbrains/android/exportSignedPackage/GradleSignStepTest.kt
index 37d61c1..fa8aacd 100644
--- a/android/jetbrains/testSrc/org/jetbrains/android/exportSignedPackage/GradleSignStepTest.kt
+++ b/android/jetbrains/testSrc/org/jetbrains/android/exportSignedPackage/GradleSignStepTest.kt
@@ -15,13 +15,18 @@
  */
 package org.jetbrains.android.exportSignedPackage
 
+import com.android.testutils.MockitoKt.argumentCaptor
 import com.android.testutils.MockitoKt.whenever
+import com.android.tools.idea.gradle.project.model.GradleAndroidModel
 import com.android.tools.idea.help.AndroidWebHelpProvider
 import com.google.common.truth.Truth.assertThat
 import com.intellij.ide.util.PropertiesComponent
 import com.intellij.testFramework.LightPlatformTestCase
 import org.mockito.Mockito
+import org.mockito.Mockito.verify
 import java.io.File
+import java.nio.file.Files
+import kotlin.io.path.Path
 
 class GradleSignStepTest : LightPlatformTestCase() {
   private var myWizard = Mockito.mock(ExportSignedPackageWizard::class.java)
@@ -41,7 +46,7 @@
     val properties = PropertiesComponent.getInstance()
     val projectPath = project.baseDir.path
     // Set Bundle to confirm it is not the same
-    val bundlePath = this.homePath + File.pathSeparator + "Bundle"
+    val bundlePath = this.homePath + File.separator + "Bundle"
     properties.setValue(gradleSignStep.getApkPathPropertyName(name, ExportSignedPackageWizard.BUNDLE), bundlePath)
     assertThat(gradleSignStep.getInitialPath(properties, name, ExportSignedPackageWizard.APK)).isEqualTo(projectPath)
   }
@@ -51,7 +56,7 @@
     val properties = PropertiesComponent.getInstance()
     val projectPath = project.baseDir.path
     // Set Apk to confirm it is not the same
-    val apkPath = this.homePath + File.pathSeparator + "Apk"
+    val apkPath = this.homePath + File.separator + "Apk"
     properties.setValue(gradleSignStep.getApkPathPropertyName(name, ExportSignedPackageWizard.APK), apkPath)
     assertThat(gradleSignStep.getInitialPath(properties, name, ExportSignedPackageWizard.BUNDLE)).isEqualTo(projectPath)
   }
@@ -59,8 +64,8 @@
   fun testInitialDestinationApkSet() {
     val gradleSignStep = GradleSignStep(myWizard)
     val properties = PropertiesComponent.getInstance()
-    val apkPath = this.homePath + File.pathSeparator + "Apk"
-    val bundlePath = this.homePath + File.pathSeparator + "Bundle"
+    val apkPath = this.homePath + File.separator + "Apk"
+    val bundlePath = this.homePath + File.separator + "Bundle"
     properties.setValue(gradleSignStep.getApkPathPropertyName(name, ExportSignedPackageWizard.APK), apkPath)
     properties.setValue(gradleSignStep.getApkPathPropertyName(name, ExportSignedPackageWizard.BUNDLE), bundlePath)
     assertThat(gradleSignStep.getInitialPath(properties, name, ExportSignedPackageWizard.APK)).isEqualTo(apkPath)
@@ -69,10 +74,40 @@
   fun testInitialDestinationBundleSet() {
     val gradleSignStep = GradleSignStep(myWizard)
     val properties = PropertiesComponent.getInstance()
-    val apkPath = this.homePath + File.pathSeparator + "Apk"
-    val bundlePath = this.homePath + File.pathSeparator + "Bundle"
+    val apkPath = this.homePath + File.separator + "Apk"
+    val bundlePath = this.homePath + File.separator + "Bundle"
     properties.setValue(gradleSignStep.getApkPathPropertyName(name, ExportSignedPackageWizard.BUNDLE), bundlePath)
     properties.setValue(gradleSignStep.getApkPathPropertyName(name, ExportSignedPackageWizard.APK), apkPath)
     assertThat(gradleSignStep.getInitialPath(properties, name, ExportSignedPackageWizard.BUNDLE)).isEqualTo(bundlePath)
   }
+
+  fun testApkDestinationEndsWhiteSpace() {
+    verifyDestinationEndsWhiteSpace(ExportSignedPackageWizard.APK)
+  }
+
+  fun testBundleDestinationEndsWhiteSpace() {
+    verifyDestinationEndsWhiteSpace(ExportSignedPackageWizard.BUNDLE)
+  }
+
+  private fun verifyDestinationEndsWhiteSpace(targetType: String) {
+    val gradleSignStep = GradleSignStep(myWizard)
+    val properties = PropertiesComponent.getInstance(project)
+    val destinationPath = "${this.homePath}${File.separator}$targetType "
+    whenever(myWizard.targetType).thenReturn(targetType)
+    val testAndroidModel = Mockito.mock(GradleAndroidModel::class.java)
+    whenever(testAndroidModel.moduleName).thenReturn(name)
+    whenever(testAndroidModel.variantNames).thenReturn(listOf("debug", "release"))
+    properties.setValue(gradleSignStep.getApkPathPropertyName(name, targetType), destinationPath)
+    properties.setList(GradleSignStep.PROPERTY_BUILD_VARIANTS, listOf("release"))
+
+    val apkDir = File(destinationPath)
+    if (!apkDir.exists()) {
+      assertThat(apkDir.mkdirs()).isTrue()
+    }
+    gradleSignStep._init(testAndroidModel)
+    val captor = argumentCaptor<String>()
+    gradleSignStep.commitForNext()
+    verify(myWizard).setApkPath(captor.capture())
+    assertThat(Files.isSameFile(Path(captor.value), Path(destinationPath))).isTrue()
+  }
 }
\ No newline at end of file
diff --git a/android/lint_baseline.xml b/android/lint_baseline.xml
index 556f9f8..349301a 100644
--- a/android/lint_baseline.xml
+++ b/android/lint_baseline.xml
@@ -499,6 +499,30 @@
 
     <issue
         id="VisibleForTests"
+        message="This class should only be accessed from tests or within package private scope">
+        <location
+            file="src/com/android/tools/idea/rendering/classloading/ClassWriterWithPseudoClassLocator.kt"
+            line="164"/>
+    </issue>
+
+    <issue
+        id="VisibleForTests"
+        message="This class should only be accessed from tests or within package private scope">
+        <location
+            file="src/com/android/tools/idea/editors/literals/LiveLiteralsService.kt"
+            line="135"/>
+    </issue>
+
+    <issue
+        id="VisibleForTests"
+        message="This class should only be accessed from tests or within package private scope">
+        <location
+            file="src/com/android/tools/idea/editors/literals/LiveLiteralsService.kt"
+            line="135"/>
+    </issue>
+
+    <issue
+        id="VisibleForTests"
         message="This method should only be accessed from tests or within package private scope">
         <location
             file="src/com/android/tools/idea/editors/literals/LiveLiteralsService.kt"
@@ -563,6 +587,14 @@
 
     <issue
         id="VisibleForTests"
+        message="This class should only be accessed from tests or within package private scope">
+        <location
+            file="src/com/android/tools/idea/editors/literals/actions/LiveLiteralsStatusAction.kt"
+            line="53"/>
+    </issue>
+
+    <issue
+        id="VisibleForTests"
         message="This method should only be accessed from tests or within package private scope">
         <location
             file="src/com/android/tools/idea/editors/literals/actions/LiveLiteralsStatusAction.kt"
diff --git a/android/res/testSrc/com/android/tools/idea/res/LightClassesTests.kt b/android/res/testSrc/com/android/tools/idea/res/LightClassesTests.kt
index ad46e44..21b06fe 100644
--- a/android/res/testSrc/com/android/tools/idea/res/LightClassesTests.kt
+++ b/android/res/testSrc/com/android/tools/idea/res/LightClassesTests.kt
@@ -36,6 +36,7 @@
 import com.android.tools.idea.testing.AndroidModuleModelBuilder
 import com.android.tools.idea.testing.AndroidProjectRule
 import com.android.tools.idea.testing.AndroidProjectStubBuilder
+import com.android.tools.idea.testing.JavaLibraryDependency
 import com.android.tools.idea.testing.JavaModuleModelBuilder.Companion.rootModuleBuilder
 import com.android.tools.idea.testing.buildAgpProjectFlagsStub
 import com.android.tools.idea.testing.caret
@@ -49,6 +50,7 @@
 import com.android.tools.idea.testing.updatePrimaryManifest
 import com.android.tools.idea.testing.waitForResourceRepositoryUpdates
 import com.android.tools.idea.util.androidFacet
+import com.android.tools.tests.AdtTestKotlinArtifacts
 import com.android.utils.executeWithRetries
 import com.google.common.truth.Truth.assertThat
 import com.intellij.codeInsight.lookup.LookupElement
@@ -715,6 +717,10 @@
       .withAndroidModuleDependencyList { _ ->
         listOf(AndroidModuleDependency(":mylib", "debug"))
       }
+      // TODO(b/300170256): Remove this once 2023.3 merges and we no longer need kotlin-stdlib for every Kotlin test.
+      .withJavaLibraryDependencyList {
+        listOf(JavaLibraryDependency.forJar(AdtTestKotlinArtifacts.kotlinStdlib))
+      }
       .withAgpProjectFlags { getAgpProjectFlags(this) },
   )
 
diff --git a/android/resources/wizardData/distributions.json b/android/resources/wizardData/distributions.json
index 966a3e5..3acdecf 100644
--- a/android/resources/wizardData/distributions.json
+++ b/android/resources/wizardData/distributions.json
@@ -3,7 +3,7 @@
     "name": "KitKat",
     "version": "4.4",
     "apiLevel": 19,
-    "distributionPercentage": 0.005,
+    "distributionPercentage": 0.004,
     "url": "https://developer.android.com/about/versions/android-4.4.html",
     "descriptionBlocks": [
       {
@@ -40,15 +40,15 @@
       },
       {
         "title": "",
-        "body": "Last updated: May 30, 2023"
+        "body": "Last updated: September 1, 2023"
       }
     ]
   },
   {
     "name": "Lollipop",
-    "version": "5.0",
+    "version": "5",
     "apiLevel": 21,
-    "distributionPercentage": 0.003,
+    "distributionPercentage": 0.002,
     "url": "https://developer.android.com/about/versions/android-5.0.html",
     "descriptionBlocks": [
       {
@@ -105,7 +105,7 @@
       },
       {
         "title": "",
-        "body": "Last updated: May 30, 2023"
+        "body": "Last updated: September 1, 2023"
       }
     ]
   },
@@ -113,7 +113,7 @@
     "name": "Lollipop",
     "version": "5.1",
     "apiLevel": 22,
-    "distributionPercentage": 0.015,
+    "distributionPercentage": 0.013,
     "url": "https://developer.android.com/about/versions/android-5.1.html",
     "descriptionBlocks": [
       {
@@ -126,15 +126,15 @@
       },
       {
         "title": "",
-        "body": "Last updated: May 30, 2023"
+        "body": "Last updated: September 1, 2023"
       }
     ]
   },
   {
     "name": "Marshmallow",
-    "version": "6.0",
+    "version": "6",
     "apiLevel": 23,
-    "distributionPercentage": 0.023,
+    "distributionPercentage": 0.02,
     "url": "https://developer.android.com/about/versions/marshmallow/android-6.0.html",
     "descriptionBlocks": [
       {
@@ -167,15 +167,15 @@
       },
       {
         "title": "",
-        "body": "Last updated: May 30, 2023"
+        "body": "Last updated: September 1, 2023"
       }
     ]
   },
   {
     "name": "Nougat",
-    "version": "7.0",
+    "version": "7",
     "apiLevel": 24,
-    "distributionPercentage": 0.015,
+    "distributionPercentage": 0.013,
     "url": "https://developer.android.com/about/versions/nougat/android-7.0.html",
     "descriptionBlocks": [
       {
@@ -224,7 +224,7 @@
       },
       {
         "title": "",
-        "body": "Last updated: May 30, 2023"
+        "body": "Last updated: September 1, 2023"
       }
     ]
   },
@@ -232,7 +232,7 @@
     "name": "Nougat",
     "version": "7.1",
     "apiLevel": 25,
-    "distributionPercentage": 0.015,
+    "distributionPercentage": 0.014,
     "url": "https://developer.android.com/about/versions/nougat/android-7.1.html",
     "descriptionBlocks": [
       {
@@ -261,15 +261,15 @@
       },
       {
         "title": "",
-        "body": "Last updated: May 30, 2023"
+        "body": "Last updated: September 1, 2023"
       }
     ]
   },
   {
     "name": "Oreo",
-    "version": "8.0",
+    "version": "8",
     "apiLevel": 26,
-    "distributionPercentage": 0.022,
+    "distributionPercentage": 0.02,
     "url": "https://developer.android.com/about/versions/oreo/android-8.0",
     "descriptionBlocks": [
       {
@@ -298,7 +298,7 @@
       },
       {
         "title": "",
-        "body": "Last updated: May 30, 2023"
+        "body": "Last updated: September 1, 2023"
       }
     ]
   },
@@ -306,7 +306,7 @@
     "name": "Oreo",
     "version": "8.1",
     "apiLevel": 27,
-    "distributionPercentage": 0.061,
+    "distributionPercentage": 0.055,
     "url": "https://developer.android.com/about/versions/oreo/android-8.1",
     "descriptionBlocks": [
       {
@@ -327,15 +327,15 @@
       },
       {
         "title": "",
-        "body": "Last updated: May 30, 2023"
+        "body": "Last updated: September 1, 2023"
       }
     ]
   },
   {
     "name": "Pie",
-    "version": "9.0",
+    "version": "9",
     "apiLevel": 28,
-    "distributionPercentage": 0.119,
+    "distributionPercentage": 0.108,
     "url": "https://developer.android.com/about/versions/pie/android-9.0",
     "descriptionBlocks": [
       {
@@ -360,15 +360,15 @@
       },
       {
         "title": "",
-        "body": "Last updated: May 30, 2023"
+        "body": "Last updated: September 1, 2023"
       }
     ]
   },
   {
     "name": "Q",
-    "version": "10.0",
+    "version": "10",
     "apiLevel": 29,
-    "distributionPercentage": 0.178,
+    "distributionPercentage": 0.166,
     "url": "https://developer.android.com/about/versions/10",
     "descriptionBlocks": [
       {
@@ -389,15 +389,15 @@
       },
       {
         "title": "",
-        "body": "Last updated: May 30, 2023"
+        "body": "Last updated: September 1, 2023"
       }
     ]
   },
   {
     "name": "R",
-    "version": "11.0",
+    "version": "11",
     "apiLevel": 30,
-    "distributionPercentage": 0.231,
+    "distributionPercentage": 0.22,
     "url": "https://developer.android.com/about/versions/11",
     "descriptionBlocks": [
       {
@@ -414,15 +414,15 @@
       },
       {
         "title": "",
-        "body": "Last updated: May 30, 2023"
+        "body": "Last updated: September 1, 2023"
       }
     ]
   },
   {
     "name": "S",
-    "version": "12.0",
+    "version": "12",
     "apiLevel": 31,
-    "distributionPercentage": 0.163,
+    "distributionPercentage": 0.159,
     "url": "https://developer.android.com/about/versions/12",
     "descriptionBlocks": [
       {
@@ -443,15 +443,15 @@
       },
       {
         "title": "",
-        "body": "Last updated: May 30, 2023"
+        "body": "Last updated: September 1, 2023"
       }
     ]
   },
   {
     "name": "T",
-    "version": "13.0",
+    "version": "13",
     "apiLevel": 33,
-    "distributionPercentage": 0.147,
+    "distributionPercentage": 0.204,
     "url": "https://developer.android.com/about/versions/13",
     "descriptionBlocks": [
       {
@@ -468,7 +468,7 @@
       },
       {
         "title": "",
-        "body": "Last updated: May 30, 2023"
+        "body": "Last updated: September 1, 2023"
       }
     ]
   }
diff --git a/android/run/testSrc/com/android/tools/idea/run/AndroidActivityRunLineMarkerContributorTest.kt b/android/run/testSrc/com/android/tools/idea/run/AndroidActivityRunLineMarkerContributorTest.kt
new file mode 100644
index 0000000..870ceef
--- /dev/null
+++ b/android/run/testSrc/com/android/tools/idea/run/AndroidActivityRunLineMarkerContributorTest.kt
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.run
+
+import com.android.tools.idea.testing.AndroidProjectRule
+import com.android.tools.idea.testing.onEdt
+import com.intellij.psi.PsiElement
+import com.intellij.psi.PsiFile
+import com.intellij.testFramework.RunsInEdt
+import junit.framework.TestCase.assertNotNull
+import junit.framework.TestCase.assertNull
+import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+
+class AndroidActivityRunLineMarkerContributorTest {
+
+  @get:Rule val projectRule = AndroidProjectRule.inMemory().onEdt()
+
+  @Before
+  fun setUp() {
+    // Simulate the existence of android.app.Activity
+    projectRule.fixture.addFileToProject(
+      "src/android/app/Activity.java",
+      """
+      package android.app
+
+      class Activity {}
+      """
+        .trimIndent()
+    )
+  }
+
+  @Test
+  @RunsInEdt
+  fun identifyKotlinActivity() {
+    val activityFile =
+      projectRule.fixture.addFileToProject(
+        "src/com/example/myapplication/MyActivity.kt",
+        """
+      package com.example.myapplication
+
+      import android.app.Activity
+
+      /**
+       */
+      class MyActivity : Activity() {
+      }
+      """
+          .trimIndent()
+      )
+
+    val contributor = AndroidActivityRunLineMarkerContributor()
+    assertNotNull(contributor.getInfo(activityFile.findElementByText("class")))
+    assertNull(
+      contributor.getInfo(activityFile.findElementByText("package com.example.myapplication"))
+    )
+  }
+
+  @Test
+  @RunsInEdt
+  fun identifyJavaActivity() {
+    val activityFile =
+      projectRule.fixture.addFileToProject(
+        "src/com/example/myapplication/MyActivity.java",
+        """
+      package com.example.myapplication;
+
+      import android.app.Activity;
+
+      /**
+       */
+      class MyActivity extends Activity {
+      }
+      """
+          .trimIndent()
+      )
+
+    val contributor = AndroidActivityRunLineMarkerContributor()
+    assertNotNull(contributor.getInfo(activityFile.findElementByText("class")))
+    assertNull(
+      contributor.getInfo(activityFile.findElementByText("package com.example.myapplication;"))
+    )
+  }
+}
+
+fun PsiFile.findElementByText(text: String): PsiElement =
+  findDescendantOfType { it.node.text == text }!!
diff --git a/android/run/testSrc/com/android/tools/idea/run/deployment/SelectMultipleDevicesDialogTest.java b/android/run/testSrc/com/android/tools/idea/run/deployment/SelectMultipleDevicesDialogTest.java
index 6aad8c0..0a81eac 100644
--- a/android/run/testSrc/com/android/tools/idea/run/deployment/SelectMultipleDevicesDialogTest.java
+++ b/android/run/testSrc/com/android/tools/idea/run/deployment/SelectMultipleDevicesDialogTest.java
@@ -156,7 +156,8 @@
     ApplicationManager.getApplication().invokeAndWait(() -> myDialog.getOKAction().actionPerformed(null));
 
     // Assert
-    Mockito.verify(service).setTargetsSelectedWithDialog(Collections.singleton(new QuickBootTarget(Keys.PIXEL_4_API_30)));
+    QuickBootTarget target = new QuickBootTarget(Keys.PIXEL_4_API_30);
+    Mockito.verify(service).setTargetsSelectedWithDialog(Collections.singleton(target), Collections.singletonList(target));
   }
 
   @Test
diff --git a/android/run/testSrc/com/android/tools/idea/run/deployment/TargetsForWritingSupplierTest.java b/android/run/testSrc/com/android/tools/idea/run/deployment/TargetsForWritingSupplierTest.java
index cc547af..df9a2d4 100644
--- a/android/run/testSrc/com/android/tools/idea/run/deployment/TargetsForWritingSupplierTest.java
+++ b/android/run/testSrc/com/android/tools/idea/run/deployment/TargetsForWritingSupplierTest.java
@@ -15,8 +15,10 @@
  */
 package com.android.tools.idea.run.deployment;
 
+import static com.google.common.truth.Truth.assertThat;
 import static org.junit.Assert.assertEquals;
 
+import com.google.common.collect.ImmutableList;
 import java.util.Optional;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -91,4 +93,30 @@
     assertEquals(Optional.of(newTarget), runningDeviceTarget);
     assertEquals(Optional.of(oldTarget), target);
   }
+
+  @Test
+  public void runningDeviceHasOldTarget() {
+    Target oldTarget = new BootWithSnapshotTarget(Keys.PIXEL_4_API_30, Keys.PIXEL_4_API_30_SNAPSHOT_2);
+    Target newTarget = new RunningDeviceTarget(Keys.PIXEL_4_API_30);
+    Target defaultLaunchTarget = new QuickBootTarget(Keys.PIXEL_4_API_30);
+
+    TargetsForWritingSupplier supplier =
+      new TargetsForWritingSupplier(ImmutableList.of(oldTarget), ImmutableList.of(newTarget), ImmutableList.of(defaultLaunchTarget));
+
+    // Default launch target is not used because we already had a launchable target
+    assertThat(supplier.getDialogRunningDeviceTargets()).containsExactly(newTarget);
+    assertThat(supplier.getDialogTargets()).containsExactly(oldTarget);
+  }
+
+  @Test
+  public void runningDeviceHasNoOldTarget() {
+    Target newTarget = new RunningDeviceTarget(Keys.PIXEL_4_API_30);
+    Target defaultLaunchTarget = new QuickBootTarget(Keys.PIXEL_4_API_30);
+
+    TargetsForWritingSupplier supplier =
+      new TargetsForWritingSupplier(ImmutableList.of(), ImmutableList.of(newTarget), ImmutableList.of(defaultLaunchTarget));
+
+    assertThat(supplier.getDialogRunningDeviceTargets()).containsExactly(newTarget);
+    assertThat(supplier.getDialogTargets()).containsExactly(defaultLaunchTarget);
+  }
 }
diff --git a/android/run/testSrc/com/android/tools/idea/run/deployment/liveedit/ComposableCompileTest.kt b/android/run/testSrc/com/android/tools/idea/run/deployment/liveedit/ComposableCompileTest.kt
index 43293ed..e7875a7 100644
--- a/android/run/testSrc/com/android/tools/idea/run/deployment/liveedit/ComposableCompileTest.kt
+++ b/android/run/testSrc/com/android/tools/idea/run/deployment/liveedit/ComposableCompileTest.kt
@@ -285,7 +285,6 @@
       """.trimIndent()
 
   // Regression test for invalid incremental analysis. See b/295257198.
-  @Ignore("b/295257198")
   @Test
   fun incrementalAnalysisFunctionBodyTest() {
     val fileName = "Test.kt"
@@ -311,7 +310,6 @@
   }
 
   // Regression test for invalid incremental analysis. See b/295257198.
-  @Ignore("b/295257198")
   @Test
   fun incrementalAnalysisFunctionExpressionBodyTest() {
     val fileName = "Test.kt"
diff --git a/android/run/testSrc/com/android/tools/idea/run/editor/AndroidRunConfigurationEditorForCloudTestMatrixTest.java b/android/run/testSrc/com/android/tools/idea/run/editor/AndroidRunConfigurationEditorForCloudTestMatrixTest.java
index 05e194a..1a044b3 100644
--- a/android/run/testSrc/com/android/tools/idea/run/editor/AndroidRunConfigurationEditorForCloudTestMatrixTest.java
+++ b/android/run/testSrc/com/android/tools/idea/run/editor/AndroidRunConfigurationEditorForCloudTestMatrixTest.java
@@ -17,15 +17,10 @@
 
 import static org.junit.Assert.assertEquals;
 
-import com.android.tools.idea.execution.common.debug.AndroidDebuggerContext;
-import com.android.tools.idea.run.ConfigurationSpecificEditor;
 import com.android.tools.idea.run.TargetSelectionMode;
-import com.android.tools.idea.run.deployment.DeviceAndSnapshotComboBoxTargetProvider;
 import com.android.tools.idea.testartifacts.instrumented.AndroidTestRunConfiguration;
 import com.android.tools.idea.testing.AndroidProjectRule;
-import java.util.Arrays;
 import java.util.List;
-import javax.swing.JLabel;
 import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -33,41 +28,24 @@
 public final class AndroidRunConfigurationEditorForCloudTestMatrixTest {
   @Rule
   public final AndroidProjectRule myRule = AndroidProjectRule.inMemory();
+  private AndroidRunConfigurationEditor<AndroidTestRunConfiguration> androidRunConfigurationEditor;
 
   @Test
   public void applyEditorTo() {
     // Arrange
-    AndroidDebuggerContext androidDebuggerContext = Mockito.mock(AndroidDebuggerContext.class);
     DeployTargetProvider provider = new CloudTestMatrixTargetProvider();
-    List<DeployTargetProvider> providers = Arrays.asList(new DeviceAndSnapshotComboBoxTargetProvider(), provider);
+    AndroidRunConfigurationEditorTest runConfigEditorTest = new AndroidRunConfigurationEditorTest();
+    List<DeployTargetProvider> providers = runConfigEditorTest.getTargetProviders(provider);
 
-    AndroidTestRunConfiguration configuration1 = Mockito.mock(AndroidTestRunConfiguration.class);
-    Mockito.when(configuration1.getAndroidDebuggerContext()).thenReturn(androidDebuggerContext);
-    Mockito.when(configuration1.getApplicableDeployTargetProviders()).thenReturn(providers);
-    Mockito.when(configuration1.getProfilerState()).thenReturn(new ProfilerState());
-
-    @SuppressWarnings("unchecked")
-    ConfigurationSpecificEditor<AndroidTestRunConfiguration> configurationSpecificEditor = Mockito.mock(ConfigurationSpecificEditor.class);
-    Mockito.when(configurationSpecificEditor.getComponent()).thenReturn(new JLabel());
-
-    AndroidRunConfigurationEditor<AndroidTestRunConfiguration> androidRunConfigurationEditor =
-      new AndroidRunConfigurationEditor<>(
-        myRule.getProject(),
-        facet -> false,
-        configuration1,
-        true,
-        false,
-        moduleSelector -> configurationSpecificEditor);
-
+    androidRunConfigurationEditor = runConfigEditorTest.getAndroidRunConfigurationEditor(provider, myRule.getProject());
     DeployTargetContext deployTargetContext = new DeployTargetContext(providers);
-
-    AndroidTestRunConfiguration configuration2 = Mockito.mock(AndroidTestRunConfiguration.class);
-    Mockito.when(configuration2.getDeployTargetContext()).thenReturn(deployTargetContext);
-    Mockito.when(configuration2.getProfilerState()).thenReturn(new ProfilerState());
+    AndroidTestRunConfiguration configuration = Mockito.mock(AndroidTestRunConfiguration.class);
+    Mockito.when(configuration.getDeployTargetContext()).thenReturn(deployTargetContext);
+    Mockito.when(configuration.getProfilerState()).thenReturn(new ProfilerState());
 
     // Act
     androidRunConfigurationEditor.getDeploymentTargetOptions().getTargetComboBox().setSelectedItem(provider);
-    androidRunConfigurationEditor.applyEditorTo(configuration2);
+    androidRunConfigurationEditor.applyEditorTo(configuration);
 
     // Assert
     assertEquals(TargetSelectionMode.FIREBASE_DEVICE_MATRIX, deployTargetContext.getTargetSelectionMode());
diff --git a/android/run/testSrc/com/android/tools/idea/run/editor/AndroidRunConfigurationEditorTest.kt b/android/run/testSrc/com/android/tools/idea/run/editor/AndroidRunConfigurationEditorTest.kt
index 859b97f..bf90191 100644
--- a/android/run/testSrc/com/android/tools/idea/run/editor/AndroidRunConfigurationEditorTest.kt
+++ b/android/run/testSrc/com/android/tools/idea/run/editor/AndroidRunConfigurationEditorTest.kt
@@ -15,6 +15,8 @@
  */
 package com.android.tools.idea.run.editor
 
+import com.android.tools.idea.execution.common.debug.AndroidDebuggerContext
+import com.android.tools.idea.flags.StudioFlags
 import com.android.tools.idea.gradle.model.IdeAndroidProjectType.PROJECT_TYPE_DYNAMIC_FEATURE
 import com.android.tools.idea.gradle.model.IdeAndroidProjectType.PROJECT_TYPE_LIBRARY
 import com.android.tools.idea.gradle.model.IdeAndroidProjectType.PROJECT_TYPE_TEST
@@ -23,6 +25,7 @@
 import com.android.tools.idea.projectsystem.getMainModule
 import com.android.tools.idea.run.AndroidRunConfiguration
 import com.android.tools.idea.run.AndroidRunConfigurationType
+import com.android.tools.idea.run.ConfigurationSpecificEditor
 import com.android.tools.idea.run.configuration.AndroidComplicationConfiguration
 import com.android.tools.idea.run.configuration.AndroidComplicationConfigurationType
 import com.android.tools.idea.run.configuration.AndroidTileConfigurationType
@@ -30,6 +33,7 @@
 import com.android.tools.idea.run.configuration.AndroidWearConfiguration
 import com.android.tools.idea.run.configuration.editors.AndroidComplicationConfigurationEditor
 import com.android.tools.idea.run.configuration.editors.AndroidWearConfigurationEditor
+import com.android.tools.idea.run.deployment.DeviceAndSnapshotComboBoxTargetProvider
 import com.android.tools.idea.testartifacts.instrumented.AndroidTestRunConfiguration
 import com.android.tools.idea.testartifacts.instrumented.AndroidTestRunConfigurationType
 import com.android.tools.idea.testing.AndroidModuleModelBuilder
@@ -41,7 +45,6 @@
 import com.android.tools.idea.testing.onEdt
 import com.google.common.truth.Expect
 import com.google.common.truth.Truth.assertThat
-import com.intellij.execution.RunConfigurationConverter
 import com.intellij.execution.configurations.ConfigurationType
 import com.intellij.execution.configurations.ConfigurationTypeUtil.findConfigurationType
 import com.intellij.execution.configurations.RunConfiguration
@@ -49,9 +52,13 @@
 import com.intellij.openapi.module.Module
 import com.intellij.openapi.module.ModuleManager
 import com.intellij.openapi.options.SettingsEditor
+import com.intellij.openapi.project.Project
 import com.intellij.testFramework.RunsInEdt
+import org.junit.After
 import org.junit.Rule
 import org.junit.Test
+import org.mockito.Mockito
+import javax.swing.JLabel
 
 @RunsInEdt
 class AndroidRunConfigurationEditorTest {
@@ -69,6 +76,12 @@
   @get:Rule
   val expect: Expect = Expect.createAndEnableStackTrace()
 
+  @After
+  fun tearDown() {
+    // Need to clear any override we use inside tests here.
+    StudioFlags.PROFILER_TASK_BASED_UX.clearOverride()
+  }
+
   @Test
   fun `android run configuration`() {
     val runConfiguration = createConfiguration<AndroidRunConfiguration>(AndroidRunConfigurationType::class.java)
@@ -123,6 +136,20 @@
       )
   }
 
+  @Test
+  fun testProfilingTabAvailable() {
+    StudioFlags.PROFILER_TASK_BASED_UX.override(false)
+    // Profiling tab available
+    assertThat(getProfilingTabIndex()).isNotEqualTo(-1)
+  }
+
+  @Test
+  fun testProfilingTabNotAvailable() {
+    StudioFlags.PROFILER_TASK_BASED_UX.override(true)
+    // Profiling tab not available
+    assertThat(getProfilingTabIndex()).isEqualTo(-1)
+  }
+
   private inline fun <reified R> createConfiguration(configurationTypeClass: Class<out ConfigurationType>): R {
     val configurationType = findConfigurationType(configurationTypeClass)
     val configurationFactory = configurationType.configurationFactories.single()
@@ -138,4 +165,38 @@
   ): List<Module> {
     return ModuleManager.getInstance(projectRule.project).modules.filter { selector(configurationEditor as E).isModuleAccepted(it) }
   }
+
+  private fun getProfilingTabIndex(): Int {
+    val provider: DeployTargetProvider = CloudTestMatrixTargetProvider()
+    var androidRunConfigurationEditor = getAndroidRunConfigurationEditor(provider, projectRule.project)
+    return androidRunConfigurationEditor.myTabbedPane.indexOfTab("Profiling")
+  }
+
+  fun getTargetProviders(provider: DeployTargetProvider): List<DeployTargetProvider> {
+    return listOf(DeviceAndSnapshotComboBoxTargetProvider(), provider)
+  }
+
+  fun getAndroidRunConfigurationEditor(provider: DeployTargetProvider,
+                                       project: Project): AndroidRunConfigurationEditor<AndroidTestRunConfiguration> {
+    val androidDebuggerContext = Mockito.mock(AndroidDebuggerContext::class.java)
+    val providers: List<DeployTargetProvider> = getTargetProviders(provider)
+    val configuration = Mockito.mock(AndroidTestRunConfiguration::class.java)
+    Mockito.`when`(configuration.androidDebuggerContext).thenReturn(androidDebuggerContext)
+    Mockito.`when`(configuration.applicableDeployTargetProviders).thenReturn(providers)
+    Mockito.`when`(configuration.profilerState).thenReturn(ProfilerState())
+
+    @Suppress("unchecked_cast")
+    val configurationSpecificEditor =
+      Mockito.mock(ConfigurationSpecificEditor::class.java) as ConfigurationSpecificEditor<AndroidTestRunConfiguration>
+
+    Mockito.`when`(configurationSpecificEditor.component).thenReturn(JLabel())
+
+    return AndroidRunConfigurationEditor(
+      project,
+      { false },
+      configuration,
+      true,
+      false,
+      { configurationSpecificEditor })
+  }
 }
\ No newline at end of file
diff --git a/android/src/META-INF/android-plugin-androidstudio.xml b/android/src/META-INF/android-plugin-androidstudio.xml
index 3a3d15c..b46e020 100755
--- a/android/src/META-INF/android-plugin-androidstudio.xml
+++ b/android/src/META-INF/android-plugin-androidstudio.xml
@@ -156,9 +156,6 @@
   <extensions defaultExtensionNs="com.intellij">
     <defaultProjectTypeProvider type="Android"/>
     <targetElementEvaluator language="XML" implementationClass="org.jetbrains.android.dom.AndroidXmlTargetElementEvaluatorEx" order="first"/>
-    <applicationService serviceInterface="org.jetbrains.plugins.gradle.service.GradleInstallationManager"
-                        serviceImplementation="com.android.tools.idea.gradle.project.AndroidStudioGradleInstallationManager"
-                        overrides="true"/>
 
     <!-- Unregister DefaultJdkConfigurator b/112481251 -->
     <applicationService serviceInterface="com.intellij.openapi.projectRoots.DefaultJdkConfigurator"
@@ -167,10 +164,6 @@
                         headlessImplementation="com.android.tools.idea.sdk.StudioJdkConfigurator"
     />
 
-    <projectService serviceInterface="org.jetbrains.plugins.gradle.settings.GradleSettings"
-                    serviceImplementation="com.android.tools.idea.gradle.project.AndroidStudioGradleSettings"
-                    overrides="true"/>
-
     <welcomeFrameProvider implementation="com.android.tools.idea.welcome.wizard.FirstRunWizardFrameProvider" order="FIRST"/>
 
     <localInspection groupPath="Java" language="JAVA" suppressId="deprecation" shortName="Deprecation" displayName="Deprecated API usage"
diff --git a/android/src/META-INF/android-plugin.xml b/android/src/META-INF/android-plugin.xml
index aa8277d..eb18c7b 100644
--- a/android/src/META-INF/android-plugin.xml
+++ b/android/src/META-INF/android-plugin.xml
@@ -354,6 +354,8 @@
     <runConfigurationProducer implementation="com.android.tools.idea.run.configuration.AndroidComplicationRunConfigurationProducer"/>
     <runLineMarkerContributor language="JAVA" implementationClass="com.android.tools.idea.run.configuration.AndroidWearRunMarkerContributor"/>
     <runLineMarkerContributor language="kotlin" implementationClass="com.android.tools.idea.run.configuration.AndroidWearRunMarkerContributor"/>
+    <runLineMarkerContributor language="JAVA" implementationClass="com.android.tools.idea.run.AndroidActivityRunLineMarkerContributor"/>
+    <runLineMarkerContributor language="kotlin" implementationClass="com.android.tools.idea.run.AndroidActivityRunLineMarkerContributor"/>
     <configurationType implementation="com.android.tools.idea.run.AndroidRunConfigurationType"/>
     <configurationType implementation="com.android.tools.idea.testartifacts.instrumented.AndroidTestRunConfigurationType"/>
     <configurationType implementation="com.android.tools.idea.run.configuration.AndroidWatchFaceConfigurationType"/>
diff --git a/android/src/com/android/tools/idea/actions/AndroidOpenFileAction.java b/android/src/com/android/tools/idea/actions/AndroidOpenFileAction.java
index 6241a72..03a84ee 100644
--- a/android/src/com/android/tools/idea/actions/AndroidOpenFileAction.java
+++ b/android/src/com/android/tools/idea/actions/AndroidOpenFileAction.java
@@ -31,6 +31,7 @@
 import com.intellij.ide.IdeBundle;
 import com.intellij.ide.actions.OpenProjectFileChooserDescriptor;
 import com.intellij.openapi.Disposable;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.fileChooser.FileChooserDescriptor;
 import com.intellij.openapi.fileChooser.PathChooserDialog;
@@ -66,6 +67,12 @@
   }
 
   @Override
+  @NotNull
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
+  @Override
   public void update(@NotNull AnActionEvent e) {
     if (NewWelcomeScreen.isNewWelcomeScreen(e)) {
       e.getPresentation().setIcon(AllIcons.Welcome.Open);
diff --git a/android/src/com/android/tools/idea/actions/ExportProjectZip.java b/android/src/com/android/tools/idea/actions/ExportProjectZip.java
index 8d1a474..093e4c8 100644
--- a/android/src/com/android/tools/idea/actions/ExportProjectZip.java
+++ b/android/src/com/android/tools/idea/actions/ExportProjectZip.java
@@ -19,6 +19,7 @@
 import com.android.tools.idea.gradle.project.GradleProjectInfo;
 import com.android.tools.idea.gradle.util.GradleUtil;
 import com.google.common.annotations.VisibleForTesting;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.application.ApplicationManager;
@@ -56,6 +57,12 @@
  */
 public class ExportProjectZip extends AnAction implements DumbAware {
 
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
   @Override
   public void update(@NotNull final AnActionEvent e) {
     Project project = e.getProject();
diff --git a/android/src/com/android/tools/idea/actions/MeetAndroidStudioHelpAction.java b/android/src/com/android/tools/idea/actions/MeetAndroidStudioHelpAction.java
index f60707b..62e218a 100644
--- a/android/src/com/android/tools/idea/actions/MeetAndroidStudioHelpAction.java
+++ b/android/src/com/android/tools/idea/actions/MeetAndroidStudioHelpAction.java
@@ -18,6 +18,7 @@
 import com.intellij.icons.AllIcons;
 import com.intellij.ide.BrowserUtil;
 import com.intellij.openapi.actionSystem.ActionPlaces;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.Presentation;
@@ -29,6 +30,12 @@
     super("Android Studio Help", "Help", AllIcons.Actions.Help);
   }
 
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
   @Override
   public void update(@NotNull AnActionEvent e) {
     if (e.getPlace().equals(ActionPlaces.MAIN_MENU)) {
diff --git a/android/src/com/android/tools/idea/actions/SendFeedbackAction.java b/android/src/com/android/tools/idea/actions/SendFeedbackAction.java
index ac2eab2..f6908bb 100644
--- a/android/src/com/android/tools/idea/actions/SendFeedbackAction.java
+++ b/android/src/com/android/tools/idea/actions/SendFeedbackAction.java
@@ -19,6 +19,7 @@
 import com.android.tools.idea.flags.StudioFlags;
 import com.intellij.ide.plugins.IdeaPluginDescriptor;
 import com.intellij.ide.plugins.PluginManagerCore;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.application.ex.ApplicationInfoEx;
@@ -143,6 +144,11 @@
     }
   }
 
+  @Override
+  public @NotNull ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
   private static String getNewFeedbackUrl() {
     String instructions = """
       ####################################################
diff --git a/android/src/com/android/tools/idea/apk/ImportApkAction.java b/android/src/com/android/tools/idea/apk/ImportApkAction.java
index 2fb4b3d..3571c9c 100644
--- a/android/src/com/android/tools/idea/apk/ImportApkAction.java
+++ b/android/src/com/android/tools/idea/apk/ImportApkAction.java
@@ -21,6 +21,7 @@
 import com.intellij.icons.AllIcons;
 import com.intellij.ide.RecentProjectsManager;
 import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.externalSystem.ExternalSystemManager;
 import com.intellij.openapi.fileChooser.FileChooserDialog;
@@ -97,6 +98,11 @@
     e.getPresentation().setEnabledAndVisible(enabled);
   }
 
+  @Override
+  public @NotNull ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
   @VisibleForTesting
   static class FileChooserDialogFactory {
     @NotNull
diff --git a/android/src/com/android/tools/idea/avdmanager/skincombobox/DefaultSkin.java b/android/src/com/android/tools/idea/avdmanager/skincombobox/DefaultSkin.java
index 1ebdee8..08b38d8 100644
--- a/android/src/com/android/tools/idea/avdmanager/skincombobox/DefaultSkin.java
+++ b/android/src/com/android/tools/idea/avdmanager/skincombobox/DefaultSkin.java
@@ -20,6 +20,18 @@
 
 @SuppressWarnings("unused")
 record DefaultSkin(@NotNull Path path) implements Skin {
+  /**
+   * Resolve collisions in favor of the parameter. If the user picks a platform skin or a system image skin with the file chooser before the
+   * asynchronous skin collection finishes it will be represented by a DefaultSkin. We resolve collisions in this way because the combo box
+   * renders PlatformSkins and SystemImageSkins with more information.
+   */
+  @NotNull
+  @Override
+  public Skin merge(@NotNull Skin skin) {
+    assert skin.path().equals(path) : skin;
+    return skin;
+  }
+
   @NotNull
   @Override
   public String toString() {
diff --git a/android/src/com/android/tools/idea/avdmanager/skincombobox/NoSkin.java b/android/src/com/android/tools/idea/avdmanager/skincombobox/NoSkin.java
index cc5899b..f7aa921 100644
--- a/android/src/com/android/tools/idea/avdmanager/skincombobox/NoSkin.java
+++ b/android/src/com/android/tools/idea/avdmanager/skincombobox/NoSkin.java
@@ -27,6 +27,12 @@
 
   @NotNull
   @Override
+  public Skin merge(@NotNull Skin skin) {
+    throw new UnsupportedOperationException();
+  }
+
+  @NotNull
+  @Override
   public Path path() {
     return Path.of(SkinUtils.NO_SKIN);
   }
diff --git a/android/src/com/android/tools/idea/avdmanager/skincombobox/PlatformSkin.java b/android/src/com/android/tools/idea/avdmanager/skincombobox/PlatformSkin.java
index 818f1f7..42b7139 100644
--- a/android/src/com/android/tools/idea/avdmanager/skincombobox/PlatformSkin.java
+++ b/android/src/com/android/tools/idea/avdmanager/skincombobox/PlatformSkin.java
@@ -22,6 +22,18 @@
 
 @SuppressWarnings("unused")
 record PlatformSkin(@NotNull Path path, @NotNull AndroidVersion version) implements Skin {
+  /**
+   * Resolve collisions in favor of platform skins. System images that don't have their own skins refer to the platform skins for their
+   * platform version. This resolution will drop those skins. It also handles the user manually picking a platform skin before the
+   * asynchronous collection is done.
+   */
+  @NotNull
+  @Override
+  public Skin merge(@NotNull Skin skin) {
+    assert skin.path().equals(path) : skin;
+    return this;
+  }
+
   @NotNull
   @Override
   public String toString() {
diff --git a/android/src/com/android/tools/idea/avdmanager/skincombobox/Skin.java b/android/src/com/android/tools/idea/avdmanager/skincombobox/Skin.java
index 2ea147d..539cf01 100644
--- a/android/src/com/android/tools/idea/avdmanager/skincombobox/Skin.java
+++ b/android/src/com/android/tools/idea/avdmanager/skincombobox/Skin.java
@@ -27,6 +27,9 @@
     .thenComparing(Object::toString, Collator.getInstance(ULocale.ROOT));
 
   @NotNull
+  Skin merge(@NotNull Skin skin);
+
+  @NotNull
   Path path();
 
   @Override
diff --git a/android/src/com/android/tools/idea/avdmanager/skincombobox/SkinComboBoxModel.java b/android/src/com/android/tools/idea/avdmanager/skincombobox/SkinComboBoxModel.java
new file mode 100644
index 0000000..7f29c25
--- /dev/null
+++ b/android/src/com/android/tools/idea/avdmanager/skincombobox/SkinComboBoxModel.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.avdmanager.skincombobox;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.util.concurrency.AppExecutorUtil;
+import com.intellij.util.concurrency.EdtExecutorService;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import javax.swing.AbstractListModel;
+import javax.swing.MutableComboBoxModel;
+import org.jetbrains.annotations.NotNull;
+
+public final class SkinComboBoxModel extends AbstractListModel<Skin> implements MutableComboBoxModel<Skin> {
+  private List<Skin> mySkins = new ArrayList<>(List.of(NoSkin.INSTANCE));
+
+  @NotNull
+  private Object mySelectedSkin = NoSkin.INSTANCE;
+
+  public void load() {
+    var future = Futures.submit(new Collector()::collect, AppExecutorUtil.getAppExecutorService());
+    Futures.addCallback(future, new Merge(), EdtExecutorService.getInstance());
+  }
+
+  private final class Merge implements FutureCallback<Collection<Skin>> {
+    @Override
+    public void onSuccess(@NotNull Collection<Skin> skins) {
+      var map = Stream.concat(mySkins.stream(), skins.stream()).collect(Collectors.toMap(Skin::path, skin -> skin, Skin::merge));
+
+      mySkins = map.values().stream()
+        .sorted()
+        .collect(Collectors.toList());
+
+      fireContentsChanged(SkinComboBoxModel.this, 0, mySkins.size() - 1);
+    }
+
+    @Override
+    public void onFailure(@NotNull Throwable throwable) {
+      Logger.getInstance(SkinComboBoxModel.class).warn(throwable);
+    }
+  }
+
+  @NotNull
+  public Skin getSkin(@NotNull Path path) {
+    return mySkins.stream()
+      .filter(skin -> skin.path().equals(path))
+      .findFirst()
+      .orElse(new DefaultSkin(path));
+  }
+
+  @Override
+  public int getSize() {
+    return mySkins.size();
+  }
+
+  @NotNull
+  @Override
+  public Skin getElementAt(int index) {
+    return mySkins.get(index);
+  }
+
+  @Override
+  public void addElement(@NotNull Skin skin) {
+    if (mySkins.contains(skin)) {
+      return;
+    }
+
+    mySkins.add(skin);
+    mySkins.sort(null);
+
+    var index = mySkins.indexOf(skin);
+    fireIntervalAdded(this, index, index);
+  }
+
+  @Override
+  public void removeElement(@NotNull Object skin) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void insertElementAt(@NotNull Skin skin, int index) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void removeElementAt(int index) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public void setSelectedItem(@NotNull Object selectedSkin) {
+    assert selectedSkin instanceof Skin skin && mySkins.contains(skin);
+
+    mySelectedSkin = selectedSkin;
+    fireContentsChanged(this, -1, -1);
+  }
+
+  @NotNull
+  @Override
+  public Object getSelectedItem() {
+    return mySelectedSkin;
+  }
+}
diff --git a/android/src/com/android/tools/idea/avdmanager/skincombobox/SystemImageSkin.java b/android/src/com/android/tools/idea/avdmanager/skincombobox/SystemImageSkin.java
index 738bab2..2427993 100644
--- a/android/src/com/android/tools/idea/avdmanager/skincombobox/SystemImageSkin.java
+++ b/android/src/com/android/tools/idea/avdmanager/skincombobox/SystemImageSkin.java
@@ -22,6 +22,18 @@
 
 @SuppressWarnings("unused")
 record SystemImageSkin(@NotNull Path path, @NotNull AndroidVersion version, @NotNull String abi) implements Skin {
+  /**
+   * If the parameter is a DefaultSkin, return this; otherwise return the parameter. System images that don't have their own skins refer to
+   * the platform skins for their platform version. This resolution will drop those skins. It also handles the user manually picking a
+   * system image skin before the asynchronous collection is done.
+   */
+  @NotNull
+  @Override
+  public Skin merge(@NotNull Skin skin) {
+    assert skin.path().equals(path) : skin;
+    return skin instanceof DefaultSkin ? this : skin;
+  }
+
   @NotNull
   @Override
   public String toString() {
diff --git a/android/src/com/android/tools/idea/databinding/index/BindingXmlIndex.kt b/android/src/com/android/tools/idea/databinding/index/BindingXmlIndex.kt
index b8b9225..eb714fb 100644
--- a/android/src/com/android/tools/idea/databinding/index/BindingXmlIndex.kt
+++ b/android/src/com/android/tools/idea/databinding/index/BindingXmlIndex.kt
@@ -59,12 +59,13 @@
     @JvmField
     val NAME = ID.create<Int, BindingXmlData>("BindingXmlIndex")
 
-    fun acceptsFile(file: VirtualFile): Boolean =
-      "xml" == file.extension &&
-      ResourceFolderType.getFolderType(file.parent?.name.orEmpty()) == ResourceFolderType.LAYOUT
-
     private fun getDataForFile(file: VirtualFile, project: Project): BindingXmlData? {
-      return FileBasedIndex.getInstance().getSingleEntryIndexData(NAME, file, project)
+      val data = FileBasedIndex.getInstance().getSingleEntryIndexData(NAME, file, project) ?: return null
+
+      val parentFolderName = file.parent?.name ?: return null
+      if (ResourceFolderType.getFolderType(parentFolderName) != ResourceFolderType.LAYOUT) return null
+
+      return data
     }
 
     fun getDataForFile(project: Project, file: VirtualFile) = getDataForFile(file, project)
@@ -161,7 +162,20 @@
 
   override fun getIndexer(): SingleEntryIndexer<BindingXmlData> {
     return object : SingleEntryIndexer<BindingXmlData>(false) {
-      override fun computeValue(inputData: FileContent): BindingXmlData {
+
+      // Quick heuristic to avoid indexing non-layout files. We can't determine for sure at indexing time whether this is a layout file,
+      // as that relies on the parent directory which can't be accessed during indexing (see [FileBasedIndexExtension] docs). But layout
+      // files must contain the Android namespace declaration (see https://developer.android.com/guide/topics/resources/layout-resource),
+      // and so this indexer can skip processing any files that don't contain the declaration.
+      // This is checked with a text search rather than in the XML parsing below, since NanoXmlBuilder doesn't get directly called when
+      // the parser sees the namespace.
+      private val xmlNamespaceRegex = Regex("""xmlns:android\s*=\s*"http://schemas.android.com/apk/res/android"""")
+
+      override fun computeValue(inputData: FileContent): BindingXmlData? {
+        val inputAsText = inputData.contentAsText
+
+        if (!inputAsText.contains(xmlNamespaceRegex)) return null
+
         var bindingLayoutType = PLAIN_LAYOUT
         var customBindingName: String? = null
         var viewBindingIgnore = false
@@ -183,7 +197,7 @@
           var viewTypeOverride: String? = null
         }
 
-        NanoXmlUtil.parse(EscapingXmlReader(inputData.contentAsText), object : NanoXmlBuilder {
+        NanoXmlUtil.parse(EscapingXmlReader(inputAsText), object : NanoXmlBuilder {
           val tags = mutableListOf<TagData>()
 
           override fun startElement(name: String, nsPrefix: String?, nsURI: String?, systemID: String, lineNr: Int) {
@@ -295,13 +309,9 @@
     }
   }
 
-  override fun getInputFilter(): FileBasedIndex.InputFilter {
-    return object : DefaultFileTypeSpecificInputFilter(XmlFileType.INSTANCE) {
-      override fun acceptInput(file: VirtualFile): Boolean = acceptsFile(file)
-    }
-  }
+  override fun getInputFilter() = DefaultFileTypeSpecificInputFilter(XmlFileType.INSTANCE)
 
-  override fun getVersion() = 11
+  override fun getVersion() = 12
 }
 
 private const val COMMENT_START = "<!--"
diff --git a/android/src/com/android/tools/idea/diagnostics/heap/HeapSnapshotTraverseService.java b/android/src/com/android/tools/idea/diagnostics/heap/HeapSnapshotTraverseService.java
index 102f951..95849a4 100644
--- a/android/src/com/android/tools/idea/diagnostics/heap/HeapSnapshotTraverseService.java
+++ b/android/src/com/android/tools/idea/diagnostics/heap/HeapSnapshotTraverseService.java
@@ -183,7 +183,7 @@
         }, statistics,
         new MemoryReportCollector.HeapSnapshotPresentationConfig(
           PLAIN_VALUES,
-          /*shouldLogSharedClusters=*/false,
+          /*shouldLogSharedClusters=*/true,
           /*shouldLogRetainedSizes=*/false));
 
       statistics = null;
diff --git a/android/src/com/android/tools/idea/diagnostics/heap/RootPathTree.java b/android/src/com/android/tools/idea/diagnostics/heap/RootPathTree.java
index f5d65d4..ca72b3d 100644
--- a/android/src/com/android/tools/idea/diagnostics/heap/RootPathTree.java
+++ b/android/src/com/android/tools/idea/diagnostics/heap/RootPathTree.java
@@ -51,7 +51,7 @@
   private int numberOfRootPathTreeNodes = 0;
 
   private final ExtendedReportStatistics extendedReportStatistics;
-  private static final int ROOT_PATH_TREE_MAX_OBJECT_DEPTH = 400;
+  private static final int ROOT_PATH_TREE_MAX_OBJECT_DEPTH = 200;
   private static final int NODE_SUBTREE_SIZE_PERCENTAGE_REQUIREMENT = 2;
   private static final int NODE_SUBTREE_OBJECTS_SIZE_REQUIREMENT_BYTES = 750_000; //750kb
 
diff --git a/android/src/com/android/tools/idea/diagnostics/profiler/DumpJfrRecording.java b/android/src/com/android/tools/idea/diagnostics/profiler/DumpJfrRecording.java
index c342aff..502a698 100644
--- a/android/src/com/android/tools/idea/diagnostics/profiler/DumpJfrRecording.java
+++ b/android/src/com/android/tools/idea/diagnostics/profiler/DumpJfrRecording.java
@@ -15,6 +15,7 @@
  */
 package com.android.tools.idea.diagnostics.profiler;
 
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.project.DumbAwareAction;
@@ -25,6 +26,12 @@
     super("Dump JFR Recording");
   }
 
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.EDT;
+  }
+
   @Override
   public void update(@NotNull AnActionEvent e) {
     e.getPresentation().setEnabled(ApplicationManager.getApplication().getService(Jfr.class).isProfilerActive());
diff --git a/android/src/com/android/tools/idea/diagnostics/profiler/StartJfr.java b/android/src/com/android/tools/idea/diagnostics/profiler/StartJfr.java
index 7874d66..02e9789 100644
--- a/android/src/com/android/tools/idea/diagnostics/profiler/StartJfr.java
+++ b/android/src/com/android/tools/idea/diagnostics/profiler/StartJfr.java
@@ -15,6 +15,7 @@
  */
 package com.android.tools.idea.diagnostics.profiler;
 
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.project.DumbAwareAction;
@@ -25,6 +26,12 @@
     super("Start JFR");
   }
 
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.EDT;
+  }
+
   @Override
   public void update(@NotNull AnActionEvent e) {
     e.getPresentation().setEnabled(JfrUtilsKt.isJfrAvailable() && !ApplicationManager.getApplication().getService(Jfr.class).isProfilerActive());
diff --git a/android/src/com/android/tools/idea/diagnostics/profiler/StopJfr.java b/android/src/com/android/tools/idea/diagnostics/profiler/StopJfr.java
index 0c9c547..9c57512 100644
--- a/android/src/com/android/tools/idea/diagnostics/profiler/StopJfr.java
+++ b/android/src/com/android/tools/idea/diagnostics/profiler/StopJfr.java
@@ -15,6 +15,7 @@
  */
 package com.android.tools.idea.diagnostics.profiler;
 
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.project.DumbAwareAction;
@@ -25,6 +26,12 @@
     super("Stop JFR");
   }
 
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.EDT;
+  }
+
   @Override
   public void update(@NotNull AnActionEvent e) {
     e.getPresentation().setEnabled(ApplicationManager.getApplication().getService(Jfr.class).isProfilerActive());
diff --git a/android/src/com/android/tools/idea/editors/GradleImplicitPropertyUsageProvider.java b/android/src/com/android/tools/idea/editors/GradleImplicitPropertyUsageProvider.java
index 6c19220..3582c64 100644
--- a/android/src/com/android/tools/idea/editors/GradleImplicitPropertyUsageProvider.java
+++ b/android/src/com/android/tools/idea/editors/GradleImplicitPropertyUsageProvider.java
@@ -36,7 +36,8 @@
       return true;
     }
 
-    if (Comparing.equal(file.getName(), "gradle.properties", caseSensitive)) {
+    if (Comparing.equal(file.getName(), "gradle.properties", caseSensitive) ||
+        Comparing.equal(file.getName(), "resources.properties", caseSensitive)) {
       // Ignore all properties in the gradle.properties; we don't have a complete set of what's used
       // and we don't want to suggest to the user that these are unused
       return true;
diff --git a/android/src/com/android/tools/idea/editors/build/ProjectBuildStatusManager.kt b/android/src/com/android/tools/idea/editors/build/ProjectBuildStatusManager.kt
index 2c8ecd7..f556477 100644
--- a/android/src/com/android/tools/idea/editors/build/ProjectBuildStatusManager.kt
+++ b/android/src/com/android/tools/idea/editors/build/ProjectBuildStatusManager.kt
@@ -15,7 +15,6 @@
  */
 package com.android.tools.idea.editors.build
 
-import com.android.annotations.concurrency.UiThread
 import com.android.tools.idea.concurrency.AndroidCoroutineScope
 import com.android.tools.idea.concurrency.AndroidDispatchers.workerThread
 import com.android.tools.idea.editors.fast.CompilationResult
@@ -37,18 +36,15 @@
 import com.intellij.psi.PsiFile
 import com.intellij.psi.SmartPointerManager
 import com.intellij.psi.SmartPsiElementPointer
-import java.util.concurrent.atomic.AtomicInteger
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.collectLatest
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.merge
 import kotlinx.coroutines.launch
 import org.jetbrains.annotations.TestOnly
-import org.jetbrains.kotlin.idea.gradleTooling.get
 import org.jetbrains.kotlin.idea.util.projectStructure.module
+import java.util.concurrent.atomic.AtomicInteger
 
 /**
  * This represents the build status of the project without taking into account any file
diff --git a/android/src/com/android/tools/idea/gradle/plugin/AgpVersions.kt b/android/src/com/android/tools/idea/gradle/plugin/AgpVersions.kt
index 0eedccf..fedd9a3 100644
--- a/android/src/com/android/tools/idea/gradle/plugin/AgpVersions.kt
+++ b/android/src/com/android/tools/idea/gradle/plugin/AgpVersions.kt
@@ -111,10 +111,7 @@
   }
 
   @VisibleForTesting
-  fun getNewProjectWizardVersions(
-    latestKnown: AgpVersion = this.latestKnown,
-    availableVersions: Set<AgpVersion> = getAvailableVersions()
-  ): Set<AgpVersion> {
+  fun getNewProjectWizardVersions(latestKnown: AgpVersion, availableVersions: Set<AgpVersion>): Set<AgpVersion> {
     val include = setOf(AndroidGradlePluginCompatibility.COMPATIBLE, AndroidGradlePluginCompatibility.DEPRECATED)
     var minOfCurrentSeries = AgpVersion(Int.MAX_VALUE, Int.MAX_VALUE, Int.MAX_VALUE)
     val recommended = mutableListOf<AgpVersion>()
@@ -122,7 +119,13 @@
       // Go from latest first, and include latest from each series that is compatible
       if (version < minOfCurrentSeries &&
           include.contains(computeAndroidGradlePluginCompatibility(version, latestKnown)) ) {
-        minOfCurrentSeries = AgpVersion.parse(version.toString().substringBefore("-") + "-alpha01")
+        minOfCurrentSeries = if (version.isSnapshot) {
+          // Treat -dev as special case, so also include the latest release version from the current series, if present.
+          version
+        } else {
+          // Exclude all older versions from the current series
+          AgpVersion.parse(version.toString().substringBefore("-") + "-alpha01")
+        }
         recommended.add(version)
       }
     }
diff --git a/android/src/com/android/tools/idea/imports/AndroidMavenImportIntentionAction.kt b/android/src/com/android/tools/idea/imports/AndroidMavenImportIntentionAction.kt
index 46b1741..9213585 100644
--- a/android/src/com/android/tools/idea/imports/AndroidMavenImportIntentionAction.kt
+++ b/android/src/com/android/tools/idea/imports/AndroidMavenImportIntentionAction.kt
@@ -60,7 +60,8 @@
 import org.jetbrains.kotlin.psi.KtUserType
 
 /**
- * An action which recognizes classes from key Maven artifacts and offers to add a dependency on them.
+ * An action which recognizes classes from key Maven artifacts and offers to add a dependency on
+ * them.
  */
 class AndroidMavenImportIntentionAction : PsiElementBaseIntentionAction() {
   private var intentionActionText: String = familyName
@@ -72,21 +73,18 @@
     val version: String?
   ) : Comparable<AutoImportVariant> {
     override fun compareTo(other: AutoImportVariant): Int {
-      artifactToAdd.compareTo(other.artifactToAdd).let {
-        if (it != 0) return it
-      }
+      artifactToAdd.compareTo(other.artifactToAdd).let { if (it != 0) return it }
 
       return classToImport.compareTo(other.classToImport)
     }
   }
 
-  private class Resolvable private constructor(
-    val libraries: Collection<MavenClassRegistryBase.LibraryImportData>
-  ) {
+  private class Resolvable
+  private constructor(val libraries: Collection<MavenClassRegistryBase.LibraryImportData>) {
     companion object {
-      fun createNewOrNull(libraries: Collection<MavenClassRegistryBase.LibraryImportData>): Resolvable? {
-        return if (libraries.isEmpty()) null else Resolvable(libraries)
-      }
+      fun createNewOrNull(
+        libraries: Collection<MavenClassRegistryBase.LibraryImportData>
+      ): Resolvable? = libraries.takeUnless { it.isEmpty() }?.let(::Resolvable)
     }
   }
 
@@ -94,28 +92,38 @@
     perform(project, editor, element, true)
   }
 
-  /**
-   * Performs a fix. Or let users to choose from the popup if there's multiple options.
-   */
+  /** Performs a fix. Or let users choose from the popup if there are multiple options. */
   fun perform(project: Project, editor: Editor, element: PsiElement, sync: Boolean) {
-    val resolvable = findResolvable(element, editor.caretModel.offset) { text ->
-      Resolvable.createNewOrNull(findLibraryData(project, text, element.containingFile?.fileType))
-    } ?: return
-
-    val suggestions = resolvable.libraries
-      .asSequence()
-      .map {
-        val artifact = resolveArtifact(project, element.language, it.artifact)
-        val importSymbol = resolveImport(project, it.importedItemFqName)
-        AutoImportVariant(artifact, importSymbol, it.version)
+    val resolvable =
+      findResolvable(element, editor.caretModel.offset) { text, receiverType ->
+        Resolvable.createNewOrNull(
+          findLibraryData(project, text, receiverType, element.containingFile?.fileType)
+        )
       }
-      .toSortedSet()
+        ?: return
+
+    val suggestions =
+      resolvable.libraries
+        .asSequence()
+        .map {
+          val artifact = resolveArtifact(project, element.language, it.artifact)
+          val importSymbol = resolveImport(project, it.importedItemFqName)
+          AutoImportVariant(artifact, importSymbol, it.version)
+        }
+        .toSortedSet()
 
     if (suggestions.isEmpty()) return
 
     if (suggestions.size == 1 || ApplicationManager.getApplication().isUnitTestMode) {
       val suggestion = suggestions.first()
-      perform(project, element, suggestion.artifactToAdd, suggestion.version, suggestion.classToImport, sync)
+      perform(
+        project,
+        element,
+        suggestion.artifactToAdd,
+        suggestion.version,
+        suggestion.classToImport,
+        sync
+      )
       return
     }
 
@@ -129,19 +137,31 @@
     suggestions: List<AutoImportVariant>,
     sync: Boolean
   ) {
-    val step = object : BaseListPopupStep<AutoImportVariant>(
-      AndroidBundle.message("android.suggested.imports.title"),
-      suggestions
-    ) {
-      override fun getTextFor(value: AutoImportVariant): String {
-        return flagPreview(value.artifactToAdd, value.version)
-      }
+    val step =
+      object :
+        BaseListPopupStep<AutoImportVariant>(
+          AndroidBundle.message("android.suggested.imports.title"),
+          suggestions
+        ) {
+        override fun getTextFor(value: AutoImportVariant): String {
+          return flagPreview(value.artifactToAdd, value.version)
+        }
 
-      override fun onChosen(selectedValue: AutoImportVariant, finalChoice: Boolean): PopupStep<*>? {
-        perform(project, element, selectedValue.artifactToAdd, selectedValue.version, selectedValue.classToImport, sync)
-        return FINAL_CHOICE
+        override fun onChosen(
+          selectedValue: AutoImportVariant,
+          finalChoice: Boolean
+        ): PopupStep<*>? {
+          perform(
+            project,
+            element,
+            selectedValue.artifactToAdd,
+            selectedValue.version,
+            selectedValue.classToImport,
+            sync
+          )
+          return FINAL_CHOICE
+        }
       }
-    }
 
     ListPopupImpl(project, step).showInBestPositionFor(editor)
   }
@@ -159,9 +179,9 @@
     var syncFuture: ListenableFuture<ProjectSystemSyncManager.SyncResult>? = null
     WriteCommandAction.runWriteCommandAction(project) {
       if (sync) {
-        syncFuture = performWithLockAndSync(project, module, element, artifact, artifactVersion, importSymbol)
-      }
-      else {
+        syncFuture =
+          performWithLockAndSync(project, module, element, artifact, artifactVersion, importSymbol)
+      } else {
         performWithLock(project, module, element, artifact, artifactVersion, importSymbol)
       }
     }
@@ -179,26 +199,35 @@
     importSymbol: String?
   ): ListenableFuture<ProjectSystemSyncManager.SyncResult> {
     // Register sync action for undo.
-    UndoManager.getInstance(project).undoableActionPerformed(object : GlobalUndoableAction() {
-      override fun undo() {
-        project.requestSync()
-      }
+    UndoManager.getInstance(project)
+      .undoableActionPerformed(
+        object : GlobalUndoableAction() {
+          override fun undo() {
+            project.requestSync()
+          }
 
-      override fun redo() {}
-    })
+          override fun redo() {}
+        }
+      )
 
     performWithLock(project, module, element, artifact, artifactVersion, importSymbol)
 
     // Register sync action for redo.
-    UndoManager.getInstance(project).undoableActionPerformed(object : GlobalUndoableAction() {
-      override fun undo() {}
+    UndoManager.getInstance(project)
+      .undoableActionPerformed(
+        object : GlobalUndoableAction() {
+          override fun undo() {}
 
-      override fun redo() {
-        project.requestSync()
-      }
-    })
+          override fun redo() {
+            project.requestSync()
+          }
+        }
+      )
 
-    return project.getProjectSystem().getSyncManager().syncProject(ProjectSystemSyncManager.SyncReason.PROJECT_MODIFIED)
+    return project
+      .getProjectSystem()
+      .getSyncManager()
+      .syncProject(ProjectSystemSyncManager.SyncReason.PROJECT_MODIFIED)
   }
 
   /**
@@ -214,7 +243,8 @@
     artifactVersion: String?,
     importSymbol: String?
   ) {
-    // Import the class as well (if possible); otherwise it might be confusing that you have to invoke two
+    // Import the class as well (if possible); otherwise it might be confusing that you have to
+    // invoke two
     // separate intention actions in order to get your symbol resolved
     if (importSymbol != null) {
       addImportStatement(project, element, importSymbol)
@@ -222,26 +252,37 @@
 
     addDependency(module, artifact, artifactVersion)
     // Also add on an extra dependency for special cases.
-    getMavenClassRegistry()
-      .findExtraArtifacts(artifact)
-      .forEach { addDependency(module, it.key, artifactVersion, it.value) }
+    getMavenClassRegistry().findExtraArtifacts(artifact).forEach {
+      addDependency(module, it.key, artifactVersion, it.value)
+    }
 
     // Also add dependent annotation processor?
-    if (module.getModuleSystem().canRegisterDependency(DependencyType.ANNOTATION_PROCESSOR).isSupported()) {
+    if (
+      module
+        .getModuleSystem()
+        .canRegisterDependency(DependencyType.ANNOTATION_PROCESSOR)
+        .isSupported()
+    ) {
       getMavenClassRegistry().findAnnotationProcessor(artifact)?.let { it ->
-        val annotationProcessor = if (project.isAndroidx()) {
-          AndroidxNameUtils.getCoordinateMapping(it)
-        }
-        else {
-          it
-        }
+        val annotationProcessor =
+          if (project.isAndroidx()) {
+            AndroidxNameUtils.getCoordinateMapping(it)
+          } else {
+            it
+          }
 
-        addDependency(module, annotationProcessor, artifactVersion, DependencyType.ANNOTATION_PROCESSOR)
+        addDependency(
+          module,
+          annotationProcessor,
+          artifactVersion,
+          DependencyType.ANNOTATION_PROCESSOR
+        )
       }
     }
   }
 
-  override fun getFamilyName(): String = AndroidBundle.message("android.suggested.import.action.family.name")
+  override fun getFamilyName(): String =
+    AndroidBundle.message("android.suggested.import.action.family.name")
 
   override fun getText(): String = intentionActionText
 
@@ -249,23 +290,31 @@
     val module = ModuleUtil.findModuleForPsiElement(element) ?: return false
     if (!module.getModuleSystem().canRegisterDependency().isSupported()) return false
 
-    val resolvable = findResolvable(element, editor?.caretModel?.offset ?: -1) { text ->
-      Resolvable.createNewOrNull(findLibraryData(project, text, element.containingFile?.fileType))
-    } ?: return false
+    val resolvable =
+      findResolvable(element, editor?.caretModel?.offset ?: -1) { text, receiverType ->
+        Resolvable.createNewOrNull(
+          findLibraryData(project, text, receiverType, element.containingFile?.fileType)
+        )
+      }
+        ?: return false
 
     val foundLibraries = resolvable.libraries
     // If we are already depending on any of them, we just abort providing any suggestions as well.
-    if (foundLibraries.isEmpty() || foundLibraries.any { dependsOn(module, it.artifact) }) return false
+    if (foundLibraries.isEmpty() || foundLibraries.any { dependsOn(module, it.artifact) })
+      return false
 
     // Update the text.
-    intentionActionText = if (foundLibraries.size == 1) {
-      val library = foundLibraries.single()
-      val artifact = resolveArtifact(project, element.language, library.artifact)
-      AndroidBundle.message("android.suggested.import.action.name.prefix", flagPreview(artifact, library.version))
-    }
-    else {
-      familyName
-    }
+    intentionActionText =
+      if (foundLibraries.size == 1) {
+        val library = foundLibraries.single()
+        val artifact = resolveArtifact(project, element.language, library.artifact)
+        AndroidBundle.message(
+          "android.suggested.import.action.name.prefix",
+          flagPreview(artifact, library.version)
+        )
+      } else {
+        familyName
+      }
 
     return true
   }
@@ -273,25 +322,33 @@
   private fun Project.requestSync() {
     val syncManager = getProjectSystem().getSyncManager()
     if (syncManager.isSyncInProgress()) {
-      listenUntilNextSync(this, object : ProjectSystemSyncManager.SyncResultListener {
-        override fun syncEnded(result: ProjectSystemSyncManager.SyncResult) {
-          syncManager.syncProject(ProjectSystemSyncManager.SyncReason.PROJECT_MODIFIED)
+      listenUntilNextSync(
+        this,
+        object : ProjectSystemSyncManager.SyncResultListener {
+          override fun syncEnded(result: ProjectSystemSyncManager.SyncResult) {
+            syncManager.syncProject(ProjectSystemSyncManager.SyncReason.PROJECT_MODIFIED)
+          }
         }
-      })
-    }
-    else {
+      )
+    } else {
       syncManager.syncProject(ProjectSystemSyncManager.SyncReason.PROJECT_MODIFIED)
     }
   }
 
-  private fun addDependency(module: Module, artifact: String, version: String?, type: DependencyType = DependencyType.IMPLEMENTATION) {
+  private fun addDependency(
+    module: Module,
+    artifact: String,
+    version: String?,
+    type: DependencyType = DependencyType.IMPLEMENTATION
+  ) {
     val coordinate = getCoordinate(artifact, version) ?: return
     val moduleSystem = module.getModuleSystem()
     moduleSystem.registerDependency(coordinate, type)
   }
 
   private fun dependsOn(module: Module, artifact: String): Boolean {
-    // To check if we depend on an artifact, we don't particularly care which version is there, just whether the library is included at all.
+    // To check if we depend on an artifact, we don't particularly care which version is there, just
+    // whether the library is included at all.
     val coordinate = getCoordinate(artifact) ?: return false
     val moduleSystem = module.getModuleSystem()
     return moduleSystem.getRegisteredDependency(coordinate) != null
@@ -301,10 +358,10 @@
    * Generates a coordinate representing the specified artifact.
    *
    * @param artifact requested artifact
-   *
-   * @param version desired version, if any. This is expected to be in the form "2.5.1". The version comes from [MavenClassRegistry], and
-   * represents the minimum version of a dependency that should be added. See
-   * [b/275602080](https://issuetracker.google.com/issues/275602080#comment6) for more details.
+   * @param version desired version, if any. This is expected to be in the form "2.5.1". The version
+   *   comes from [MavenClassRegistry], and represents the minimum version of a dependency that
+   *   should be added. See [b/275602080](https://issuetracker.google.com/issues/275602080#comment6)
+   *   for more details.
    */
   private fun getCoordinate(artifact: String, version: String? = null) =
     if (version.isNullOrEmpty()) GradleCoordinate.parseCoordinateString("$artifact:+")
@@ -313,42 +370,47 @@
   private fun findResolvable(
     element: PsiElement,
     caret: Int,
-    resolve: (String) -> Resolvable?
+    resolve: (String, String?) -> Resolvable?
   ): Resolvable? {
+    // This is actually the common case.
+    fun resolveWithoutReceiver(s: String) = resolve(s, null)
     if (element is PsiIdentifier || caret == 0) {
-      // In Java code, if you're pointing somewhere in the middle of a fully qualified name (such as an import
-      // statement to a library that isn't available), the unresolved symbol won't be the final class, it will be the
-      // first unavailable package segment. In these cases, search down the chain for the actual imported class symbol
-      // and scan on that one instead.
-      // E.g. for "androidx.camera.core.ImageCapture.OnImageSavedCallback" and "camera" is an unresolvable symbol, we
-      // search first for "androidx.camera", and then "androidx.camera.core", and we stop at the first resolvable, which
-      // is "androidx.camera.core.ImageCapture".
+      // In Java code, if you're pointing somewhere in the middle of a fully qualified name (such as
+      // an import statement to a library that isn't available), the unresolved symbol won't be the
+      // final class, it will be the first unavailable package segment. In these cases, search down
+      // the chain for the actual imported class symbol and scan on that one instead. E.g. for
+      // "androidx.camera.core.ImageCapture.OnImageSavedCallback" and "camera" is an unresolvable
+      // symbol, we search first for "androidx.camera", and then "androidx.camera.core", and we stop
+      // at the first resolvable, which is "androidx.camera.core.ImageCapture".
       if (element.parent is PsiJavaCodeReferenceElement) {
         var curr: PsiJavaCodeReferenceElement? = element.parent as PsiJavaCodeReferenceElement
         while (curr != null) {
-          val found = resolve(curr.text)
-          if (found != null) return found
+          resolveWithoutReceiver(curr.text)?.let {
+            return it
+          }
 
           curr = curr.parent as? PsiJavaCodeReferenceElement
         }
       }
 
-      return resolve(element.text)
-    }
-    else if (element is LeafPsiElement && element.elementType == KtTokens.IDENTIFIER) {
-      // In Kotlin code, if you're pointing somewhere in the middle of a fully qualified name (such as an import
-      // statement to a library that isn't available), the unresolved symbol won't be the final class, it will be the
-      // first unavailable package segment. In these cases, search down the chain for the actual imported class symbol
-      // and scan on that one instead.
+      return resolveWithoutReceiver(element.text)
+    } else if (element is LeafPsiElement && element.elementType == KtTokens.IDENTIFIER) {
+      // In Kotlin code, if you're pointing somewhere in the middle of a fully qualified name (such
+      // as an import statement to a library that isn't available), the unresolved symbol won't be
+      // the final class, it will be the first unavailable package segment. In these cases, search
+      // down the chain for the actual imported class symbol and scan on that one instead.
       if (element.parent is KtNameReferenceExpression) {
         when (val current = element.parent.parent) {
           is KtDotQualifiedExpression -> {
             var curr: KtDotQualifiedExpression? = current
             while (curr != null) {
-              val found = curr.formText()?.let {
-                resolve(it)
-              }
-              if (found != null) return found
+              // TODO(b/300296134): Use receiver type if available.
+              curr
+                .formText()
+                ?.let { resolveWithoutReceiver(it) }
+                ?.let {
+                  return it
+                }
 
               curr = curr.parent as? KtDotQualifiedExpression
             }
@@ -356,17 +418,18 @@
           is KtUserType -> {
             var curr: KtUserType? = current
             while (curr != null) {
-              val found = resolve(curr.text)
-              if (found != null) return found
+              resolveWithoutReceiver(curr.text)?.let {
+                return it
+              }
 
               curr = curr.parent as? KtUserType
             }
           }
-          else -> return resolve(element.text)
+          else -> return resolveWithoutReceiver(element.text)
         }
       }
 
-      return resolve(element.text)
+      return resolveWithoutReceiver(element.text)
     }
 
     // When the caret is at the end of the word (which it frequently is in the unresolved symbol
@@ -374,7 +437,7 @@
     // on the right of the caret, which is the next element, not the symbol element.
     if (caret == element.textOffset || element is PsiWhiteSpace) {
       if (element.prevSibling != null) {
-        return resolve(element.prevSibling.text)
+        return resolveWithoutReceiver(element.prevSibling.text)
       }
       val targetOffset = caret - 1
       var curr = element.parent
@@ -383,11 +446,11 @@
       }
       if (curr != null) {
         val text = curr.findElementAt(targetOffset - curr.textOffset)?.text ?: element.text
-        return resolve(text)
+        return resolveWithoutReceiver(text)
       }
     }
 
-    return resolve(element.text)
+    return resolveWithoutReceiver(element.text)
   }
 
   private fun KtDotQualifiedExpression.formText(): String? {
@@ -403,9 +466,14 @@
     return null
   }
 
-  private fun findLibraryData(project: Project, text: String, completionFileType: FileType?)
-      : Collection<MavenClassRegistryBase.LibraryImportData> {
-    return getMavenClassRegistry().findLibraryData(text, project.isAndroidx(), completionFileType)
+  private fun findLibraryData(
+    project: Project,
+    text: String,
+    receiverType: String?,
+    completionFileType: FileType?
+  ): Collection<MavenClassRegistryBase.LibraryImportData> {
+    return getMavenClassRegistry()
+      .findLibraryData(text, receiverType, project.isAndroidx(), completionFileType)
   }
 
   private fun resolveArtifact(project: Project, language: Language, artifact: String): String {
@@ -420,8 +488,7 @@
       }
 
       androidx
-    }
-    else {
+    } else {
       artifact
     }
   }
@@ -429,8 +496,7 @@
   private fun resolveImport(project: Project, fqn: String): String {
     return if (project.isAndroidx()) {
       AndroidxNameUtils.getNewName(fqn)
-    }
-    else {
+    } else {
       fqn
     }
   }
@@ -456,7 +522,7 @@
         // Can't access org.jetbrains.kotlin.idea.util.ImportInsertHelper
         ImportInsertHelperImpl.addImport(project, file as KtFile, FqName(import))
       }
-      // Nothing to do in XML etc
+    // Nothing to do in XML etc
     }
   }
 
diff --git a/android/src/com/android/tools/idea/imports/MavenClassRegistry.kt b/android/src/com/android/tools/idea/imports/MavenClassRegistry.kt
index c4134bc..0494123 100644
--- a/android/src/com/android/tools/idea/imports/MavenClassRegistry.kt
+++ b/android/src/com/android/tools/idea/imports/MavenClassRegistry.kt
@@ -19,31 +19,40 @@
 import com.google.gson.stream.JsonReader
 import com.intellij.openapi.diagnostic.logger
 import com.intellij.openapi.fileTypes.FileType
-import org.jetbrains.kotlin.idea.KotlinFileType
-import org.jetbrains.kotlin.name.FqName
 import java.io.IOException
 import java.io.InputStream
 import java.io.InputStreamReader
+import org.jetbrains.kotlin.idea.KotlinFileType
+import org.jetbrains.kotlin.name.FqName
 
 /**
  * Registry contains [lookup] extracted by reading indices from [GMavenIndexRepository].
  *
- * Here, it covers all the latest stable versions of libraries which are explicitly marked as `Yes` to include in
- * go/studio-auto-import-packages.
+ * Here, it covers all the latest stable versions of libraries which are explicitly marked as `Yes`
+ * to include in go/studio-auto-import-packages.
  */
-class MavenClassRegistry(private val indexRepository: GMavenIndexRepository) : MavenClassRegistryBase() {
+class MavenClassRegistry(private val indexRepository: GMavenIndexRepository) :
+  MavenClassRegistryBase() {
   val lookup: LookupData = generateLookup()
 
   /**
-   * Given an unresolved name, returns the likely collection of [LibraryImportData] objects for the maven.google.com artifacts containing a
-   * class or function matching the name.
+   * Given an unresolved name, returns the likely collection of [LibraryImportData] objects for the
+   * maven.google.com artifacts containing a class or function matching the name.
    *
    * This implementation only returns results of index data from [GMavenIndexRepository].
    *
-   * @param name simple or fully-qualified name typed by the user. May correspond to a class name (any files) or a top-level Kotlin function
-   * name (Kotlin files only).
+   * @param name simple or fully-qualified name typed by the user. May correspond to a class name
+   *   (any files) or a top-level Kotlin function name (Kotlin files only).
+   * @param receiverType the fully-qualified name of the receiver type, if any,
+   *   [MavenClassRegistryBase.ALL_RECEIVER_TYPES] if results for any receiver type (including no
+   *   receiver) should be returned, or `null` otherwise.
    */
-  override fun findLibraryData(name: String, useAndroidX: Boolean, completionFileType: FileType?): Collection<LibraryImportData> {
+  override fun findLibraryData(
+    name: String,
+    receiverType: String?,
+    useAndroidX: Boolean,
+    completionFileType: FileType?
+  ): Collection<LibraryImportData> {
     // We only support projects that set android.useAndroidX=true.
     if (!useAndroidX) return emptyList()
 
@@ -51,10 +60,17 @@
     val packageName = name.substringBeforeLast('.', missingDelimiterValue = "")
 
     val foundArtifacts = buildList {
-      lookup.classNameMap[shortName]?.let { addAll(it) }
-
+      if (receiverType == null || receiverType == ALL_RECEIVER_TYPES)
+        lookup.classNameMap[shortName]?.let { addAll(it) }
       // Only suggest top-level Kotlin functions when completing in a Kotlin file.
-      if (completionFileType == KotlinFileType.INSTANCE) lookup.topLevelFunctionsMap[shortName]?.let { addAll(it) }
+      if (completionFileType == KotlinFileType.INSTANCE) {
+        if (receiverType == ALL_RECEIVER_TYPES) {
+          lookup.topLevelFunctionsMapAllReceivers[shortName]?.let { addAll(it) }
+        } else {
+          val functionSpecifier = FunctionSpecifier(shortName, receiverType?.let(::FqName))
+          lookup.topLevelFunctionsMap[functionSpecifier]?.let { addAll(it) }
+        }
+      }
     }
 
     if (packageName.isEmpty()) return foundArtifacts
@@ -75,8 +91,7 @@
 
     return try {
       data.use { readIndicesFromJsonFile(it) }
-    }
-    catch (e: Exception) {
+    } catch (e: Exception) {
       logger<MavenClassRegistry>().warn("Problem reading GMaven index file: ${e.message}")
       LookupData.EMPTY
     }
@@ -102,7 +117,7 @@
   @Throws(IOException::class)
   private fun readIndexArray(reader: JsonReader): LookupData {
     val classNames: MutableList<Pair<String, LibraryImportData>> = mutableListOf()
-    val topLevelFunctions: MutableList<Pair<String, LibraryImportData>> = mutableListOf()
+    val topLevelFunctions: MutableList<Pair<FunctionSpecifier, LibraryImportData>> = mutableListOf()
     val ktxMap: MutableMap<String, String> = mutableMapOf()
     val coordinateList: MutableList<Coordinate> = mutableListOf()
 
@@ -114,12 +129,10 @@
       classNames.addAll(indexData.getClassSimpleNamesWithLibraries())
 
       // Get top-level function names and their associated libraries.
-      topLevelFunctions.addAll(indexData.getTopLevelFunctionSimpleNamesWithLibraries())
+      topLevelFunctions.addAll(indexData.getTopLevelFunctionSpecifiersWithLibraries())
 
       // Update "artifact to the associated KTX artifact" map.
-      indexData.toKtxMapEntry()?.let {
-        ktxMap[it.targetLibrary] = it.ktxLibrary
-      }
+      indexData.toKtxMapEntry()?.let { ktxMap[it.targetLibrary] = it.ktxLibrary }
 
       // Update maven artifact coordinate list.
       coordinateList.add(Coordinate(indexData.groupId, indexData.artifactId, indexData.version))
@@ -140,7 +153,8 @@
     var version: String? = null
     var ktxTargets: Collection<String>? = null
     var fqcns: Collection<FqName>? = null
-    // Top-level functions aren't in the index when empty in order to save bytes. Missing is not consider malformed, so allow empty list.
+    // Top-level functions aren't in the index when empty in order to save bytes. Missing is not
+    // consider malformed, so allow empty list.
     var topLevelFunctions: Collection<KotlinTopLevelFunction> = emptyList()
     while (reader.hasNext()) {
       when (reader.nextName()) {
@@ -168,14 +182,18 @@
       }
     }
 
-    val gMavenIndex = GMavenArtifactIndex(
-      groupId = groupId ?: throw MalformedIndexException("Group ID is missing($reader)."),
-      artifactId = artifactId ?: throw MalformedIndexException("Artifact ID is missing($reader)."),
-      version = version ?: throw MalformedIndexException("Version is missing($reader)."),
-      ktxTargets = ktxTargets ?: throw MalformedIndexException("Ktx targets are missing($reader)."),
-      fqcns = fqcns ?: throw MalformedIndexException("Fully qualified class names are missing($reader)."),
-      topLevelFunctions = topLevelFunctions,
-    )
+    val gMavenIndex =
+      GMavenArtifactIndex(
+        groupId = groupId ?: throw MalformedIndexException("Group ID is missing($reader)."),
+        artifactId = artifactId
+            ?: throw MalformedIndexException("Artifact ID is missing($reader)."),
+        version = version ?: throw MalformedIndexException("Version is missing($reader)."),
+        ktxTargets = ktxTargets
+            ?: throw MalformedIndexException("Ktx targets are missing($reader)."),
+        fqcns = fqcns
+            ?: throw MalformedIndexException("Fully qualified class names are missing($reader)."),
+        topLevelFunctions = topLevelFunctions,
+      )
     reader.endObject()
     return gMavenIndex
   }
@@ -198,15 +216,23 @@
       while (reader.hasNext()) {
         reader.beginObject()
         var fqName: String? = null
+        var xFqName: String? = null
+        var receiverFqName: String? = null
         while (reader.hasNext()) {
           when (reader.nextName()) {
             "fqn" -> fqName = reader.nextString()
+            "xfqn" -> xFqName = reader.nextString()
+            "rcvr" -> receiverFqName = reader.nextString()
             else -> reader.skipValue()
           }
         }
         reader.endObject()
 
-        if (fqName != null) add(KotlinTopLevelFunction.fromJvmQualifiedName(fqName))
+        when {
+          fqName != null -> add(KotlinTopLevelFunction.fromJvmQualifiedName(fqName))
+          xFqName != null && receiverFqName != null ->
+            add(KotlinTopLevelFunction.fromJvmQualifiedName(xFqName, receiverFqName))
+        }
       }
       reader.endArray()
     }
@@ -233,9 +259,7 @@
   }
 }
 
-/**
- * An index of a specific [version] of GMaven Artifact.
- */
+/** An index of a specific [version] of GMaven Artifact. */
 data class GMavenArtifactIndex(
   val groupId: String,
   val artifactId: String,
@@ -247,28 +271,31 @@
 
   /** Gets a list of simple class names and their corresponding [LibraryImportData]s. */
   fun getClassSimpleNamesWithLibraries(): List<Pair<String, LibraryImportData>> {
-    return fqcns
-      .map { fqName ->
-        fqName.shortName().asString() to LibraryImportData(
+    return fqcns.map { fqName ->
+      fqName.shortName().asString() to
+        LibraryImportData(
           artifact = "$groupId:$artifactId",
           importedItemFqName = fqName.asString(),
           importedItemPackageName = fqName.parent().asString(),
           version = version
         )
-      }
+    }
   }
 
-  /** Gets a list of top-level function simple names and their corresponding [LibraryImportData]s. */
-  fun getTopLevelFunctionSimpleNamesWithLibraries(): List<Pair<String, LibraryImportData>> {
-    return topLevelFunctions
-      .map { topLevelFunction ->
-        topLevelFunction.simpleName to LibraryImportData(
+  /**
+   * Gets a list of top-level function simple names and their corresponding [LibraryImportData]s.
+   */
+  fun getTopLevelFunctionSpecifiersWithLibraries():
+    List<Pair<FunctionSpecifier, LibraryImportData>> {
+    return topLevelFunctions.map { topLevelFunction ->
+      topLevelFunction.toSpecifier() to
+        LibraryImportData(
           artifact = "$groupId:$artifactId",
           importedItemFqName = topLevelFunction.kotlinFqName.asString(),
           importedItemPackageName = topLevelFunction.packageName,
           version = version
         )
-      }
+    }
   }
 
   /**
@@ -279,17 +306,13 @@
   fun toKtxMapEntry(): KtxMapEntry? {
     if (ktxTargets.isEmpty()) return null
 
-    // It's implicit that there's up to one target artifact that's associated to the given KTX artifact.
-    return KtxMapEntry(
-      ktxLibrary = "$groupId:$artifactId",
-      targetLibrary = ktxTargets.first()
-    )
+    // It's implicit that there's up to one target artifact that's associated to the given KTX
+    // artifact.
+    return KtxMapEntry(ktxLibrary = "$groupId:$artifactId", targetLibrary = ktxTargets.first())
   }
 }
 
-/**
- * An entry of a map from the KTX library to its decorated library.
- */
+/** An entry of a map from the KTX library to its decorated library. */
 data class KtxMapEntry(val ktxLibrary: String, val targetLibrary: String)
 
 /** A top-level Kotlin function. */
@@ -299,14 +322,22 @@
   /** Package name of the function. */
   val packageName: String,
   /**
-   * Fully-qualified name of the function in Kotlin. This does not contain the synthetic class (e.g. "FileFacadeKt") that contains the
-   * function in the JVM. That makes this name appropriate to use when calling from Kotlin, but not from Java.
+   * Fully-qualified name of the function in Kotlin. This does not contain the synthetic class (e.g.
+   * "FileFacadeKt") that contains the function in the JVM. That makes this name appropriate to use
+   * when calling from Kotlin, but not from Java.
    */
   val kotlinFqName: FqName,
+  /** Fully-qualified name of the function's receiver in Kotlin. */
+  val receiverFqName: FqName?,
 ) {
 
+  fun toSpecifier() = FunctionSpecifier(simpleName, receiverFqName)
+
   companion object {
-    fun fromJvmQualifiedName(fqName: String): KotlinTopLevelFunction {
+    fun fromJvmQualifiedName(
+      fqName: String,
+      receiverFqName: String? = null
+    ): KotlinTopLevelFunction {
       require(fqName.contains('.')) {
         "fqName does not have file facade class containing the function: '$fqName'"
       }
@@ -317,42 +348,45 @@
       val packagePrefix = if (packageName.isEmpty()) "" else "$packageName."
 
       return KotlinTopLevelFunction(
-          simpleName = functionSimpleName,
-          kotlinFqName = FqName("$packagePrefix$functionSimpleName"),
-          packageName = packageName)
+        simpleName = functionSimpleName,
+        packageName = packageName,
+        kotlinFqName = FqName("$packagePrefix$functionSimpleName"),
+        receiverFqName = receiverFqName?.let(::FqName),
+      )
     }
   }
 }
 
-/**
- * Lookup data extracted from an index file.
- */
+/** Lookup data extracted from an index file. */
 data class LookupData(
-  /**
-   * A map from simple class names to the corresponding [LibraryImportData] objects.
-   */
+  /** A map from simple class names to the corresponding [LibraryImportData] objects. */
   val classNameMap: Map<String, List<LibraryImportData>>,
-  /**
-   * A map from simple Kotlin top-level function names to the corresponding [LibraryImportData] objects.
-   */
-  val topLevelFunctionsMap: Map<String, List<LibraryImportData>>,
-  /**
-   * A map from non-KTX libraries to the associated KTX libraries.
-   */
+  /** A map from function specifiers to the corresponding [LibraryImportData] objects. */
+  val topLevelFunctionsMap: Map<FunctionSpecifier, List<LibraryImportData>>,
+  /** A map from non-KTX libraries to the associated KTX libraries. */
   val ktxMap: Map<String, String>,
 
-  /**
-   * A list of Google Maven [MavenClassRegistryBase.Coordinate].
-   */
+  /** A list of Google Maven [MavenClassRegistryBase.Coordinate]. */
   val coordinateList: List<MavenClassRegistryBase.Coordinate>,
 ) {
+  /**
+   * A map from simple names (irrespective of receiver) to corresponding [LibraryImportData]
+   * objects.
+   */
+  val topLevelFunctionsMapAllReceivers: Map<String, List<LibraryImportData>> =
+    topLevelFunctionsMap.entries.groupBy({ it.key.simpleName }, { it.value }).mapValues {
+      it.value.flatten().distinct()
+    }
+
   companion object {
-    @JvmStatic
-    val EMPTY = LookupData(emptyMap(), emptyMap(), emptyMap(), emptyList())
+    @JvmStatic val EMPTY = LookupData(emptyMap(), emptyMap(), emptyMap(), emptyList())
   }
 }
 
-/**
- * Exception thrown when parsing malformed GMaven index file.
- */
+data class FunctionSpecifier(
+  val simpleName: String,
+  val receiverFqName: FqName?,
+)
+
+/** Exception thrown when parsing malformed GMaven index file. */
 private class MalformedIndexException(message: String) : RuntimeException(message)
diff --git a/android/src/com/android/tools/idea/imports/MavenClassRegistryBase.kt b/android/src/com/android/tools/idea/imports/MavenClassRegistryBase.kt
index 02eb9b3..af87daf 100644
--- a/android/src/com/android/tools/idea/imports/MavenClassRegistryBase.kt
+++ b/android/src/com/android/tools/idea/imports/MavenClassRegistryBase.kt
@@ -18,15 +18,15 @@
 import com.android.tools.idea.projectsystem.DependencyType
 import com.intellij.openapi.fileTypes.FileType
 
-/**
- * Registry provides lookup service for Google Maven Artifacts when asked.
- */
+/** Registry provides lookup service for Google Maven Artifacts when asked. */
 abstract class MavenClassRegistryBase {
   /**
    * Library data for importing a specific item (class or function) with its GMaven artifact.
    *
-   * @property artifact maven coordinate: groupId:artifactId, please note version is not included here.
-   * @property importedItemFqName fully-qualified name of the item to import. Can be a class or function name.
+   * @property artifact maven coordinate: groupId:artifactId, please note version is not included
+   *   here.
+   * @property importedItemFqName fully-qualified name of the item to import. Can be a class or
+   *   function name.
    * @property importedItemPackageName package name of the item to import.
    * @property version the version of the [artifact].
    */
@@ -34,35 +34,39 @@
     val artifact: String,
     val importedItemFqName: String,
     val importedItemPackageName: String,
-    val version: String? = null)
+    val version: String? = null
+  )
 
-  /**
-   * Coordinate for Google Maven artifact.
-   */
+  /** Coordinate for Google Maven artifact. */
   data class Coordinate(val groupId: String, val artifactId: String, val version: String)
 
   /**
-   * Given an unresolved name, returns the likely collection of [MavenClassRegistryBase.LibraryImportData] objects for the maven.google.com
-   * artifacts containing a class or function matching the name.
+   * Given an unresolved name, returns the likely collection of
+   * [MavenClassRegistryBase.LibraryImportData] objects for the maven.google.com artifacts
+   * containing a class or function matching the name.
    *
-   * @param name simple or fully-qualified name typed by the user. May correspond to a class name (any files) or a top-level Kotlin function
-   * name (Kotlin files only).
+   * @param name simple or fully-qualified name typed by the user. May correspond to a class name
+   *   (any files) or a top-level Kotlin function name (Kotlin files only).
+   * @param receiverType the fully-qualified name of the receiver type, if any, [ALL_RECEIVER_TYPES]
+   *   if results for all receiver types should be returned, or `null` otherwise.
    */
-  abstract fun findLibraryData(name: String, useAndroidX: Boolean, completionFileType: FileType?): Collection<LibraryImportData>
+  abstract fun findLibraryData(
+    name: String,
+    receiverType: String?,
+    useAndroidX: Boolean,
+    completionFileType: FileType?
+  ): Collection<LibraryImportData>
 
   /**
-   * For the given runtime artifact, if Kotlin is the adopted language, the corresponding ktx library is provided.
+   * For the given runtime artifact, if Kotlin is the adopted language, the corresponding ktx
+   * library is provided.
    */
   abstract fun findKtxLibrary(artifact: String): String?
 
-  /**
-   * Returns a collection of [Coordinate].
-   */
+  /** Returns a collection of [Coordinate]. */
   abstract fun getCoordinates(): Collection<Coordinate>
 
-  /**
-   * For the given runtime artifact, if it also requires an annotation processor, provide it.
-   */
+  /** For the given runtime artifact, if it also requires an annotation processor, provide it. */
   fun findAnnotationProcessor(artifact: String): String? {
     return when (artifact) {
       "androidx.room:room-runtime",
@@ -73,17 +77,24 @@
   }
 
   /**
-   * For the given artifact, if it also requires extra artifacts for proper functionality, provide it.
+   * For the given artifact, if it also requires extra artifacts for proper functionality, provide
+   * it.
    *
    * This is to handle those special cases. For example, for an unresolved symbol "@Preview",
-   * "androidx.compose.ui:ui-tooling-preview" is one of the suggested artifacts to import based on the extracted
-   * contents from the GMaven index file. However, this is not enough -"androidx.compose.ui:ui-tooling" should be added
-   * on instead. So we just provide both in the end.
+   * "androidx.compose.ui:ui-tooling-preview" is one of the suggested artifacts to import based on
+   * the extracted contents from the GMaven index file. However, this is not enough
+   * -"androidx.compose.ui:ui-tooling" should be added on instead. So we just provide both in the
+   * end.
    */
   fun findExtraArtifacts(artifact: String): Map<String, DependencyType> {
     return when (artifact) {
-      "androidx.compose.ui:ui-tooling-preview" -> mapOf("androidx.compose.ui:ui-tooling" to DependencyType.DEBUG_IMPLEMENTATION)
+      "androidx.compose.ui:ui-tooling-preview" ->
+        mapOf("androidx.compose.ui:ui-tooling" to DependencyType.DEBUG_IMPLEMENTATION)
       else -> emptyMap()
     }
   }
-}
\ No newline at end of file
+
+  companion object {
+    const val ALL_RECEIVER_TYPES = "*"
+  }
+}
diff --git a/android/src/com/android/tools/idea/model/MergedManifestInfo.java b/android/src/com/android/tools/idea/model/MergedManifestInfo.java
index 016b94d..0cec242 100644
--- a/android/src/com/android/tools/idea/model/MergedManifestInfo.java
+++ b/android/src/com/android/tools/idea/model/MergedManifestInfo.java
@@ -23,9 +23,9 @@
 import com.android.manifmerger.ManifestMerger2;
 import com.android.manifmerger.MergingReport;
 import com.android.manifmerger.XmlDocument;
-import com.android.tools.idea.gradle.plugin.AndroidPluginInfo;
 import com.android.tools.idea.project.SyncTimestampUtil;
 import com.android.tools.idea.projectsystem.AndroidModuleSystem;
+import com.android.tools.idea.projectsystem.AndroidProjectSystem;
 import com.android.tools.idea.projectsystem.ManifestOverrides;
 import com.android.tools.idea.projectsystem.MergedManifestContributors;
 import com.android.tools.idea.projectsystem.ProjectSystemUtil;
@@ -33,7 +33,6 @@
 import com.android.utils.ILogger;
 import com.android.utils.NullLogger;
 import com.android.utils.Pair;
-import com.android.utils.XmlUtils;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.intellij.openapi.application.ApplicationManager;
@@ -55,6 +54,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
@@ -322,8 +322,6 @@
 
     ManifestMerger2.Invoker manifestMergerInvoker = ManifestMerger2.newMerger(mainManifestFile, logger, mergeType);
     manifestMergerInvoker.withFeatures(ManifestMerger2.Invoker.Feature.SKIP_BLAME, ManifestMerger2.Invoker.Feature.SKIP_XML_STRING, ManifestMerger2.Invoker.Feature.KEEP_GOING_AFTER_ERRORS);
-    if(!isVersionAtLeast7_4_0(facet.getModule().getProject()))
-      manifestMergerInvoker.withFeatures(ManifestMerger2.Invoker.Feature.DISABLE_STRIP_LIBRARY_TARGET_SDK);
     manifestMergerInvoker.addFlavorAndBuildTypeManifests(VfsUtilCore.virtualToIoFiles(flavorAndBuildTypeManifests).toArray(new File[0]));
     manifestMergerInvoker.addNavigationFiles(VfsUtilCore.virtualToIoFiles(navigationFiles));
     manifestMergerInvoker.withProcessCancellationChecker(ProgressManager::checkCanceled);
@@ -391,6 +389,14 @@
       }
     });
 
+    Project project = facet.getModule().getProject();
+    AndroidProjectSystem projectSystem = ProjectSystemUtil.getProjectSystem(project);
+    Optional<MergedManifestInfoToken<AndroidProjectSystem>> maybeToken =
+      Arrays.stream(MergedManifestInfoToken.EP_NAME.getExtensions(project))
+        .filter(t -> t.isApplicable(projectSystem))
+        .findFirst();
+    maybeToken.ifPresent(token -> token.withProjectSystemFeatures(projectSystem, manifestMergerInvoker));
+
     return manifestMergerInvoker.merge();
   }
 
@@ -421,11 +427,4 @@
     }
     return null;
   }
-
-  private static boolean isVersionAtLeast7_4_0(Project project) {
-    AndroidPluginInfo androidPluginInfo = AndroidPluginInfo.findFromModel(project);
-    return androidPluginInfo != null &&
-           androidPluginInfo.getPluginVersion() != null &&
-           androidPluginInfo.getPluginVersion().isAtLeast(7, 4, 0);
-  }
 }
\ No newline at end of file
diff --git a/android/src/com/android/tools/idea/project/DefaultModuleSystem.kt b/android/src/com/android/tools/idea/project/DefaultModuleSystem.kt
index f1895f4..609291c 100644
--- a/android/src/com/android/tools/idea/project/DefaultModuleSystem.kt
+++ b/android/src/com/android/tools/idea/project/DefaultModuleSystem.kt
@@ -266,7 +266,6 @@
     val applicationRClassConstantIds: Key<Boolean> = Key.create(::applicationRClassConstantIds.qualifiedName<DefaultModuleSystem>())
     val testRClassConstantIds: Key<Boolean> = Key.create(::testRClassConstantIds.qualifiedName<DefaultModuleSystem>())
     val useAndroidX: Key<Boolean> = Key.create(::useAndroidX.qualifiedName<DefaultModuleSystem>())
-    val enableVcsInfo: Key<Boolean> = Key.create(::enableVcsInfo.qualifiedName<DefaultModuleSystem>())
   }
 
   override var usesCompose: Boolean by UserData(Keys.usesCompose, false)
@@ -302,8 +301,6 @@
 
   override var useAndroidX: Boolean by UserData(Keys.useAndroidX, false)
 
-  override var enableVcsInfo: Boolean by UserData(Keys.enableVcsInfo, false)
-
   override val moduleDependencies: ModuleDependencies
     get() = StudioModuleDependencies(module)
 }
diff --git a/android/src/com/android/tools/idea/project/DefaultProjectSystem.kt b/android/src/com/android/tools/idea/project/DefaultProjectSystem.kt
index ddd5fda..0bb037f 100644
--- a/android/src/com/android/tools/idea/project/DefaultProjectSystem.kt
+++ b/android/src/com/android/tools/idea/project/DefaultProjectSystem.kt
@@ -138,7 +138,7 @@
     }
   }
 
-  override fun validateRunConfiguration(runConfiguration: RunConfiguration): List<ValidationError> {
+  override fun validateRunConfiguration(runConfiguration: RunConfiguration, quickFixCallback: Runnable?): List<ValidationError> {
     return emptyList()
   }
 
diff --git a/android/src/com/android/tools/idea/res/ToggleResourceTraceAction.kt b/android/src/com/android/tools/idea/res/ToggleResourceTraceAction.kt
index 508da5d..d9fde63 100644
--- a/android/src/com/android/tools/idea/res/ToggleResourceTraceAction.kt
+++ b/android/src/com/android/tools/idea/res/ToggleResourceTraceAction.kt
@@ -15,6 +15,7 @@
  */
 package com.android.tools.idea.res
 
+import com.intellij.openapi.actionSystem.ActionUpdateThread
 import com.intellij.openapi.actionSystem.AnActionEvent
 import com.intellij.openapi.actionSystem.ToggleAction
 import com.intellij.openapi.application.ex.ApplicationInfoEx
@@ -38,6 +39,10 @@
     ResourceUpdateTraceSettings.getInstance().enabled = state
   }
 
+  override fun getActionUpdateThread(): ActionUpdateThread {
+    return ActionUpdateThread.BGT
+  }
+
   override fun update(event: AnActionEvent) {
     super.update(event)
     event.presentation.isVisible = ApplicationInfoEx.getInstanceEx().isEAP
diff --git a/android/src/com/android/tools/idea/run/AndroidActivityRunLineMarkerContributor.kt b/android/src/com/android/tools/idea/run/AndroidActivityRunLineMarkerContributor.kt
new file mode 100644
index 0000000..bd24774
--- /dev/null
+++ b/android/src/com/android/tools/idea/run/AndroidActivityRunLineMarkerContributor.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.run
+
+import com.android.SdkConstants
+import com.android.tools.idea.run.configuration.getPsiClass
+import com.intellij.execution.JavaExecutionUtil
+import com.intellij.execution.lineMarker.ExecutorAction
+import com.intellij.execution.lineMarker.RunLineMarkerContributor
+import com.intellij.icons.AllIcons
+import com.intellij.psi.JavaTokenType
+import com.intellij.psi.PsiClass
+import com.intellij.psi.PsiElement
+import com.intellij.psi.util.InheritanceUtil
+import org.jetbrains.android.util.AndroidBundle
+import org.jetbrains.kotlin.lexer.KtTokens
+
+/**
+ * Identifies classes that implement an Android Activity and adds a gutter icon to run them.
+ * (The details of the run configuration are provided by AndroidConfigurationProducer.)
+ */
+class AndroidActivityRunLineMarkerContributor : RunLineMarkerContributor() {
+  override fun getInfo(e: PsiElement): Info? {
+    if (!e.isClassToken()) {
+      return null
+    }
+
+    val psiClass = e.getPsiClass() ?: return null
+    if (psiClass.isAndroidActivitySubclass()) {
+      val activityName = psiClass.name ?: return null
+      return Info(AllIcons.RunConfigurations.TestState.Run, ExecutorAction.getActions()) {
+        AndroidBundle.message(
+          "android.run.configuration.run",
+          JavaExecutionUtil.getPresentableClassName(activityName)!!
+        )
+      }
+    }
+    return null
+  }
+
+  private fun PsiElement.isClassToken() =
+    node.elementType == KtTokens.CLASS_KEYWORD || node.elementType == JavaTokenType.CLASS_KEYWORD
+  private fun PsiClass.isAndroidActivitySubclass() =
+    InheritanceUtil.isInheritor(this, SdkConstants.CLASS_ACTIVITY)
+}
diff --git a/android/src/com/android/tools/idea/run/AndroidRunConfigurationBase.java b/android/src/com/android/tools/idea/run/AndroidRunConfigurationBase.java
index 5392779..034821d 100644
--- a/android/src/com/android/tools/idea/run/AndroidRunConfigurationBase.java
+++ b/android/src/com/android/tools/idea/run/AndroidRunConfigurationBase.java
@@ -56,7 +56,6 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.Objects;
-import java.util.Optional;
 import org.jdom.Element;
 import org.jetbrains.android.facet.AndroidFacet;
 import org.jetbrains.android.sdk.AndroidPlatforms;
@@ -132,6 +131,10 @@
    * We use a separate method for the collection so the compiler prevents us from accidentally throwing.
    */
   public List<ValidationError> validate(@Nullable Executor executor) {
+    return validate(executor, null);
+  }
+
+  public List<ValidationError> validate(@Nullable Executor executor, @Nullable Runnable quickFixCallback) {
     List<ValidationError> errors = new ArrayList<>();
     JavaRunConfigurationModule configurationModule = getConfigurationModule();
     try {
@@ -198,7 +201,7 @@
     }
 
     AndroidProjectSystem projectSystem = getProjectSystem(getProject());
-    errors.addAll(projectSystem.validateRunConfiguration(this));
+    errors.addAll(projectSystem.validateRunConfiguration(this, quickFixCallback));
 
     errors.addAll(checkConfiguration(facet));
     AndroidDebuggerState androidDebuggerState = myAndroidDebuggerContext.getAndroidDebuggerState();
diff --git a/android/src/com/android/tools/idea/run/AndroidRunConfigurationExecutor.kt b/android/src/com/android/tools/idea/run/AndroidRunConfigurationExecutor.kt
index 21131d84..6374899 100644
--- a/android/src/com/android/tools/idea/run/AndroidRunConfigurationExecutor.kt
+++ b/android/src/com/android/tools/idea/run/AndroidRunConfigurationExecutor.kt
@@ -170,7 +170,7 @@
   private fun notifyLiveEditService(device: IDevice, applicationId: String) {
     try {
       AndroidLiveLiteralDeployMonitor.startMonitor(project, applicationId, device)
-      LiveEditHelper().invokeLiveEdit(liveEditService, env, applicationIdProvider, apkProvider, device)
+      LiveEditHelper().invokeLiveEdit(liveEditService, env, applicationId, apkProvider, device)
     } catch (e: Exception) {
 
       // Monitoring should always start successfully.
diff --git a/android/src/com/android/tools/idea/run/LiveEditHelper.kt b/android/src/com/android/tools/idea/run/LiveEditHelper.kt
index 9ae9cd2..ed42fe5 100644
--- a/android/src/com/android/tools/idea/run/LiveEditHelper.kt
+++ b/android/src/com/android/tools/idea/run/LiveEditHelper.kt
@@ -22,9 +22,15 @@
 import java.nio.file.Path
 
 class LiveEditHelper {
-  fun invokeLiveEdit(liveEditService: LiveEditService, env: ExecutionEnvironment, applicationIdProvider: ApplicationIdProvider, apkProvider: ApkProvider, device: IDevice) {
+  fun invokeLiveEdit(
+    liveEditService: LiveEditService,
+    env: ExecutionEnvironment,
+    applicationId: String,
+    apkProvider: ApkProvider,
+    device: IDevice
+  ) {
     val liveEditApp = LiveEditApp(getApkPaths(apkProvider, device), device.getVersion().getApiLevel())
-    liveEditService.notifyAppDeploy(env.getRunProfile(), env.getExecutor(), applicationIdProvider.packageName, device, liveEditApp)
+    liveEditService.notifyAppDeploy(env.getRunProfile(), env.getExecutor(), applicationId, device, liveEditApp)
   }
 
   fun getApkPaths(apkProvider: ApkProvider, device: IDevice): Set<Path> {
diff --git a/android/src/com/android/tools/idea/run/blaze/BlazeAndroidConfigurationExecutor.kt b/android/src/com/android/tools/idea/run/blaze/BlazeAndroidConfigurationExecutor.kt
index d624ffc..2916903 100644
--- a/android/src/com/android/tools/idea/run/blaze/BlazeAndroidConfigurationExecutor.kt
+++ b/android/src/com/android/tools/idea/run/blaze/BlazeAndroidConfigurationExecutor.kt
@@ -133,7 +133,7 @@
           LiveEditHelper().invokeLiveEdit(
             liveEditService,
             env,
-            applicationIdProvider,
+            applicationId,
             apkProvider,
             device
           ) // Notify listeners of the deployment.
diff --git a/android/src/com/android/tools/idea/run/deployment/DevicesSelectedService.java b/android/src/com/android/tools/idea/run/deployment/DevicesSelectedService.java
index f22adbd..607e9e3 100644
--- a/android/src/com/android/tools/idea/run/deployment/DevicesSelectedService.java
+++ b/android/src/com/android/tools/idea/run/deployment/DevicesSelectedService.java
@@ -210,14 +210,26 @@
     return supplier.getDialogTargets();
   }
 
-  void setTargetsSelectedWithDialog(@NotNull Set<Target> targetsSelectedWithDialog) {
+  /**
+   * Updates the currently-persisted selected device state with the new set of selected targets.
+   *
+   * RunningDeviceTargets will be replaced first by any pre-existing launchable targets with the same device key, and alternatively by
+   * defaultLaunchTargets.
+   */
+  void setTargetsSelectedWithDialog(@NotNull Set<Target> targetsSelectedWithDialog, @NotNull List<Target> defaultLaunchTargets) {
     var state = myPersistentStateComponent.getState(getSelectedRunConfiguration());
-    TargetsForWritingSupplier supplier = new TargetsForWritingSupplier(state.getTargetsSelectedWithDialog(), targetsSelectedWithDialog);
+
+    TargetsForWritingSupplier supplier =
+      new TargetsForWritingSupplier(state.getTargetsSelectedWithDialog(), targetsSelectedWithDialog, defaultLaunchTargets);
 
     state.setRunningDeviceTargetsSelectedWithDialog(supplier.getDialogRunningDeviceTargets());
     state.setTargetsSelectedWithDialog(supplier.getDialogTargets());
   }
 
+  void setTargetsSelectedWithDialog(@NotNull Set<Target> targetsSelectedWithDialog) {
+    setTargetsSelectedWithDialog(targetsSelectedWithDialog, Collections.emptyList());
+  }
+
   @Nullable
   private RunConfiguration getSelectedRunConfiguration() {
     var configurationAndSettings = myRunManager.getSelectedConfiguration();
diff --git a/android/src/com/android/tools/idea/run/deployment/Heading.java b/android/src/com/android/tools/idea/run/deployment/Heading.java
index 9b7b9fd..7ca6d8a 100644
--- a/android/src/com/android/tools/idea/run/deployment/Heading.java
+++ b/android/src/com/android/tools/idea/run/deployment/Heading.java
@@ -15,6 +15,7 @@
  */
 package com.android.tools.idea.run.deployment;
 
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import org.jetbrains.annotations.NotNull;
@@ -26,6 +27,12 @@
   private Heading() {
   }
 
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
   @Override
   public void update(@NotNull AnActionEvent event) {
     event.getPresentation().setEnabled(false);
diff --git a/android/src/com/android/tools/idea/run/deployment/OWNERS b/android/src/com/android/tools/idea/run/deployment/OWNERS
index 7d3bdae..16ea468 100644
--- a/android/src/com/android/tools/idea/run/deployment/OWNERS
+++ b/android/src/com/android/tools/idea/run/deployment/OWNERS
@@ -1,5 +1,5 @@
 estebandlc@google.com
-juancnuno@google.com
+rosej@google.com
 rpaquay@google.com
 
 # IntelliJ Platform SDK merges
diff --git a/android/src/com/android/tools/idea/run/deployment/SelectMultipleDevicesDialog.java b/android/src/com/android/tools/idea/run/deployment/SelectMultipleDevicesDialog.java
index 34cd6f5..acb94c3 100644
--- a/android/src/com/android/tools/idea/run/deployment/SelectMultipleDevicesDialog.java
+++ b/android/src/com/android/tools/idea/run/deployment/SelectMultipleDevicesDialog.java
@@ -107,7 +107,10 @@
     super.doOKAction();
 
     assert myTable != null;
-    myDevicesSelectedServiceGetInstance.apply(myProject).setTargetsSelectedWithDialog(myTable.getSelectedTargets());
+
+    List<Target> defaultLaunchTargets =
+      myDevices.stream().filter(VirtualDevice.class::isInstance).<Target>map(device -> new QuickBootTarget(device.key())).toList();
+    myDevicesSelectedServiceGetInstance.apply(myProject).setTargetsSelectedWithDialog(myTable.getSelectedTargets(), defaultLaunchTargets);
   }
 
   @VisibleForTesting
@@ -153,7 +156,8 @@
   }
 
   @VisibleForTesting
-  @NotNull SelectMultipleDevicesDialogTable getTable() {
+  @NotNull
+  SelectMultipleDevicesDialogTable getTable() {
     assert myTable != null;
     return myTable;
   }
diff --git a/android/src/com/android/tools/idea/run/deployment/TargetsForWritingSupplier.java b/android/src/com/android/tools/idea/run/deployment/TargetsForWritingSupplier.java
index c67494d..84a91a6 100644
--- a/android/src/com/android/tools/idea/run/deployment/TargetsForWritingSupplier.java
+++ b/android/src/com/android/tools/idea/run/deployment/TargetsForWritingSupplier.java
@@ -15,8 +15,10 @@
  */
 package com.android.tools.idea.run.deployment;
 
+import com.google.common.collect.Maps;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Collectors;
@@ -25,36 +27,45 @@
 
 /**
  * Consumes the selection from the drop down or dialog and splits it up into RunningDeviceTargets and nonRunningDeviceTargets
- * (ColdBootTarget, QuickBootTarget, BootWithSnapshotTarget) to write to DevicesSelectedService.State. For each RunningDeviceTarget in the
- * selection, the corresponding nonRunningDeviceTarget is kept from oldTargets. So the original target selection isn't lost when the device
- * is stopped.
+ * (ColdBootTarget, QuickBootTarget, BootWithSnapshotTarget) to write to DevicesSelectedService.State.
+ *
+ * For each RunningDeviceTarget in the selection, the corresponding nonRunningDeviceTarget is kept from oldTargets, so the original target
+ * selection isn't lost when the device is stopped. If there is no corresponding oldTarget, uses the default launch target (i.e. quickboot)
+ * for virtual devices.
  */
 final class TargetsForWritingSupplier {
   private final @NotNull Collection<RunningDeviceTarget> myRunningDeviceTargets;
   private final @NotNull Collection<Target> myTargets;
 
   TargetsForWritingSupplier(@Nullable Target oldTarget, @Nullable Target newTarget) {
-    this(DeploymentCollections.toList(oldTarget), DeploymentCollections.toList(newTarget));
+    this(DeploymentCollections.toList(oldTarget), DeploymentCollections.toList(newTarget), Collections.emptyList());
   }
 
   /**
    * @param oldTargets either the list from DevicesSelectedService.State.targetSelectedWithDropDown or targetsSelectedWithDialog. None of
    *                   these will be RunningDeviceTargets.
    * @param newTargets the new selection from the drop down or dialog. May contain RunningDeviceTargets.
+   * @param defaultLaunchTargets targets to be used in place of RunningDeviceTargets if there is no existing non-RunningDeviceTarget for the device.
    */
-  TargetsForWritingSupplier(@NotNull Collection<Target> oldTargets, @NotNull Collection<Target> newTargets) {
+  TargetsForWritingSupplier(@NotNull Collection<Target> oldTargets, @NotNull Collection<Target> newTargets, Collection<Target> defaultLaunchTargets) {
     Map<Key, Target> keyToTargetMap = oldTargets.stream().collect(Collectors.toMap(Target::getDeviceKey, target -> target));
+    Map<Key, Target> keyToDefaultLaunchTargetMap = defaultLaunchTargets.stream().collect(Collectors.toMap(Target::getDeviceKey, target -> target));
 
     int size = newTargets.size();
     myRunningDeviceTargets = new ArrayList<>(size);
     myTargets = new ArrayList<>(size);
 
-    newTargets.forEach(newTarget -> {
+    for (Target newTarget : newTargets) {
       if (newTarget instanceof RunningDeviceTarget) {
         Target oldTarget = keyToTargetMap.get(newTarget.getDeviceKey());
 
         if (oldTarget != null) {
           myTargets.add(oldTarget);
+        } else {
+          Target defaultTarget = keyToDefaultLaunchTargetMap.get(newTarget.getDeviceKey());
+          if (defaultTarget != null) {
+            myTargets.add(defaultTarget);
+          }
         }
 
         myRunningDeviceTargets.add((RunningDeviceTarget)newTarget);
@@ -62,7 +73,7 @@
       else {
         myTargets.add(newTarget);
       }
-    });
+    }
   }
 
   @NotNull Optional<RunningDeviceTarget> getDropDownRunningDeviceTarget() {
diff --git a/android/src/com/android/tools/idea/run/deployment/Updater.java b/android/src/com/android/tools/idea/run/deployment/Updater.java
index 2d1e39d..ec5f3ca 100644
--- a/android/src/com/android/tools/idea/run/deployment/Updater.java
+++ b/android/src/com/android/tools/idea/run/deployment/Updater.java
@@ -181,6 +181,10 @@
     }
   }
 
+  /**
+   * Given that we are in the "multiple devices" selection mode, updates the set of selected devices based on the currently-existing
+   * devices. For example, this might reduce the count of devices when a physical device is unplugged.
+   */
   private void updateInToolbarForMultipleDevices() {
     Set<Target> selectedTargets = myDevicesSelectedService.getTargetsSelectedWithDialog(myDevices);
 
@@ -190,7 +194,7 @@
       .collect(Collectors.toSet());
 
     if (selectedTargets.retainAll(targets)) {
-      myDevicesSelectedService.setTargetsSelectedWithDialog(selectedTargets);
+      myDevicesSelectedService.setTargetsSelectedWithDialog(selectedTargets, Collections.emptyList());
     }
 
     if (selectedTargets.isEmpty()) {
diff --git a/android/src/com/android/tools/idea/run/editor/AndroidDebuggerPanel.java b/android/src/com/android/tools/idea/run/editor/AndroidDebuggerPanel.java
index 97bf097..49f23a8 100644
--- a/android/src/com/android/tools/idea/run/editor/AndroidDebuggerPanel.java
+++ b/android/src/com/android/tools/idea/run/editor/AndroidDebuggerPanel.java
@@ -96,7 +96,7 @@
     AndroidDebuggerConfigurable<AndroidDebuggerState> configurable = getConfigurable(androidDebugger);
 
     if (configurable != null) {
-      configurable.applyTo(myAndroidDebuggerContext.getAndroidDebuggerState(androidDebugger.getId()));
+      configurable.applyTo(androidDebuggerContext.getAndroidDebuggerState(androidDebugger.getId()));
     }
   }
 
diff --git a/android/src/com/android/tools/idea/run/editor/AndroidRunConfigurationEditor.java b/android/src/com/android/tools/idea/run/editor/AndroidRunConfigurationEditor.java
index fbab885..953cf38 100644
--- a/android/src/com/android/tools/idea/run/editor/AndroidRunConfigurationEditor.java
+++ b/android/src/com/android/tools/idea/run/editor/AndroidRunConfigurationEditor.java
@@ -16,6 +16,7 @@
 package com.android.tools.idea.run.editor;
 
 import com.android.tools.idea.execution.common.debug.AndroidDebuggerContext;
+import com.android.tools.idea.flags.StudioFlags;
 import com.android.tools.idea.run.AndroidRunConfigurationBase;
 import com.android.tools.idea.run.AndroidRunConfigurationModule;
 import com.android.tools.idea.run.ConfigurationSpecificEditor;
@@ -126,7 +127,9 @@
     }
 
     myAndroidProfilersPanel = new AndroidProfilersPanel(project, config.getProfilerState());
-    myTabbedPane.add("Profiling", myAndroidProfilersPanel.getComponent());
+    if(!StudioFlags.PROFILER_TASK_BASED_UX.get()) {
+      myTabbedPane.add("Profiling", myAndroidProfilersPanel.getComponent());
+    }
 
     myConfigurationSpecificEditor = configurationSpecificEditorFactory.apply(myModuleSelector);
     Disposer.register(this, myConfigurationSpecificEditor);
@@ -138,7 +141,7 @@
 
     myShowLogcatCheckBox.setVisible(showLogcatCheckbox);
 
-    checkValidationResults(config.validate(null));
+    checkValidationResults(config.validate(null, this::fireEditorStateChanged));
   }
 
   /**
diff --git a/android/src/com/android/tools/idea/stats/ShowStatisticsViewerAction.java b/android/src/com/android/tools/idea/stats/ShowStatisticsViewerAction.java
index 491ea1f..13ffb44 100644
--- a/android/src/com/android/tools/idea/stats/ShowStatisticsViewerAction.java
+++ b/android/src/com/android/tools/idea/stats/ShowStatisticsViewerAction.java
@@ -15,6 +15,7 @@
  */
 package com.android.tools.idea.stats;
 
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import org.jetbrains.annotations.NotNull;
@@ -26,6 +27,12 @@
   private StatisticsViewer myStatisticsViewer;
 
   @Override
+  @NotNull
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
+  @Override
   public void update(@NotNull AnActionEvent e) {
     e.getPresentation().setText(StatisticsViewer.TITLE);
   }
diff --git a/android/src/com/android/tools/idea/ui/resourcemanager/actions/OpenResourceManagerAction.kt b/android/src/com/android/tools/idea/ui/resourcemanager/actions/OpenResourceManagerAction.kt
index feae89f..1bf2eab 100644
--- a/android/src/com/android/tools/idea/ui/resourcemanager/actions/OpenResourceManagerAction.kt
+++ b/android/src/com/android/tools/idea/ui/resourcemanager/actions/OpenResourceManagerAction.kt
@@ -33,18 +33,13 @@
 
   override fun update(e: AnActionEvent) {
     val project = e.project
-    e.presentation.isEnabledAndVisible = project != null && ProjectFacetManager.getInstance(project).hasFacets(AndroidFacet.ID)
+    e.presentation.isEnabledAndVisible = project != null
+                                         && ProjectFacetManager.getInstance(project).hasFacets(AndroidFacet.ID)
+                                         && ToolWindowManager.getInstance(project).getToolWindow(RESOURCE_EXPLORER_TOOL_WINDOW_ID) != null
   }
 
   override fun actionPerformed(e: AnActionEvent) {
-    val project = e.getData(CommonDataKeys.PROJECT)
-    if (project != null) {
-      showResourceExplorer(project)
-    }
-  }
-
-  private fun showResourceExplorer(project: Project) {
-    val toolWindow = ToolWindowManager.getInstance(project).getToolWindow(RESOURCE_EXPLORER_TOOL_WINDOW_ID)!!
-    toolWindow.show(null)
+    val project = e.getData(CommonDataKeys.PROJECT) ?: return
+    ToolWindowManager.getInstance(project).getToolWindow(RESOURCE_EXPLORER_TOOL_WINDOW_ID)?.show(null)
   }
 }
\ No newline at end of file
diff --git a/android/src/com/android/tools/idea/ui/validation/validators/PathValidator.kt b/android/src/com/android/tools/idea/ui/validation/validators/PathValidator.kt
index dd40a92..6fbb6f7 100644
--- a/android/src/com/android/tools/idea/ui/validation/validators/PathValidator.kt
+++ b/android/src/com/android/tools/idea/ui/validation/validators/PathValidator.kt
@@ -19,6 +19,7 @@
 import com.android.tools.adtui.validation.Validator
 import com.android.tools.adtui.validation.Validator.Result
 import com.android.tools.adtui.validation.Validator.Severity
+import com.android.tools.idea.ui.validation.validators.PathValidator.Companion.createDefault
 import com.google.common.base.CharMatcher
 import com.intellij.openapi.application.Application
 import com.intellij.openapi.application.ApplicationNamesInfo
@@ -32,7 +33,6 @@
 import java.io.File
 import java.nio.file.Path
 import java.util.Locale
-import kotlin.streams.toList
 
 private val logger: Logger get() = logger<PathValidator>()
 
@@ -46,13 +46,15 @@
  */
 @Immutable
 class PathValidator
-/**
- * Constructs a class that will validate a path against the various passed in rules, returning
- * a readable message if something goes wrong. A name describing the purpose of the path should
- * be included as it will be used in the error messages when applicable.
- */ private constructor(private val pathName: String,
+    /**
+     * Constructs a class that will validate a path against the various passed in rules, returning
+     * a readable message if something goes wrong. A name describing the purpose of the path should
+     * be included as it will be used in the error messages when applicable.
+     */
+    private constructor(val pathName: String,
                         @get:TestOnly val errors: Iterable<Rule>,
                         private val warnings: Iterable<Rule>) : Validator<Path> {
+
   /**
    * Validate that the target location passes all tests.
    *
diff --git a/android/src/com/android/tools/idea/ui/validation/validators/StringPathValidator.kt b/android/src/com/android/tools/idea/ui/validation/validators/StringPathValidator.kt
new file mode 100644
index 0000000..12a3fb2
--- /dev/null
+++ b/android/src/com/android/tools/idea/ui/validation/validators/StringPathValidator.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.ui.validation.validators
+
+import com.android.tools.adtui.validation.Validator
+import java.nio.file.InvalidPathException
+import java.nio.file.Paths
+
+class StringPathValidator(private val pathValidator: PathValidator) : Validator<String> {
+
+  override fun validate(value: String): Validator.Result {
+    val path = try {
+      Paths.get(value)
+    }
+    catch (e: InvalidPathException) {
+      return Validator.Result(Validator.Severity.ERROR, "${pathValidator.pathName} in not a valid file system path")
+    }
+    return pathValidator.validate(path)
+  }
+}
\ No newline at end of file
diff --git a/android/src/com/android/tools/idea/welcome/install/InstallableComponent.kt b/android/src/com/android/tools/idea/welcome/install/InstallableComponent.kt
index 7fbab26..213a83b 100644
--- a/android/src/com/android/tools/idea/welcome/install/InstallableComponent.kt
+++ b/android/src/com/android/tools/idea/welcome/install/InstallableComponent.kt
@@ -25,6 +25,7 @@
 import com.android.tools.idea.welcome.wizard.getSizeLabel
 import com.android.tools.idea.wizard.dynamic.DynamicWizardStep
 import com.android.tools.idea.wizard.model.ModelWizardStep
+import com.intellij.openapi.diagnostic.thisLogger
 
 private val PROGRESS_LOGGER = StudioLoggerProgressIndicator(InstallableComponent::class.java)
 
@@ -111,8 +112,11 @@
         else -> isSelectedByDefault()
       }
     )
-    isInstalled = sdkHandler != null && packagesToInstall.isEmpty() && unavailablePackages.isEmpty()
-    isUnavailable = sdkHandler == null || unavailablePackages.isNotEmpty()
+    isInstalled = packagesToInstall.isEmpty() && unavailablePackages.isEmpty()
+    isUnavailable = unavailablePackages.isNotEmpty()
+    if (isUnavailable) {
+      thisLogger().warn("$name depends on the the packages that are not available: ${unavailablePackages.joinToString(", ")}")
+    }
   }
 
   override fun toggle(isSelected: Boolean) {
diff --git a/android/src/org/jetbrains/android/AndroidPlugin.java b/android/src/org/jetbrains/android/AndroidPlugin.java
index 8d8ba66..e3e4152 100644
--- a/android/src/org/jetbrains/android/AndroidPlugin.java
+++ b/android/src/org/jetbrains/android/AndroidPlugin.java
@@ -12,6 +12,7 @@
 import com.google.wireless.android.sdk.stats.AndroidStudioEvent;
 import com.intellij.ide.util.PropertiesComponent;
 import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.Anchor;
@@ -71,6 +72,11 @@
             Project project = e.getProject();
             e.getPresentation().setEnabledAndVisible(project != null && ProjectSystemUtil.requiresAndroidModel(project));
           }
+          @NotNull
+          @Override
+          public ActionUpdateThread getActionUpdateThread() {
+            return ActionUpdateThread.BGT;
+          }
         };
         actionManager.registerAction(groupId, group);
         ((DefaultActionGroup)parentGroup).add(group, new Constraints(Anchor.BEFORE, "Android.GenerateSignedApk"), actionManager);
diff --git a/android/src/org/jetbrains/android/actions/AndroidConnectDebuggerAction.java b/android/src/org/jetbrains/android/actions/AndroidConnectDebuggerAction.java
index 3579657..7faade6 100644
--- a/android/src/org/jetbrains/android/actions/AndroidConnectDebuggerAction.java
+++ b/android/src/org/jetbrains/android/actions/AndroidConnectDebuggerAction.java
@@ -5,6 +5,7 @@
 import com.android.tools.idea.IdeInfo;
 import com.android.tools.idea.execution.common.debug.utils.AndroidConnectDebugger;
 import com.intellij.facet.ProjectFacetManager;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.project.Project;
@@ -34,6 +35,12 @@
     }
   }
 
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
   @Override
   public void update(@NotNull AnActionEvent e) {
     final Project project = e.getProject();
diff --git a/android/src/org/jetbrains/android/actions/AndroidToolsActionGroup.java b/android/src/org/jetbrains/android/actions/AndroidToolsActionGroup.java
index 6ac2b67..6c08fcb 100644
--- a/android/src/org/jetbrains/android/actions/AndroidToolsActionGroup.java
+++ b/android/src/org/jetbrains/android/actions/AndroidToolsActionGroup.java
@@ -18,6 +18,7 @@
 import com.android.tools.idea.sdk.IdeSdks;
 import com.google.common.annotations.VisibleForTesting;
 import com.intellij.facet.ProjectFacetManager;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.CommonDataKeys;
 import com.intellij.openapi.actionSystem.DefaultActionGroup;
@@ -32,6 +33,12 @@
  * IDE users developing cross-platform applications (e.g. with react native) using android tools, e.g. AVD Manager.
  */
 public class AndroidToolsActionGroup extends DefaultActionGroup implements DumbAware {
+
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
   @Override
   public void update(@NotNull AnActionEvent e) {
     final Project project = e.getData(CommonDataKeys.PROJECT);
diff --git a/android/src/org/jetbrains/android/dom/inspections/MavenClassResolverUtils.kt b/android/src/org/jetbrains/android/dom/inspections/MavenClassResolverUtils.kt
index 3279737..ac86fe7 100644
--- a/android/src/org/jetbrains/android/dom/inspections/MavenClassResolverUtils.kt
+++ b/android/src/org/jetbrains/android/dom/inspections/MavenClassResolverUtils.kt
@@ -26,27 +26,21 @@
 import org.jetbrains.android.refactoring.isAndroidx
 
 /**
- * Returns a collection of [LocalQuickFix] by querying [MavenClassRegistryManager.getMavenClassRegistry].
+ * Returns a collection of [LocalQuickFix] by querying
+ * [MavenClassRegistryManager.getMavenClassRegistry].
  */
 internal fun MavenClassRegistryManager.collectFixesFromMavenClassRegistry(
-    className: String, project: Project, completionFileType: FileType?): List<LocalQuickFix> {
-  val fixes = mutableListOf<LocalQuickFix>()
+  className: String,
+  project: Project,
+  completionFileType: FileType?
+): List<LocalQuickFix> {
   val useAndroidX = project.isAndroidx()
 
-  this.getMavenClassRegistry()
-    .findLibraryData(className, useAndroidX, completionFileType)
-    .asSequence()
+  return getMavenClassRegistry()
+    .findLibraryData(className, null, useAndroidX, completionFileType)
     .map {
-      val resolvedArtifact = if (useAndroidX) {
-        AndroidxNameUtils.getCoordinateMapping(it.artifact)
-      }
-      else {
-        it.artifact
-      }
-
-      fixes.add(AndroidMavenImportFix(className, resolvedArtifact, it.version))
+      val resolvedArtifact =
+        if (useAndroidX) AndroidxNameUtils.getCoordinateMapping(it.artifact) else it.artifact
+      AndroidMavenImportFix(className, resolvedArtifact, it.version)
     }
-    .toList()
-
-  return fixes.toList()
 }
diff --git a/android/src/org/jetbrains/android/intentions/AndroidCreateOnClickHandlerAction.java b/android/src/org/jetbrains/android/intentions/AndroidCreateOnClickHandlerAction.java
index 7978107..0d47296 100644
--- a/android/src/org/jetbrains/android/intentions/AndroidCreateOnClickHandlerAction.java
+++ b/android/src/org/jetbrains/android/intentions/AndroidCreateOnClickHandlerAction.java
@@ -60,7 +60,6 @@
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.kotlin.asJava.classes.KtLightClass;
 import org.jetbrains.kotlin.idea.KotlinLanguage;
-import org.jetbrains.kotlin.idea.core.OldGenerateUtilKt;
 import org.jetbrains.kotlin.psi.KtClassOrObject;
 import org.jetbrains.kotlin.psi.KtDeclaration;
 import org.jetbrains.kotlin.psi.KtNamedFunction;
@@ -199,7 +198,7 @@
       KtNamedFunction namedFunction = new KtPsiFactory(origin.getProject())
         .createFunction("fun " + methodName + "(" + varName + ": " + methodParamType + ") {}");
       KtDeclaration anchor = Iterables.getLast(origin.getDeclarations(), null);
-      OldGenerateUtilKt.insertMembersAfterAndReformat(null, origin, namedFunction, anchor);
+      GenerateUtilsKt.insertMembersAfterAndReformat(null, origin, namedFunction, anchor);
     }
     return null;
   }
diff --git a/android/src/org/jetbrains/android/intentions/generateUtils.kt b/android/src/org/jetbrains/android/intentions/generateUtils.kt
new file mode 100644
index 0000000..04c6847
--- /dev/null
+++ b/android/src/org/jetbrains/android/intentions/generateUtils.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 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 org.jetbrains.android.intentions
+
+import com.intellij.openapi.application.runWriteAction
+import com.intellij.openapi.editor.Editor
+import com.intellij.psi.PsiElement
+import com.intellij.psi.codeStyle.CodeStyleManager
+import org.jetbrains.kotlin.idea.base.codeInsight.ShortenReferencesFacility
+import org.jetbrains.kotlin.idea.core.insertMembersAfter
+import org.jetbrains.kotlin.idea.core.moveCaretIntoGeneratedElement
+import org.jetbrains.kotlin.psi.KtClassOrObject
+import org.jetbrains.kotlin.psi.KtDeclaration
+
+internal fun <T : KtDeclaration> insertMembersAfterAndReformat(
+  editor: Editor?,
+  classOrObject: KtClassOrObject,
+  members: Collection<T>,
+  anchor: PsiElement? = null,
+  getAnchor: (KtDeclaration) -> PsiElement? = { null },
+): List<T> {
+  val codeStyleManager = CodeStyleManager.getInstance(classOrObject.project)
+  return runWriteAction {
+    val insertedMembersElementPointers = insertMembersAfter(editor, classOrObject, members, anchor, getAnchor)
+    val firstElement = insertedMembersElementPointers.firstOrNull() ?: return@runWriteAction emptyList()
+
+    fun insertedMembersElements() = insertedMembersElementPointers.mapNotNull { it.element }
+
+    for (added in insertedMembersElements()) {
+      ShortenReferencesFacility.getInstance().shorten(added)
+    }
+    if (editor != null) {
+      firstElement.element?.let { moveCaretIntoGeneratedElement(editor, it) }
+    }
+
+    insertedMembersElementPointers.onEach { it.element?.let { element -> codeStyleManager.reformat(element) } }
+    insertedMembersElements()
+  }
+}
+
+internal fun <T : KtDeclaration> insertMembersAfterAndReformat(
+  editor: Editor?,
+  classOrObject: KtClassOrObject,
+  declaration: T,
+  anchor: PsiElement? = null
+): T {
+  return insertMembersAfterAndReformat(editor, classOrObject, listOf(declaration), anchor).single()
+}
\ No newline at end of file
diff --git a/android/testSrc/com/android/tools/idea/databinding/index/BindingXmlIndexTest.kt b/android/testSrc/com/android/tools/idea/databinding/index/BindingXmlIndexTest.kt
index 8f7f241..a57b582 100644
--- a/android/testSrc/com/android/tools/idea/databinding/index/BindingXmlIndexTest.kt
+++ b/android/testSrc/com/android/tools/idea/databinding/index/BindingXmlIndexTest.kt
@@ -17,6 +17,7 @@
 
 import com.android.tools.idea.testing.AndroidProjectRule
 import com.google.common.truth.Truth.assertThat
+import com.intellij.openapi.application.runReadAction
 import com.intellij.openapi.command.WriteCommandAction
 import com.intellij.openapi.project.Project
 import com.intellij.openapi.util.TextRange
@@ -58,7 +59,7 @@
   @Test
   fun indexDataBindingLayout() {
     val file = fixture.configureByText("layout.xml", """
-      <layout>
+      <layout xmlns:android="http://schemas.android.com/apk/res/android">
         <data class="a.b.c.CustomBinding">
           <import type="C"/>
           <import type="Map&lt;D&gt;" alias="Dee" />
@@ -91,7 +92,7 @@
   fun indexDataBindingLayout_nullValue() {
     // regression for b/284046638
     val file = fixture.configureByText("layout.xml", """
-      <layout>
+      <layout xmlns:android="http://schemas.android.com/apk/res/android">
         <data class= >
         </data>
       </layout>
@@ -106,7 +107,7 @@
   @Test
   fun indexDataBindingLayout_emptyValue() {
     val file = fixture.configureByText("layout.xml", """
-      <layout>
+      <layout xmlns:android="http://schemas.android.com/apk/res/android">
         <data class="">
         </data>
       </layout>
@@ -567,6 +568,65 @@
     )
   }
 
+  @Test
+  fun nonLayoutFilesNotReturnedFromIndex() {
+    val layoutContents =
+      // language=XML
+      """
+      <layout xmlns:android="http://schemas.android.com/apk/res/android">
+        <LinearLayout
+          android:id="@+id/root_view"
+          android:orientation="vertical"
+          android:layout_width="fill_parent"
+          android:layout_height="fill_parent">
+        </LinearLayout>
+      </layout>
+      """.trimIndent()
+
+    val layoutPsiFile = fixture.addFileToProject("res/layout/some_layout.xml", layoutContents)
+    val otherPsiFile = fixture.addFileToProject("res/values/some_layout.xml", layoutContents)
+
+    runReadAction {
+      assertThat(BindingXmlIndex.getDataForFile(layoutPsiFile)).isNotNull()
+      assertThat(BindingXmlIndex.getDataForFile(otherPsiFile)).isNull()
+    }
+  }
+
+  @Test
+  fun xmlFileWithoutNamespaceNotIndexed() {
+    val unrelatedContent =
+      // language=XML
+      """
+      <abc>
+        <def>
+          <ghi />
+        </def>
+      </abc>
+      """.trimIndent()
+
+    // This file will be a false positive and will be indexed, even though it's not a layout file.
+    val unrelatedContentWithNamespace =
+      // language=XML
+      """
+      <abc xmlns:android="http://schemas.android.com/apk/res/android">
+        <def>
+          <ghi />
+        </def>
+      </abc>
+      """.trimIndent()
+
+    val unrelatedFile =
+      fixture.configureByText("layout/unrelated.xml", unrelatedContent).virtualFile
+    val unrelatedFileWithNamespace =
+      fixture.configureByText("layout/unrelatedWithNamespace.xml", unrelatedContentWithNamespace).virtualFile
+
+    val map1 = BindingXmlIndex().indexer.map(FileContentImpl.createByFile(unrelatedFile))
+    assertThat(map1).isEmpty()
+
+    val map2 = BindingXmlIndex().indexer.map(FileContentImpl.createByFile(unrelatedFileWithNamespace))
+    assertThat(map2).hasSize(1)
+  }
+
   /**
    * asserts all views with viewIds.
    * Pairs are variable name to view type
diff --git a/android/ui/testSrc/com/android/tools/idea/ui/validation/validators/StringPathValidatorTest.kt b/android/ui/testSrc/com/android/tools/idea/ui/validation/validators/StringPathValidatorTest.kt
new file mode 100644
index 0000000..339ab3d
--- /dev/null
+++ b/android/ui/testSrc/com/android/tools/idea/ui/validation/validators/StringPathValidatorTest.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.ui.validation.validators
+
+import com.android.tools.adtui.validation.Validator
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+
+class StringPathValidatorTest {
+
+  private val validator = StringPathValidator(PathValidator.createDefault("Test path"))
+
+  @Test
+  fun testValid() {
+    val result = validator.validate("${System.getProperty("java.io.tmpdir")}/valid/path")
+    assertThat(result.severity).isEqualTo(Validator.Severity.OK)
+  }
+
+  @Test
+  fun testInvalid() {
+    val result = validator.validate("${System.getProperty("java.io.tmpdir")}/path/with/illegal/character\u0000")
+    assertThat(result.severity).isEqualTo(Validator.Severity.ERROR)
+    assertThat(result.message).isEqualTo("Test path in not a valid file system path")
+  }
+}
\ No newline at end of file
diff --git a/apkanalyzer/src/com/android/tools/idea/apk/viewer/AnalyzeApkAction.java b/apkanalyzer/src/com/android/tools/idea/apk/viewer/AnalyzeApkAction.java
index 534bb97..d082b06 100644
--- a/apkanalyzer/src/com/android/tools/idea/apk/viewer/AnalyzeApkAction.java
+++ b/apkanalyzer/src/com/android/tools/idea/apk/viewer/AnalyzeApkAction.java
@@ -19,6 +19,7 @@
 import com.android.tools.idea.projectsystem.ProjectSystemUtil;
 import com.intellij.facet.ProjectFacetManager;
 import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.fileChooser.FileChooser;
@@ -56,6 +57,11 @@
   }
 
   @Override
+  public @NotNull ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
+  @Override
   public void actionPerformed(@NotNull AnActionEvent e) {
     Project project = e.getProject();
     if (project == null) {
diff --git a/app-inspection/api/src/com/android/tools/idea/appinspection/api/process/ProcessesModel.kt b/app-inspection/api/src/com/android/tools/idea/appinspection/api/process/ProcessesModel.kt
index 7ad2727..8f355ec 100644
--- a/app-inspection/api/src/com/android/tools/idea/appinspection/api/process/ProcessesModel.kt
+++ b/app-inspection/api/src/com/android/tools/idea/appinspection/api/process/ProcessesModel.kt
@@ -136,7 +136,7 @@
 
         synchronized(lock) {
           _processes.add(process)
-          if (isProcessPreferred(process) && !isProcessPreferred(selectedProcess)) {
+          if (isProcessPreferred(process)) {
             setSelectedProcess(process, autoConnected = true)
           }
         }
diff --git a/app-inspection/api/testSrc/com/android/tools/idea/appinspection/api/process/ProcessesModelTest.kt b/app-inspection/api/testSrc/com/android/tools/idea/appinspection/api/process/ProcessesModelTest.kt
index bf26b7d..ddb65c9 100644
--- a/app-inspection/api/testSrc/com/android/tools/idea/appinspection/api/process/ProcessesModelTest.kt
+++ b/app-inspection/api/testSrc/com/android/tools/idea/appinspection/api/process/ProcessesModelTest.kt
@@ -142,7 +142,7 @@
   }
 
   @Test
-  fun newProcessDoesNotCauseSelectionToChange() {
+  fun lastPreferredProcessIsSelected() {
     val testNotifier = TestProcessDiscovery()
     val model = ProcessesModel(testNotifier) { it.name in listOf("A", "B") }
 
@@ -152,9 +152,10 @@
 
     testNotifier.fireConnected(fakeProcessA)
     testNotifier.fireConnected(fakeProcessB)
+
     // Verify the added target.
     assertThat(model.processes.size).isEqualTo(2)
-    assertThat(model.selectedProcess!!).isSameAs(fakeProcessA)
+    assertThat(model.selectedProcess!!).isSameAs(fakeProcessB)
   }
 
   @Test
diff --git a/app-inspection/api/testSrc/com/android/tools/idea/appinspection/test/AppInspectionServiceRule.kt b/app-inspection/api/testSrc/com/android/tools/idea/appinspection/test/AppInspectionServiceRule.kt
index 8a285a8..27055f7 100644
--- a/app-inspection/api/testSrc/com/android/tools/idea/appinspection/test/AppInspectionServiceRule.kt
+++ b/app-inspection/api/testSrc/com/android/tools/idea/appinspection/test/AppInspectionServiceRule.kt
@@ -105,14 +105,10 @@
   override fun before(description: Description) {
     client = TransportClient(grpcServer.name)
     executorService = Executors.newSingleThreadExecutor()
-    streamManager =
-      TransportStreamManager.createManager(
-        client.transportStub,
-        executorService.asCoroutineDispatcher()
-      )
     streamChannel =
       TransportStreamChannel(stream, client.transportStub, executorService.asCoroutineDispatcher())
     scope = CoroutineScope(executorService.asCoroutineDispatcher() + SupervisorJob())
+    streamManager = TransportStreamManager(client.transportStub, scope)
     transport = AppInspectionTransport(client, process, streamChannel)
     jarCopier = AppInspectionTestUtils.TestTransportJarCopier
     targetManager = AppInspectionTargetManager(client, scope)
@@ -130,7 +126,6 @@
   }
 
   override fun after(description: Description) = runBlocking {
-    TransportStreamManager.unregisterManager(streamManager)
     scope.coroutineContext[Job]!!.cancelAndJoin()
     executorService.shutdownNow()
     timer.currentTimeNs += 1
diff --git a/app-inspection/ide/src/com/android/tools/idea/appinspection/ide/AppInspectionDiscoveryService.kt b/app-inspection/ide/src/com/android/tools/idea/appinspection/ide/AppInspectionDiscoveryService.kt
index 5fdd707..3cb0274 100644
--- a/app-inspection/ide/src/com/android/tools/idea/appinspection/ide/AppInspectionDiscoveryService.kt
+++ b/app-inspection/ide/src/com/android/tools/idea/appinspection/ide/AppInspectionDiscoveryService.kt
@@ -23,14 +23,13 @@
 import com.android.tools.idea.appinspection.inspector.api.AppInspectorJar
 import com.android.tools.idea.appinspection.inspector.api.process.DeviceDescriptor
 import com.android.tools.idea.concurrency.AndroidCoroutineScope
-import com.android.tools.idea.concurrency.AndroidDispatchers
 import com.android.tools.idea.concurrency.AndroidExecutors
 import com.android.tools.idea.transport.DeployableFile
 import com.android.tools.idea.transport.TransportClient
 import com.android.tools.idea.transport.TransportFileManager
 import com.android.tools.idea.transport.TransportService
 import com.android.tools.idea.transport.TransportServiceProxy
-import com.android.tools.idea.transport.manager.TransportStreamManager
+import com.android.tools.idea.transport.manager.TransportStreamManagerService
 import com.google.common.util.concurrent.MoreExecutors
 import com.intellij.openapi.Disposable
 import com.intellij.openapi.application.ApplicationManager
@@ -57,8 +56,7 @@
   }
 
   private val client = TransportClient(TransportService.channelName)
-  private val streamManager =
-    TransportStreamManager.createManager(client.transportStub, AndroidDispatchers.workerThread)
+  private val streamManager = service<TransportStreamManagerService>().streamManager
 
   private val applicationMessageBus = ApplicationManager.getApplication().messageBus.connect(this)
 
@@ -113,9 +111,7 @@
       get() = service()
   }
 
-  override fun dispose() {
-    TransportStreamManager.unregisterManager(streamManager)
-  }
+  override fun dispose() = Unit
 
   /**
    * This uses the current [AndroidDebugBridge] to locate a device described by [device]. Return
diff --git a/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/NetworkInspectorDataSeriesTest.kt b/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/NetworkInspectorDataSeriesTest.kt
index 13a9813..a3babe2 100644
--- a/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/NetworkInspectorDataSeriesTest.kt
+++ b/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/NetworkInspectorDataSeriesTest.kt
@@ -19,15 +19,12 @@
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import studio.network.inspection.NetworkInspectorProtocol.Event
-import studio.network.inspection.NetworkInspectorProtocol.SpeedEvent
 
 class NetworkInspectorDataSeriesTest {
   @Test
   fun getDataForRange() {
-    val event1 =
-      Event.newBuilder().setTimestamp(1000).setSpeedEvent(SpeedEvent.getDefaultInstance()).build()
-    val event2 =
-      Event.newBuilder().setTimestamp(2000).setSpeedEvent(SpeedEvent.getDefaultInstance()).build()
+    val event1 = speedEvent(timestampNanos = 1000)
+    val event2 = speedEvent(timestampNanos = 2000)
     val source = FakeNetworkInspectorDataSource(speedEventList = listOf(event1, event2))
 
     val foundEvents = mutableListOf<Event>()
diff --git a/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/NetworkInspectorDataSourceTest.kt b/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/NetworkInspectorDataSourceTest.kt
index 3445100..1b6e272 100644
--- a/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/NetworkInspectorDataSourceTest.kt
+++ b/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/NetworkInspectorDataSourceTest.kt
@@ -26,14 +26,10 @@
 import kotlinx.coroutines.SupervisorJob
 import kotlinx.coroutines.asCoroutineDispatcher
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.runBlocking
 import org.junit.Test
-import studio.network.inspection.NetworkInspectorProtocol.Event
-import studio.network.inspection.NetworkInspectorProtocol.HttpConnectionEvent
-import studio.network.inspection.NetworkInspectorProtocol.SpeedEvent
 
 class NetworkInspectorDataSourceTest {
   private val executor = Executors.newSingleThreadExecutor()
@@ -41,26 +37,8 @@
 
   @Test
   fun basicSearch() = runBlocking {
-    val speedEvent =
-      Event.newBuilder()
-        .setTimestamp(1000)
-        .setSpeedEvent(SpeedEvent.newBuilder().setRxSpeed(10).setTxSpeed(20))
-        .build()
-    val httpEvent =
-      Event.newBuilder()
-        .setTimestamp(1002)
-        .setHttpConnectionEvent(
-          HttpConnectionEvent.newBuilder()
-            .setConnectionId(1)
-            .setHttpRequestStarted(
-              HttpConnectionEvent.RequestStarted.newBuilder()
-                .setFields("a")
-                .setMethod("http")
-                .setTrace("abc")
-                .setUrl("www.google.com")
-            )
-        )
-        .build()
+    val speedEvent = speedEvent(timestampNanos = 1000, rxSpeed = 10, txSpeed = 20)
+    val httpEvent = requestStarted(id = 1, timestampNanos = 1002)
     val testMessenger =
       TestMessenger(scope, flowOf(speedEvent.toByteArray(), httpEvent.toByteArray()))
     val dataSource = NetworkInspectorDataSourceImpl(testMessenger, scope)
@@ -77,22 +55,14 @@
 
   @Test
   fun advancedSearch(): Unit = runBlocking {
-    val speedEvent1 =
-      Event.newBuilder().setTimestamp(1000).setSpeedEvent(SpeedEvent.getDefaultInstance()).build()
-    val speedEvent2 =
-      Event.newBuilder().setTimestamp(2000).setSpeedEvent(SpeedEvent.getDefaultInstance()).build()
-    val speedEvent3 =
-      Event.newBuilder().setTimestamp(2000).setSpeedEvent(SpeedEvent.getDefaultInstance()).build()
-    val speedEvent4 =
-      Event.newBuilder().setTimestamp(3000).setSpeedEvent(SpeedEvent.getDefaultInstance()).build()
-    val speedEvent5 =
-      Event.newBuilder().setTimestamp(3000).setSpeedEvent(SpeedEvent.getDefaultInstance()).build()
-    val speedEvent6 =
-      Event.newBuilder().setTimestamp(3000).setSpeedEvent(SpeedEvent.getDefaultInstance()).build()
-    val speedEvent7 =
-      Event.newBuilder().setTimestamp(3001).setSpeedEvent(SpeedEvent.getDefaultInstance()).build()
-    val speedEvent8 =
-      Event.newBuilder().setTimestamp(6000).setSpeedEvent(SpeedEvent.getDefaultInstance()).build()
+    val speedEvent1 = speedEvent(timestampNanos = 1000)
+    val speedEvent2 = speedEvent(timestampNanos = 2000)
+    val speedEvent3 = speedEvent(timestampNanos = 2000)
+    val speedEvent4 = speedEvent(timestampNanos = 3000)
+    val speedEvent5 = speedEvent(timestampNanos = 3000)
+    val speedEvent6 = speedEvent(timestampNanos = 3000)
+    val speedEvent7 = speedEvent(timestampNanos = 3001)
+    val speedEvent8 = speedEvent(timestampNanos = 6000)
 
     val testMessenger =
       TestMessenger(
@@ -162,108 +132,20 @@
   @Test
   fun searchHttpData(): Unit = runBlocking {
     // Request that starts in the selection range but ends outside of it.
-    val httpEvent =
-      Event.newBuilder()
-        .setTimestamp(1002)
-        .setHttpConnectionEvent(
-          HttpConnectionEvent.newBuilder()
-            .setConnectionId(1)
-            .setHttpRequestStarted(
-              HttpConnectionEvent.RequestStarted.newBuilder()
-                .setFields("a")
-                .setMethod("http")
-                .setTrace("abc")
-                .setUrl("www.google.com")
-            )
-        )
-        .build()
-    val httpEvent2 =
-      Event.newBuilder()
-        .setTimestamp(3000)
-        .setHttpConnectionEvent(
-          HttpConnectionEvent.newBuilder()
-            .setConnectionId(1)
-            .setHttpRequestCompleted(HttpConnectionEvent.RequestCompleted.getDefaultInstance())
-        )
-        .build()
+    val httpEvent = requestStarted(id = 1, timestampNanos = 1002)
+    val httpEvent2 = requestCompleted(id = 1, timestampNanos = 3000)
 
-    // Request that starts outside of the range, but ends inside of it.
-    val httpEvent3 =
-      Event.newBuilder()
-        .setTimestamp(44)
-        .setHttpConnectionEvent(
-          HttpConnectionEvent.newBuilder()
-            .setConnectionId(2)
-            .setHttpRequestStarted(
-              HttpConnectionEvent.RequestStarted.newBuilder()
-                .setFields("a")
-                .setMethod("http")
-                .setTrace("abc")
-                .setUrl("www.google.com")
-            )
-        )
-        .build()
-    val httpEvent4 =
-      Event.newBuilder()
-        .setTimestamp(1534)
-        .setHttpConnectionEvent(
-          HttpConnectionEvent.newBuilder()
-            .setConnectionId(2)
-            .setHttpRequestCompleted(HttpConnectionEvent.RequestCompleted.getDefaultInstance())
-        )
-        .build()
+    // Request that starts outside the range, but ends inside of it.
+    val httpEvent3 = requestStarted(id = 2, timestampNanos = 44)
+    val httpEvent4 = requestCompleted(id = 2, timestampNanos = 1534)
 
     // Request that starts and ends outside the range, but spans over it.
-    val httpEvent5 =
-      Event.newBuilder()
-        .setTimestamp(55)
-        .setHttpConnectionEvent(
-          HttpConnectionEvent.newBuilder()
-            .setConnectionId(3)
-            .setHttpRequestStarted(
-              HttpConnectionEvent.RequestStarted.newBuilder()
-                .setFields("a")
-                .setMethod("http")
-                .setTrace("abc")
-                .setUrl("www.google.com")
-            )
-        )
-        .build()
-    val httpEvent6 =
-      Event.newBuilder()
-        .setTimestamp(4500)
-        .setHttpConnectionEvent(
-          HttpConnectionEvent.newBuilder()
-            .setConnectionId(3)
-            .setHttpRequestCompleted(HttpConnectionEvent.RequestCompleted.getDefaultInstance())
-        )
-        .build()
+    val httpEvent5 = requestStarted(id = 3, timestampNanos = 55)
+    val httpEvent6 = requestCompleted(id = 3, timestampNanos = 4500)
 
     // Request that starts and ends outside and not overlap the range.
-    val httpEvent7 =
-      Event.newBuilder()
-        .setTimestamp(58)
-        .setHttpConnectionEvent(
-          HttpConnectionEvent.newBuilder()
-            .setConnectionId(4)
-            .setHttpRequestStarted(
-              HttpConnectionEvent.RequestStarted.newBuilder()
-                .setFields("a")
-                .setMethod("http")
-                .setTrace("abc")
-                .setUrl("www.google.com")
-            )
-        )
-        .build()
-    val httpEvent8 =
-      Event.newBuilder()
-        .setTimestamp(67)
-        .setHttpConnectionEvent(
-          HttpConnectionEvent.newBuilder()
-            .setConnectionId(4)
-            .setHttpRequestCompleted(HttpConnectionEvent.RequestCompleted.getDefaultInstance())
-        )
-        .build()
+    val httpEvent7 = requestStarted(id = 4, timestampNanos = 58)
+    val httpEvent8 = requestCompleted(id = 4, timestampNanos = 67)
 
     val testMessenger =
       TestMessenger(
@@ -288,24 +170,23 @@
   }
 
   @Test
-  fun cleanUpChannelOnDispose() =
-    runBlocking<Unit> {
-      val testMessenger =
-        TestMessenger(scope, flow { throw ArithmeticException("Something went wrong!") })
-      val dataSource = NetworkInspectorDataSourceImpl(testMessenger, scope)
-      testMessenger.await()
-      try {
-        dataSource.queryForSpeedData(Range(0.0, 5.0))
-        fail()
-      } catch (e: Throwable) {
-        assertThat(e).isInstanceOf(CancellationException::class.java)
-        var cause: Throwable? = e.cause
-        while (cause != null && cause !is ArithmeticException) {
-          cause = cause.cause
-        }
-        assertThat(cause).isInstanceOf(ArithmeticException::class.java)
+  fun cleanUpChannelOnDispose() = runBlocking {
+    val testMessenger =
+      TestMessenger(scope, flow { throw ArithmeticException("Something went wrong!") })
+    val dataSource = NetworkInspectorDataSourceImpl(testMessenger, scope)
+    testMessenger.await()
+    try {
+      dataSource.queryForSpeedData(Range(0.0, 5.0))
+      fail()
+    } catch (e: Throwable) {
+      assertThat(e).isInstanceOf(CancellationException::class.java)
+      var cause: Throwable? = e.cause
+      while (cause != null && cause !is ArithmeticException) {
+        cause = cause.cause
       }
+      assertThat(cause).isInstanceOf(ArithmeticException::class.java)
     }
+  }
 }
 
 private class TestMessenger(override val scope: CoroutineScope, val flow: Flow<ByteArray>) :
diff --git a/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/NetworkInspectorModelTest.kt b/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/NetworkInspectorModelTest.kt
index cecb3d6..4b3650f 100644
--- a/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/NetworkInspectorModelTest.kt
+++ b/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/NetworkInspectorModelTest.kt
@@ -24,13 +24,11 @@
 import com.android.tools.idea.protobuf.ByteString
 import com.google.common.truth.Truth.assertThat
 import com.google.common.util.concurrent.MoreExecutors
-import java.util.concurrent.TimeUnit
+import java.util.concurrent.TimeUnit.SECONDS
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.asCoroutineDispatcher
 import org.junit.Before
 import org.junit.Test
-import studio.network.inspection.NetworkInspectorProtocol.Event
-import studio.network.inspection.NetworkInspectorProtocol.SpeedEvent
 
 class NetworkInspectorModelTest {
   private lateinit var model: NetworkInspectorModel
@@ -46,35 +44,13 @@
         FakeNetworkInspectorDataSource(
           speedEventList =
             listOf(
-              Event.newBuilder()
-                .apply {
-                  timestamp = 0
-                  speedEvent =
-                    SpeedEvent.newBuilder()
-                      .apply {
-                        rxSpeed = 1
-                        txSpeed = 2
-                      }
-                      .build()
-                }
-                .build(),
-              Event.newBuilder()
-                .apply {
-                  timestamp = TimeUnit.SECONDS.toNanos(10)
-                  speedEvent =
-                    SpeedEvent.newBuilder()
-                      .apply {
-                        rxSpeed = 3
-                        txSpeed = 4
-                      }
-                      .build()
-                }
-                .build()
+              speedEvent(timestampNanos = 0, rxSpeed = 1, txSpeed = 2),
+              speedEvent(timestampNanos = SECONDS.toNanos(10), rxSpeed = 3, txSpeed = 4),
             )
         ),
         CoroutineScope(MoreExecutors.directExecutor().asCoroutineDispatcher())
       )
-    model.timeline.viewRange.set(0.0, TimeUnit.SECONDS.toMicros(5).toDouble())
+    model.timeline.viewRange.set(0.0, SECONDS.toMicros(5).toDouble())
   }
 
   @Test
@@ -99,7 +75,7 @@
     model.tooltip = (NetworkTrafficTooltipModel(model))
     assertThat(model.tooltip).isInstanceOf(NetworkTrafficTooltipModel::class.java)
     val tooltip = model.tooltip as NetworkTrafficTooltipModel
-    val tooltipTime = TimeUnit.SECONDS.toMicros(10).toDouble()
+    val tooltipTime = SECONDS.toMicros(10).toDouble()
     model.timeline.tooltipRange.set(tooltipTime, tooltipTime)
     val networkLegends = tooltip.getLegends()
     assertThat(networkLegends.rxLegend.name).isEqualTo("Received")
@@ -119,10 +95,10 @@
     assertThat(sending.name).isEqualTo("Sending")
     assertThat(receiving.series).hasSize(1)
     assertThat(receiving.series[0].x).isEqualTo(0)
-    assertThat(receiving.series[0].value.toLong()).isEqualTo(1)
+    assertThat(receiving.series[0].value).isEqualTo(1)
     assertThat(sending.series).hasSize(1)
     assertThat(sending.series[0].x).isEqualTo(0)
-    assertThat(sending.series[0].value.toLong()).isEqualTo(2)
+    assertThat(sending.series[0].value).isEqualTo(2)
   }
 
   @Test
@@ -151,24 +127,18 @@
     assertThat(legendsUpdated).isFalse()
     assertThat(tooltipLegendsUpdated).isFalse()
 
-    model.timeline.viewRange.set(
-      TimeUnit.SECONDS.toMicros(1).toDouble(),
-      TimeUnit.SECONDS.toMicros(2).toDouble()
-    )
+    model.timeline.viewRange.set(SECONDS.toMicros(1).toDouble(), SECONDS.toMicros(2).toDouble())
     assertThat(networkUsageUpdated).isTrue()
 
     // Make sure the axis lerps correctly when we move the range there.
-    model.timeline.dataRange.max = TimeUnit.SECONDS.toMicros(101).toDouble()
-    model.timeline.viewRange.set(
-      TimeUnit.SECONDS.toMicros(99).toDouble(),
-      TimeUnit.SECONDS.toMicros(101).toDouble()
-    )
+    model.timeline.dataRange.max = SECONDS.toMicros(101).toDouble()
+    model.timeline.viewRange.set(SECONDS.toMicros(99).toDouble(), SECONDS.toMicros(101).toDouble())
     timer.tick(100)
     assertThat(legendsUpdated).isTrue()
     assertThat(trafficAxisUpdated).isTrue()
     model.timeline.tooltipRange.set(
-      TimeUnit.SECONDS.toMicros(100).toDouble(),
-      TimeUnit.SECONDS.toMicros(100).toDouble()
+      SECONDS.toMicros(100).toDouble(),
+      SECONDS.toMicros(100).toDouble()
     )
     assertThat(tooltipLegendsUpdated).isTrue()
   }
diff --git a/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/ProtoBuilder.kt b/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/ProtoBuilder.kt
new file mode 100644
index 0000000..8baae97
--- /dev/null
+++ b/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/ProtoBuilder.kt
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.appinspection.inspectors.network.model
+
+import com.android.tools.idea.protobuf.ByteString
+import studio.network.inspection.NetworkInspectorProtocol
+import studio.network.inspection.NetworkInspectorProtocol.HttpConnectionEvent
+import studio.network.inspection.NetworkInspectorProtocol.HttpConnectionEvent.Closed
+import studio.network.inspection.NetworkInspectorProtocol.HttpConnectionEvent.Payload
+import studio.network.inspection.NetworkInspectorProtocol.HttpConnectionEvent.RequestCompleted
+import studio.network.inspection.NetworkInspectorProtocol.HttpConnectionEvent.RequestStarted
+import studio.network.inspection.NetworkInspectorProtocol.HttpConnectionEvent.ResponseCompleted
+import studio.network.inspection.NetworkInspectorProtocol.HttpConnectionEvent.ResponseStarted
+import studio.network.inspection.NetworkInspectorProtocol.SpeedEvent
+
+@Suppress("SameParameterValue")
+internal fun requestStarted(
+  id: Long,
+  timestampNanos: Long,
+  url: String = "www.url.com",
+  method: String = "GET",
+  fields: String = "",
+  trace: String = "trace",
+) =
+  httpConnectionEvent(id, timestampNanos) {
+      setHttpRequestStarted(
+        RequestStarted.newBuilder().setUrl(url).setMethod(method).setTrace(trace).setFields(fields)
+      )
+    }
+    .build()
+
+@Suppress("SameParameterValue")
+internal fun requestPayload(id: Long, timestampNanos: Long, payload: String) =
+  httpConnectionEvent(id, timestampNanos) {
+      setRequestPayload(Payload.newBuilder().setPayload(ByteString.copyFromUtf8(payload)))
+    }
+    .build()
+
+@Suppress("SameParameterValue")
+internal fun requestCompleted(id: Long, timestampNanos: Long) =
+  httpConnectionEvent(id, timestampNanos) { setHttpRequestCompleted(RequestCompleted.newBuilder()) }
+    .build()
+
+@Suppress("SameParameterValue")
+internal fun responseStarted(id: Long, timestampNanos: Long, fields: String) =
+  httpConnectionEvent(id, timestampNanos) {
+      setHttpResponseStarted(ResponseStarted.newBuilder().setFields(fields))
+    }
+    .build()
+
+@Suppress("SameParameterValue")
+internal fun responsePayload(id: Long, timestampNanos: Long, payload: String) =
+  httpConnectionEvent(id, timestampNanos) {
+      setResponsePayload(Payload.newBuilder().setPayload(ByteString.copyFromUtf8(payload)))
+    }
+    .build()
+
+@Suppress("SameParameterValue")
+internal fun responseCompleted(id: Long, timestampNanos: Long) =
+  httpConnectionEvent(id, timestampNanos) {
+      setHttpResponseCompleted(ResponseCompleted.newBuilder())
+    }
+    .build()
+
+@Suppress("SameParameterValue")
+internal fun httpClosed(id: Long, timestamp: Long, completed: Boolean) =
+  httpConnectionEvent(id, timestamp) { setHttpClosed(Closed.newBuilder().setCompleted(completed)) }
+    .build()
+
+@Suppress("SameParameterValue")
+internal fun httpThread(id: Long, timestampNanos: Long, threadId: Long, threadName: String) =
+  httpConnectionEvent(id, timestampNanos) {
+      setHttpThread(
+        HttpConnectionEvent.ThreadData.newBuilder().setThreadId(threadId).setThreadName(threadName)
+      )
+    }
+    .build()
+
+internal fun speedEvent(timestampNanos: Long, rxSpeed: Long = 0, txSpeed: Long = 0) =
+  NetworkInspectorProtocol.Event.newBuilder()
+    .setTimestamp(timestampNanos)
+    .setSpeedEvent(SpeedEvent.newBuilder().setRxSpeed(rxSpeed).setTxSpeed(txSpeed))
+    .build()
+
+private fun httpConnectionEvent(
+  id: Long,
+  timestampNanos: Long,
+  block: HttpConnectionEvent.Builder.() -> HttpConnectionEvent.Builder
+) =
+  NetworkInspectorProtocol.Event.newBuilder()
+    .setTimestamp(timestampNanos)
+    .setHttpConnectionEvent(HttpConnectionEvent.newBuilder().setConnectionId(id).block())
diff --git a/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/httpdata/HttpDataModelTest.kt b/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/httpdata/HttpDataModelTest.kt
index fd2e374..4dcc2f8 100644
--- a/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/httpdata/HttpDataModelTest.kt
+++ b/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/httpdata/HttpDataModelTest.kt
@@ -18,138 +18,76 @@
 import com.android.tools.adtui.model.Range
 import com.android.tools.idea.appinspection.inspectors.network.model.FakeNetworkInspectorDataSource
 import com.android.tools.idea.appinspection.inspectors.network.model.analytics.StubNetworkInspectorTracker
+import com.android.tools.idea.appinspection.inspectors.network.model.httpClosed
+import com.android.tools.idea.appinspection.inspectors.network.model.httpThread
+import com.android.tools.idea.appinspection.inspectors.network.model.requestCompleted
+import com.android.tools.idea.appinspection.inspectors.network.model.requestPayload
+import com.android.tools.idea.appinspection.inspectors.network.model.requestStarted
+import com.android.tools.idea.appinspection.inspectors.network.model.responseCompleted
+import com.android.tools.idea.appinspection.inspectors.network.model.responsePayload
+import com.android.tools.idea.appinspection.inspectors.network.model.responseStarted
 import com.android.tools.idea.protobuf.ByteString
 import com.google.common.truth.Truth.assertThat
 import com.google.common.util.concurrent.MoreExecutors
-import java.util.concurrent.TimeUnit
+import java.util.concurrent.TimeUnit.SECONDS
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.asCoroutineDispatcher
 import org.junit.Test
-import studio.network.inspection.NetworkInspectorProtocol.Event
-import studio.network.inspection.NetworkInspectorProtocol.HttpConnectionEvent
 
 private const val CONNECTION_ID = 1L
+private val fakeUrl = fakeUrl(CONNECTION_ID)
+private val faceTrace = fakeStackTrace(CONNECTION_ID)
 
 private val HTTP_DATA =
   listOf(
-    Event.newBuilder()
-      .apply {
-        timestamp = TimeUnit.SECONDS.toNanos(0)
-        httpConnectionEvent =
-          HttpConnectionEvent.newBuilder()
-            .apply {
-              connectionId = CONNECTION_ID
-              httpRequestStarted =
-                HttpConnectionEvent.RequestStarted.newBuilder()
-                  .apply {
-                    url = fakeUrl(CONNECTION_ID)
-                    method = ""
-                    trace = fakeStackTrace(1)
-                    fields = ""
-                  }
-                  .build()
-            }
-            .build()
-      }
-      .build(),
-    Event.newBuilder()
-      .apply {
-        timestamp = TimeUnit.SECONDS.toNanos(1)
-        httpConnectionEvent =
-          HttpConnectionEvent.newBuilder()
-            .apply {
-              connectionId = CONNECTION_ID
-              requestPayload =
-                HttpConnectionEvent.Payload.newBuilder()
-                  .apply { payload = ByteString.copyFromUtf8("REQUEST_CONTENT") }
-                  .build()
-            }
-            .build()
-      }
-      .build(),
-    Event.newBuilder()
-      .apply {
-        timestamp = TimeUnit.SECONDS.toNanos(1)
-        httpConnectionEvent =
-          HttpConnectionEvent.newBuilder()
-            .apply {
-              connectionId = CONNECTION_ID
-              httpRequestCompleted = HttpConnectionEvent.RequestCompleted.getDefaultInstance()
-            }
-            .build()
-      }
-      .build(),
-    Event.newBuilder()
-      .apply {
-        timestamp = TimeUnit.SECONDS.toNanos(2)
-        httpConnectionEvent =
-          HttpConnectionEvent.newBuilder()
-            .apply {
-              connectionId = CONNECTION_ID
-              httpResponseStarted =
-                HttpConnectionEvent.ResponseStarted.newBuilder()
-                  .apply { fields = fakeResponseFields(CONNECTION_ID) }
-                  .build()
-            }
-            .build()
-      }
-      .build(),
-    Event.newBuilder()
-      .apply {
-        timestamp = TimeUnit.SECONDS.toNanos(3)
-        httpConnectionEvent =
-          HttpConnectionEvent.newBuilder()
-            .apply {
-              connectionId = CONNECTION_ID
-              responsePayload =
-                HttpConnectionEvent.Payload.newBuilder()
-                  .apply { payload = ByteString.copyFromUtf8("RESPONSE_CONTENT") }
-                  .build()
-            }
-            .build()
-      }
-      .build(),
-    Event.newBuilder()
-      .apply {
-        timestamp = TimeUnit.SECONDS.toNanos(3)
-        httpConnectionEvent =
-          HttpConnectionEvent.newBuilder()
-            .apply {
-              connectionId = CONNECTION_ID
-              httpResponseCompleted = HttpConnectionEvent.ResponseCompleted.getDefaultInstance()
-            }
-            .build()
-      }
-      .build(),
-    Event.newBuilder()
-      .apply {
-        timestamp = TimeUnit.SECONDS.toNanos(3)
-        httpConnectionEvent =
-          HttpConnectionEvent.newBuilder()
-            .apply {
-              connectionId = CONNECTION_ID
-              httpClosed =
-                HttpConnectionEvent.Closed.newBuilder().apply { completed = true }.build()
-            }
-            .build()
-      }
-      .build()
+    requestStarted(
+      CONNECTION_ID,
+      timestampNanos = SECONDS.toNanos(0),
+      url = fakeUrl,
+      method = "",
+      trace = faceTrace
+    ),
+    requestPayload(CONNECTION_ID, timestampNanos = SECONDS.toNanos(1), payload = "REQUEST_CONTENT"),
+    requestCompleted(CONNECTION_ID, timestampNanos = SECONDS.toNanos(1)),
+    responseStarted(
+      CONNECTION_ID,
+      timestampNanos = SECONDS.toNanos(2),
+      fields = fakeResponseFields(CONNECTION_ID)
+    ),
+    responsePayload(
+      CONNECTION_ID,
+      timestampNanos = SECONDS.toNanos(3),
+      payload = "RESPONSE_CONTENT"
+    ),
+    responseCompleted(CONNECTION_ID, timestampNanos = SECONDS.toNanos(3)),
+    httpClosed(CONNECTION_ID, timestamp = SECONDS.toNanos(3), completed = true),
   )
 
 private val HTTP_DATA_WITH_THREAD =
-  HTTP_DATA +
-    listOf(
-      Event.newBuilder()
-        .setTimestamp(TimeUnit.SECONDS.toNanos(4))
-        .setHttpConnectionEvent(
-          HttpConnectionEvent.newBuilder()
-            .setConnectionId(CONNECTION_ID)
-            .setHttpThread(
-              HttpConnectionEvent.ThreadData.newBuilder().setThreadId(1).setThreadName("thread")
-            )
-        )
-        .build()
-    )
+  listOf(
+    requestStarted(
+      CONNECTION_ID,
+      timestampNanos = SECONDS.toNanos(0),
+      url = fakeUrl,
+      method = "",
+      trace = faceTrace
+    ),
+    requestPayload(CONNECTION_ID, timestampNanos = SECONDS.toNanos(1), payload = "REQUEST_CONTENT"),
+    requestCompleted(CONNECTION_ID, timestampNanos = SECONDS.toNanos(1)),
+    responseStarted(
+      CONNECTION_ID,
+      timestampNanos = SECONDS.toNanos(2),
+      fields = fakeResponseFields(CONNECTION_ID)
+    ),
+    responsePayload(
+      CONNECTION_ID,
+      timestampNanos = SECONDS.toNanos(3),
+      payload = "RESPONSE_CONTENT"
+    ),
+    responseCompleted(CONNECTION_ID, timestampNanos = SECONDS.toNanos(3)),
+    httpClosed(CONNECTION_ID, timestamp = SECONDS.toNanos(3), completed = true),
+    httpThread(CONNECTION_ID, timestampNanos = SECONDS.toNanos(4), 1, "thread"),
+  )
 
 class HttpDataModelTest {
 
@@ -158,7 +96,7 @@
     val source = FakeNetworkInspectorDataSource(httpEventList = HTTP_DATA_WITH_THREAD)
     val scope = CoroutineScope(MoreExecutors.directExecutor().asCoroutineDispatcher())
     val model = HttpDataModelImpl(source, StubNetworkInspectorTracker(), scope)
-    val httpDataList = model.getData(Range(0.0, TimeUnit.SECONDS.toMicros(5).toDouble()))
+    val httpDataList = model.getData(Range(0.0, SECONDS.toMicros(5).toDouble()))
     assertThat(httpDataList).hasSize(1)
     val httpData = httpDataList[0]
 
@@ -168,8 +106,8 @@
     assertThat(httpData.responseCompleteTimeUs).isEqualTo(3000000)
     assertThat(httpData.connectionEndTimeUs).isEqualTo(3000000)
     assertThat(httpData.method).isEmpty()
-    assertThat(httpData.url).isEqualTo(fakeUrl(CONNECTION_ID))
-    assertThat(httpData.trace).isEqualTo(fakeStackTrace(CONNECTION_ID))
+    assertThat(httpData.url).isEqualTo(fakeUrl)
+    assertThat(httpData.trace).isEqualTo(faceTrace)
     assertThat(httpData.requestPayload).isEqualTo(ByteString.copyFromUtf8("REQUEST_CONTENT"))
     assertThat(httpData.responsePayload).isEqualTo(ByteString.copyFromUtf8("RESPONSE_CONTENT"))
     assertThat(httpData.responseHeader.getField("connId")).isEqualTo("1")
@@ -180,7 +118,7 @@
     val source = FakeNetworkInspectorDataSource(httpEventList = HTTP_DATA)
     val scope = CoroutineScope(MoreExecutors.directExecutor().asCoroutineDispatcher())
     val model = HttpDataModelImpl(source, StubNetworkInspectorTracker(), scope)
-    val httpDataList = model.getData(Range(0.0, TimeUnit.SECONDS.toMicros(5).toDouble()))
+    val httpDataList = model.getData(Range(0.0, SECONDS.toMicros(5).toDouble()))
     assertThat(httpDataList).isEmpty()
   }
 }
diff --git a/app-quality-insights/api/testSrc/com/android/tools/idea/insights/AppInsightsProjectLevelControllerRule.kt b/app-quality-insights/api/testSrc/com/android/tools/idea/insights/AppInsightsProjectLevelControllerRule.kt
index bdc682a..ee116cb 100644
--- a/app-quality-insights/api/testSrc/com/android/tools/idea/insights/AppInsightsProjectLevelControllerRule.kt
+++ b/app-quality-insights/api/testSrc/com/android/tools/idea/insights/AppInsightsProjectLevelControllerRule.kt
@@ -28,12 +28,14 @@
 import com.android.tools.idea.insights.client.IssueRequest
 import com.android.tools.idea.insights.client.IssueResponse
 import com.android.tools.idea.insights.events.actions.AppInsightsActionQueueImpl
+import com.android.tools.idea.testing.AndroidProjectRule
 import com.android.tools.idea.testing.NamedExternalResource
 import com.google.common.truth.Truth.assertThat
 import com.google.gct.login.GoogleLogin
 import com.google.wireless.android.sdk.stats.AppQualityInsightsUsageEvent.AppQualityInsightsFetchDetails.FetchSource
 import com.intellij.openapi.Disposable
 import com.intellij.openapi.application.ApplicationManager
+import com.intellij.openapi.project.Project
 import com.intellij.testFramework.DisposableRule
 import com.intellij.testFramework.ProjectRule
 import com.intellij.testFramework.registerOrReplaceServiceInstance
@@ -56,9 +58,17 @@
 private suspend fun <T> ReceiveChannel<T>.receiveWithTimeout(): T = withTimeout(5000) { receive() }
 
 class AppInsightsProjectLevelControllerRule(
-  private val projectRule: ProjectRule,
+  private val projectProvider: () -> Project,
   private val onErrorAction: (String, HyperlinkListener?) -> Unit = { _, _ -> }
 ) : NamedExternalResource() {
+  constructor(
+    projectRule: ProjectRule,
+    onErrorAction: (String, HyperlinkListener?) -> Unit = { _, _ -> }
+  ) : this({ projectRule.project }, onErrorAction)
+  constructor(
+    androidProjectRule: AndroidProjectRule,
+    onErrorAction: (String, HyperlinkListener?) -> Unit = { _, _ -> }
+  ) : this({ androidProjectRule.project }, onErrorAction)
   private val disposableRule = DisposableRule()
   val disposable: Disposable
     get() = disposableRule.disposable
@@ -98,7 +108,7 @@
         flowStart = SharingStarted.Lazily,
         tracker = tracker,
         clock = clock,
-        project = projectRule.project,
+        project = projectProvider(),
         queue = AppInsightsActionQueueImpl(ConcurrentLinkedQueue()),
         onErrorAction = onErrorAction,
         defaultFilters = TEST_FILTERS,
diff --git a/app-quality-insights/ide/BUILD b/app-quality-insights/ide/BUILD
index 08b9d0a..05fe5a1 100644
--- a/app-quality-insights/ide/BUILD
+++ b/app-quality-insights/ide/BUILD
@@ -28,7 +28,10 @@
     name = "intellij.android.app-quality-insights.ide.tests",
     iml_files = ["intellij.android.app-quality-insights.ide.tests.iml"],
     test_class = "com.android.tools.idea.insights.InsightsIdeTestSuite",
-    test_data = glob(["testData/**"]),
+    test_data = [
+        ":testData",
+        "//prebuilts/studio/sdk:platforms/latest",
+    ],
     test_srcs = ["testSrc"],
     visibility = ["//visibility:public"],
     # do not sort: must match IML order
@@ -50,5 +53,13 @@
         "//tools/analytics-library/testing:android.sdktools.analytics-testing[module, test]",
         "//tools/analytics-library/tracker:analytics-tracker[module, test]",
         "//tools/adt/idea/.idea/libraries:studio-analytics-proto[test]",
+        "//tools/adt/idea/project-system-gradle-models:intellij.android.projectSystem.gradle.models[module, test]",
+        "//tools/adt/idea/app-quality-insights/ide/gradle:intellij.android.app-quality-insights.ide.gradle[module, test]",
     ],
 )
+
+filegroup(
+    name = "testData",
+    srcs = glob(["testData/**"]),
+    visibility = ["//visibility:public"],
+)
diff --git a/app-quality-insights/ide/gradle/BUILD b/app-quality-insights/ide/gradle/BUILD
new file mode 100644
index 0000000..6b6d2b4
--- /dev/null
+++ b/app-quality-insights/ide/gradle/BUILD
@@ -0,0 +1,20 @@
+load("//tools/base/bazel:bazel.bzl", "iml_module")
+
+# managed by go/iml_to_build
+iml_module(
+    name = "intellij.android.app-quality-insights.ide.gradle",
+    srcs = ["src"],
+    iml_files = ["intellij.android.app-quality-insights.ide.gradle.iml"],
+    visibility = ["//visibility:public"],
+    # do not sort: must match IML order
+    deps = [
+        "//prebuilts/studio/intellij-sdk:studio-sdk",
+        "//tools/adt/idea/app-quality-insights/ide:intellij.android.app-quality-insights.ide[module]",
+        "//tools/adt/idea/project-system-gradle:intellij.android.projectSystem.gradle[module]",
+        "//tools/adt/idea/project-system:intellij.android.projectSystem[module]",
+        "//tools/adt/idea/android-common:intellij.android.common[module]",
+        "//tools/adt/idea/app-quality-insights/api:intellij.android.app-quality-insights.api[module]",
+        "//tools/base/flags:studio.android.sdktools.flags[module]",
+        "//tools/base/sdk-common:studio.android.sdktools.sdk-common[module]",
+    ],
+)
diff --git a/app-quality-insights/ide/gradle/intellij.android.app-quality-insights.ide.gradle.iml b/app-quality-insights/ide/gradle/intellij.android.app-quality-insights.ide.gradle.iml
new file mode 100644
index 0000000..d150583
--- /dev/null
+++ b/app-quality-insights/ide/gradle/intellij.android.app-quality-insights.ide.gradle.iml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="studio-sdk" level="project" />
+    <orderEntry type="module" module-name="intellij.android.app-quality-insights.ide" />
+    <orderEntry type="module" module-name="intellij.android.projectSystem.gradle" />
+    <orderEntry type="module" module-name="intellij.android.projectSystem" />
+    <orderEntry type="module" module-name="intellij.android.common" />
+    <orderEntry type="module" module-name="intellij.android.app-quality-insights.api" />
+    <orderEntry type="module" module-name="android.sdktools.flags" />
+    <orderEntry type="module" module-name="android.sdktools.sdk-common" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/app-quality-insights/ide/gradle/src/META-INF/app-insights-gradle.xml b/app-quality-insights/ide/gradle/src/META-INF/app-insights-gradle.xml
new file mode 100644
index 0000000..ae49678
--- /dev/null
+++ b/app-quality-insights/ide/gradle/src/META-INF/app-insights-gradle.xml
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright (C) 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.
+  -->
+<idea-plugin>
+  <extensions defaultExtensionNs="com.android.tools.idea.insights">
+    <vcsIntegrationToken implementation="com.android.tools.idea.insights.VcsIntegrationGradleToken"/>
+  </extensions>
+</idea-plugin>
diff --git a/app-quality-insights/ide/gradle/src/com/android/tools/idea/insights/VcsIntegrationGradleToken.kt b/app-quality-insights/ide/gradle/src/com/android/tools/idea/insights/VcsIntegrationGradleToken.kt
new file mode 100644
index 0000000..532dbd7
--- /dev/null
+++ b/app-quality-insights/ide/gradle/src/com/android/tools/idea/insights/VcsIntegrationGradleToken.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.insights
+
+import com.android.tools.idea.flags.StudioFlags
+import com.android.tools.idea.gradle.plugin.AndroidPluginInfo
+import com.android.tools.idea.insights.persistence.AppInsightsSettings
+import com.android.tools.idea.projectsystem.GradleToken
+import com.android.tools.idea.projectsystem.cacheInvalidatingOnSyncModifications
+import com.android.tools.idea.projectsystem.getModuleSystem
+import com.android.tools.idea.projectsystem.gradle.GradleModuleSystem
+import com.android.tools.idea.projectsystem.gradle.GradleProjectSystem
+import com.intellij.openapi.components.service
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.project.modules
+
+class VcsIntegrationGradleToken : VcsIntegrationToken<GradleProjectSystem>, GradleToken {
+  override fun canShowSuggestVcsIntegrationFeaturePanel(
+    projectSystem: GradleProjectSystem
+  ): Boolean {
+    val project = projectSystem.project
+    if (!StudioFlags.APP_INSIGHTS_VCS_SUPPORT.get()) return false
+    if (project.service<AppInsightsSettings>().isSuggestVcsIntegrationDismissed) return false
+    if (project.isVcsInfoEnabledInAgp()) return false
+
+    return project.hasRequiredAgpVersion(MIN_SUPPORTED_AGP_VERSION)
+  }
+
+  override fun isChangeAwareAnnotationEnabled(projectSystem: GradleProjectSystem): Boolean {
+    if (
+      !StudioFlags.APP_INSIGHTS_VCS_SUPPORT.get() ||
+        !StudioFlags.APP_INSIGHTS_CHANGE_AWARE_ANNOTATION_SUPPORT.get()
+    ) {
+      return false
+    }
+    return projectSystem.project.isVcsInfoEnabledInAgp()
+  }
+
+  companion object {
+    const val MIN_SUPPORTED_AGP_VERSION = "8.2.0-alpha06"
+  }
+
+  private fun Project.isVcsInfoEnabledInAgp(): Boolean {
+    return cacheInvalidatingOnSyncModifications {
+      modules
+        .asList()
+        .mapNotNull { it.getModuleSystem() as? GradleModuleSystem }
+        .any { it.enableVcsInfo }
+    }
+  }
+
+  private fun Project.hasRequiredAgpVersion(requiredAppVersion: String): Boolean {
+    val androidPluginInfo = AndroidPluginInfo.findFromModel(this)?.pluginVersion ?: return false
+
+    return androidPluginInfo >= requiredAppVersion
+  }
+}
diff --git a/app-quality-insights/ide/intellij.android.app-quality-insights.ide.tests.iml b/app-quality-insights/ide/intellij.android.app-quality-insights.ide.tests.iml
index 8ea42cc..2efd39a 100644
--- a/app-quality-insights/ide/intellij.android.app-quality-insights.ide.tests.iml
+++ b/app-quality-insights/ide/intellij.android.app-quality-insights.ide.tests.iml
@@ -24,5 +24,7 @@
     <orderEntry type="module" module-name="android.sdktools.analytics-testing" scope="TEST" />
     <orderEntry type="module" module-name="analytics-tracker" scope="TEST" />
     <orderEntry type="library" scope="TEST" name="studio-analytics-proto" level="project" />
+    <orderEntry type="module" module-name="intellij.android.projectSystem.gradle.models" scope="TEST" />
+    <orderEntry type="module" module-name="intellij.android.app-quality-insights.ide.gradle" scope="TEST" />
   </component>
 </module>
\ No newline at end of file
diff --git a/app-quality-insights/ide/src/META-INF/app-insights.xml b/app-quality-insights/ide/src/META-INF/app-insights.xml
index 62b43a2..8d4db55 100644
--- a/app-quality-insights/ide/src/META-INF/app-insights.xml
+++ b/app-quality-insights/ide/src/META-INF/app-insights.xml
@@ -30,6 +30,9 @@
   <extensionPoints>
     <extensionPoint qualifiedName="com.android.tools.idea.insights.ui.appInsightsTabProvider"
                     interface="com.android.tools.idea.insights.ui.AppInsightsTabProvider"/>
+    <extensionPoint qualifiedName="com.android.tools.idea.insights.vcsIntegrationToken"
+                    interface="com.android.tools.idea.insights.VcsIntegrationToken"
+                    area="IDEA_PROJECT"/>
   </extensionPoints>
   <actions>
     <action internal="true" id="Android.EnterOfflineModeInternalAction" class="com.android.tools.idea.insights.EnterOfflineModeInternalAction">
diff --git a/app-quality-insights/ide/src/com/android/tools/idea/insights/ModuleUtil.kt b/app-quality-insights/ide/src/com/android/tools/idea/insights/ModuleUtil.kt
index 75a655c..7f3b286 100644
--- a/app-quality-insights/ide/src/com/android/tools/idea/insights/ModuleUtil.kt
+++ b/app-quality-insights/ide/src/com/android/tools/idea/insights/ModuleUtil.kt
@@ -15,7 +15,6 @@
  */
 package com.android.tools.idea.insights
 
-import com.android.tools.idea.gradle.plugin.AndroidPluginInfo
 import com.android.tools.idea.model.AndroidModel
 import com.android.tools.idea.projectsystem.getAndroidFacets
 import com.intellij.openapi.module.Module
@@ -38,9 +37,3 @@
     }
     return appId
   }
-
-fun Project.hasRequiredAgpVersion(requiredAppVersion: String): Boolean {
-  val androidPluginInfo = AndroidPluginInfo.findFromModel(this)?.pluginVersion ?: return false
-
-  return androidPluginInfo >= requiredAppVersion
-}
diff --git a/app-quality-insights/ide/src/com/android/tools/idea/insights/VcsIntegrationToken.kt b/app-quality-insights/ide/src/com/android/tools/idea/insights/VcsIntegrationToken.kt
new file mode 100644
index 0000000..6cb36ab
--- /dev/null
+++ b/app-quality-insights/ide/src/com/android/tools/idea/insights/VcsIntegrationToken.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.insights
+
+import com.android.tools.idea.projectsystem.AndroidProjectSystem
+import com.android.tools.idea.projectsystem.Token
+import com.intellij.openapi.extensions.ExtensionPointName
+
+interface VcsIntegrationToken<P : AndroidProjectSystem> : Token {
+  companion object {
+    val EP_NAME =
+      ExtensionPointName<VcsIntegrationToken<AndroidProjectSystem>>(
+        "com.android.tools.idea.insights.vcsIntegrationToken"
+      )
+  }
+  fun canShowSuggestVcsIntegrationFeaturePanel(projectSystem: P): Boolean
+  fun isChangeAwareAnnotationEnabled(projectSystem: P): Boolean
+}
diff --git a/app-quality-insights/ide/src/com/android/tools/idea/insights/inspection/AppInsightsExternalAnnotator.kt b/app-quality-insights/ide/src/com/android/tools/idea/insights/inspection/AppInsightsExternalAnnotator.kt
index 1d75f2d..9bab900 100644
--- a/app-quality-insights/ide/src/com/android/tools/idea/insights/inspection/AppInsightsExternalAnnotator.kt
+++ b/app-quality-insights/ide/src/com/android/tools/idea/insights/inspection/AppInsightsExternalAnnotator.kt
@@ -17,6 +17,7 @@
 
 import com.android.tools.idea.insights.AppInsight
 import com.android.tools.idea.insights.AppInsightsModel
+import com.android.tools.idea.insights.VcsIntegrationToken
 import com.android.tools.idea.insights.analysis.StackTraceAnalyzer
 import com.android.tools.idea.insights.analytics.AppInsightsPerformanceTracker
 import com.android.tools.idea.insights.inspection.AppInsightsExternalAnnotator.AnnotationResult
@@ -24,6 +25,7 @@
 import com.android.tools.idea.insights.ui.AppInsightsGutterRenderer
 import com.android.tools.idea.insights.ui.AppInsightsTabProvider
 import com.android.tools.idea.insights.ui.AppInsightsToolWindowFactory
+import com.android.tools.idea.projectsystem.getProjectSystem
 import com.intellij.codeInsight.daemon.LineMarkerProviderDescriptor
 import com.intellij.codeInsight.daemon.LineMarkerSettings
 import com.intellij.lang.annotation.AnnotationHolder
@@ -76,9 +78,14 @@
     collectedInfo ?: return null
 
     val project = collectedInfo.project
+    val projectSystem = project.getProjectSystem()
+    val changeAwareToken =
+      VcsIntegrationToken.EP_NAME.getExtensions(project).firstOrNull {
+        it.isApplicable(projectSystem)
+      }
     val insights = collectedInfo.insights
 
-    if (!project.isChangeAwareAnnotationEnabled()) {
+    if (changeAwareToken?.isChangeAwareAnnotationEnabled(projectSystem) != true) {
       return AnnotationResult(insights)
     }
 
diff --git a/app-quality-insights/ide/src/com/android/tools/idea/insights/inspection/LineNumberMapperUtils.kt b/app-quality-insights/ide/src/com/android/tools/idea/insights/inspection/LineNumberMapperUtils.kt
index 8032f44..9127c67 100644
--- a/app-quality-insights/ide/src/com/android/tools/idea/insights/inspection/LineNumberMapperUtils.kt
+++ b/app-quality-insights/ide/src/com/android/tools/idea/insights/inspection/LineNumberMapperUtils.kt
@@ -15,12 +15,10 @@
  */
 package com.android.tools.idea.insights.inspection
 
-import com.android.tools.idea.flags.StudioFlags
 import com.android.tools.idea.insights.AppInsight
 import com.android.tools.idea.insights.AppVcsInfo
 import com.android.tools.idea.insights.vcs.createVcsDocument
 import com.android.tools.idea.insights.vcs.getVcsManager
-import com.android.tools.idea.insights.vcs.isVcsInfoEnabledInAgp
 import com.android.tools.idea.insights.vcs.locateRepository
 import com.intellij.diff.comparison.iterables.FairDiffIterable
 import com.intellij.diff.tools.util.text.LineOffsetsUtil
@@ -32,17 +30,6 @@
 import com.intellij.openapi.vcs.ex.compareLines
 import com.intellij.openapi.vfs.VirtualFile
 
-fun Project.isChangeAwareAnnotationEnabled(): Boolean {
-  if (
-    !StudioFlags.APP_INSIGHTS_VCS_SUPPORT.get() ||
-      !StudioFlags.APP_INSIGHTS_CHANGE_AWARE_ANNOTATION_SUPPORT.get()
-  ) {
-    return false
-  }
-
-  return isVcsInfoEnabledInAgp()
-}
-
 fun AppInsight.tryCreateVcsDocumentOrNull(contextVFile: VirtualFile, project: Project): Document? {
   return try {
     createVcsDocument(contextVFile, project)
diff --git a/app-quality-insights/ide/src/com/android/tools/idea/insights/vcs/SuggestVcsIntegrationFeaturePanel.kt b/app-quality-insights/ide/src/com/android/tools/idea/insights/vcs/SuggestVcsIntegrationFeaturePanel.kt
index 7af1ba7..317d5ad 100644
--- a/app-quality-insights/ide/src/com/android/tools/idea/insights/vcs/SuggestVcsIntegrationFeaturePanel.kt
+++ b/app-quality-insights/ide/src/com/android/tools/idea/insights/vcs/SuggestVcsIntegrationFeaturePanel.kt
@@ -15,15 +15,10 @@
  */
 package com.android.tools.idea.insights.vcs
 
-import com.android.tools.idea.flags.StudioFlags
-import com.android.tools.idea.insights.hasRequiredAgpVersion
 import com.android.tools.idea.insights.persistence.AppInsightsSettings
-import com.android.tools.idea.projectsystem.cacheInvalidatingOnSyncModifications
-import com.android.tools.idea.projectsystem.getModuleSystem
 import com.intellij.ide.BrowserUtil
 import com.intellij.openapi.components.service
 import com.intellij.openapi.project.Project
-import com.intellij.openapi.project.modules
 import com.intellij.ui.EditorNotificationPanel
 import com.intellij.util.ui.JBUI.CurrentTheme.Banner
 
@@ -46,22 +41,4 @@
 
     isVisible = true
   }
-
-  companion object {
-    const val MIN_SUPPORTED_AGP_VERSION = "8.2.0-alpha06"
-
-    fun canShow(project: Project): Boolean {
-      if (!StudioFlags.APP_INSIGHTS_VCS_SUPPORT.get()) return false
-      if (project.service<AppInsightsSettings>().isSuggestVcsIntegrationDismissed) return false
-      if (project.isVcsInfoEnabledInAgp()) return false
-
-      return project.hasRequiredAgpVersion(MIN_SUPPORTED_AGP_VERSION)
-    }
-  }
-}
-
-fun Project.isVcsInfoEnabledInAgp(): Boolean {
-  return cacheInvalidatingOnSyncModifications {
-    modules.asList().any { it.getModuleSystem().enableVcsInfo }
-  }
 }
diff --git a/app-quality-insights/ide/testSrc/com/android/tools/idea/insights/inspection/AppInsightsExternalAnnotatorOnChangeTest.kt b/app-quality-insights/ide/testSrc/com/android/tools/idea/insights/inspection/AppInsightsExternalAnnotatorOnChangeTest.kt
index d346520..19dab95 100644
--- a/app-quality-insights/ide/testSrc/com/android/tools/idea/insights/inspection/AppInsightsExternalAnnotatorOnChangeTest.kt
+++ b/app-quality-insights/ide/testSrc/com/android/tools/idea/insights/inspection/AppInsightsExternalAnnotatorOnChangeTest.kt
@@ -25,19 +25,34 @@
 import com.android.tools.idea.insights.VCS_CATEGORY
 import com.android.tools.idea.insights.ui.AppInsightsGutterRenderer
 import com.android.tools.idea.insights.vcs.InsightsVcsTestRule
-import com.android.tools.idea.insights.vcs.updateVcsInfoFlagInModel
 import com.android.tools.idea.testing.AndroidProjectRule
+import com.android.tools.idea.testing.JavaLibraryDependency
+import com.android.tools.idea.testing.buildAgpProjectFlagsStub
+import com.android.tools.idea.testing.createAndroidProjectBuilderForDefaultTestProjectStructure
+import com.android.tools.tests.AdtTestKotlinArtifacts
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.rules.RuleChain
 
 class AppInsightsExternalAnnotatorOnChangeTest {
-  private val projectRule = AndroidProjectRule.onDisk()
+  private val projectRule =
+    AndroidProjectRule.withAndroidModel(
+      createAndroidProjectBuilderForDefaultTestProjectStructure()
+        .withAgpProjectFlags { buildAgpProjectFlagsStub().copy(enableVcsInfo = true) }
+        // TODO(b/300170256): Remove this once 2023.3 merges and we no longer need kotlin-stdlib for
+        // every Kotlin test.
+        .withJavaLibraryDependencyList {
+          listOf(JavaLibraryDependency.forJar(AdtTestKotlinArtifacts.kotlinStdlib))
+        }
+    )
   private val vcsInsightsRule = InsightsVcsTestRule(projectRule)
-  private val flagRule = FlagRule(StudioFlags.APP_INSIGHTS_CHANGE_AWARE_ANNOTATION_SUPPORT, true)
+  private val changeAwareFlagRule =
+    FlagRule(StudioFlags.APP_INSIGHTS_CHANGE_AWARE_ANNOTATION_SUPPORT, true)
 
-  @get:Rule val rule = RuleChain.outerRule(projectRule).around(vcsInsightsRule).around(flagRule)
+  @get:Rule
+  val rule: RuleChain =
+    RuleChain.outerRule(projectRule).around(vcsInsightsRule).around(changeAwareFlagRule)
 
   private lateinit var appVcsInfo: AppVcsInfo
 
@@ -46,8 +61,6 @@
 
   @Before
   fun setUp() {
-    projectRule.fixture.module.updateVcsInfoFlagInModel(true)
-
     appVcsInfo =
       AppVcsInfo(
         listOf(
diff --git a/app-quality-insights/ide/testSrc/com/android/tools/idea/insights/inspection/AppInsightsExternalAnnotatorTest.kt b/app-quality-insights/ide/testSrc/com/android/tools/idea/insights/inspection/AppInsightsExternalAnnotatorTest.kt
index dad455f..caf091d 100644
--- a/app-quality-insights/ide/testSrc/com/android/tools/idea/insights/inspection/AppInsightsExternalAnnotatorTest.kt
+++ b/app-quality-insights/ide/testSrc/com/android/tools/idea/insights/inspection/AppInsightsExternalAnnotatorTest.kt
@@ -22,8 +22,11 @@
 import com.android.tools.idea.insights.REPO_INFO
 import com.android.tools.idea.insights.ui.AppInsightsGutterRenderer
 import com.android.tools.idea.insights.vcs.InsightsVcsTestRule
-import com.android.tools.idea.insights.vcs.updateVcsInfoFlagInModel
 import com.android.tools.idea.testing.AndroidProjectRule
+import com.android.tools.idea.testing.JavaLibraryDependency
+import com.android.tools.idea.testing.buildAgpProjectFlagsStub
+import com.android.tools.idea.testing.createAndroidProjectBuilderForDefaultTestProjectStructure
+import com.android.tools.tests.AdtTestKotlinArtifacts
 import com.intellij.codeInsight.daemon.GutterIconDescriptor
 import com.intellij.codeInsight.daemon.LineMarkerSettings
 import com.intellij.openapi.application.ApplicationManager
@@ -37,13 +40,23 @@
 
 @RunWith(Parameterized::class)
 class AppInsightsExternalAnnotatorTest(private val enableChangeAwareAnnotation: Boolean) {
-  private val projectRule = AndroidProjectRule.onDisk()
+  private val projectRule =
+    AndroidProjectRule.withAndroidModel(
+      createAndroidProjectBuilderForDefaultTestProjectStructure()
+        .withAgpProjectFlags { buildAgpProjectFlagsStub().copy(enableVcsInfo = true) }
+        // TODO(b/300170256): Remove this once 2023.3 merges and we no longer need kotlin-stdlib for
+        // every Kotlin test.
+        .withJavaLibraryDependencyList {
+          listOf(JavaLibraryDependency.forJar(AdtTestKotlinArtifacts.kotlinStdlib))
+        }
+    )
   private val vcsInsightsRule = InsightsVcsTestRule(projectRule)
-  private val flagRule =
+  private val changeAwareFlagRule =
     FlagRule(StudioFlags.APP_INSIGHTS_CHANGE_AWARE_ANNOTATION_SUPPORT, enableChangeAwareAnnotation)
 
   @get:Rule
-  val rule: RuleChain = RuleChain.outerRule(projectRule).around(vcsInsightsRule).around(flagRule)
+  val rule: RuleChain =
+    RuleChain.outerRule(projectRule).around(vcsInsightsRule).around(changeAwareFlagRule)
 
   companion object {
     @JvmStatic @Parameterized.Parameters(name = "{0}") fun data() = listOf(true, false)
@@ -56,7 +69,6 @@
 
   @Before
   fun setUp() {
-    projectRule.fixture.module.updateVcsInfoFlagInModel(enableChangeAwareAnnotation)
     appVcsInfo = AppVcsInfo(listOf(REPO_INFO))
   }
 
diff --git a/app-quality-insights/play-vitals/view/src/com/android/tools/idea/vitals/ui/VitalsIssueDetailsPanel.kt b/app-quality-insights/play-vitals/view/src/com/android/tools/idea/vitals/ui/VitalsIssueDetailsPanel.kt
index 93333a4..1b4b4a7 100644
--- a/app-quality-insights/play-vitals/view/src/com/android/tools/idea/vitals/ui/VitalsIssueDetailsPanel.kt
+++ b/app-quality-insights/play-vitals/view/src/com/android/tools/idea/vitals/ui/VitalsIssueDetailsPanel.kt
@@ -164,7 +164,7 @@
   @VisibleForTesting val stackTraceConsole = StackTraceConsole(controller, project, tracker)
 
   // Title
-  private val header = DetailsPanelHeader(stackTraceConsole.consoleView.editor)
+  private val header = DetailsPanelHeader(stackTraceConsole.consoleView.editor, controller, false)
 
   // TODO(b/290647605): add back device label
   // Events, users, affected api levels
@@ -228,7 +228,11 @@
             mainPanel,
             if (issue != null) MAIN_CARD else EMPTY_CARD
           )
-          header.updateWithIssue(issue)
+          if (issue == null) {
+            header.clear()
+          } else {
+            header.updateWithIssue(issue)
+          }
         }
     }
 
diff --git a/app-quality-insights/ui/BUILD b/app-quality-insights/ui/BUILD
index 9adff0f..d25f799 100644
--- a/app-quality-insights/ui/BUILD
+++ b/app-quality-insights/ui/BUILD
@@ -19,6 +19,7 @@
         "//tools/base/testutils:studio.android.sdktools.testutils[module, test]",
         "//tools/adt/idea/.idea/libraries:mockito[test]",
         "//tools/base/sdklib:studio.android.sdktools.sdklib[module]",
+        "//tools/adt/idea/adt-ui-model:intellij.android.adt.ui.model[module]",
     ],
 )
 
@@ -45,5 +46,9 @@
         "//tools/adt/idea/adt-testutils:intellij.android.adt.testutils[module, test]",
         "//tools/adt/idea/artwork:intellij.android.artwork[module, test]",
         "//tools/adt/idea/.idea/libraries:studio-analytics-proto[test]",
+        "//tools/adt/idea/adt-ui-model:intellij.android.adt.ui.model[module, test]",
+        "//tools/base/flags:studio.android.sdktools.flags[module, test]",
+        "//tools/adt/idea/.idea/libraries:jetbrains.kotlinx.coroutines.test[test]",
+        "//tools/adt/idea/.idea/libraries:kotlin-test[test]",
     ],
 )
diff --git a/app-quality-insights/ui/intellij.android.app-quality-insights.ui.iml b/app-quality-insights/ui/intellij.android.app-quality-insights.ui.iml
index 71b987d..84f6021 100644
--- a/app-quality-insights/ui/intellij.android.app-quality-insights.ui.iml
+++ b/app-quality-insights/ui/intellij.android.app-quality-insights.ui.iml
@@ -18,5 +18,6 @@
     <orderEntry type="module" module-name="android.sdktools.testutils" scope="TEST" />
     <orderEntry type="library" scope="TEST" name="mockito" level="project" />
     <orderEntry type="module" module-name="android.sdktools.sdklib" />
+    <orderEntry type="module" module-name="intellij.android.adt.ui.model" />
   </component>
 </module>
\ No newline at end of file
diff --git a/app-quality-insights/ui/intellij.android.app-quality-insights.ui.tests.iml b/app-quality-insights/ui/intellij.android.app-quality-insights.ui.tests.iml
index 277600e..1569738 100644
--- a/app-quality-insights/ui/intellij.android.app-quality-insights.ui.tests.iml
+++ b/app-quality-insights/ui/intellij.android.app-quality-insights.ui.tests.iml
@@ -20,5 +20,9 @@
     <orderEntry type="module" module-name="intellij.android.adt.testutils" scope="TEST" />
     <orderEntry type="module" module-name="intellij.android.artwork" scope="TEST" />
     <orderEntry type="library" scope="TEST" name="studio-analytics-proto" level="project" />
+    <orderEntry type="module" module-name="intellij.android.adt.ui.model" scope="TEST" />
+    <orderEntry type="module" module-name="android.sdktools.flags" scope="TEST" />
+    <orderEntry type="library" scope="TEST" name="jetbrains.kotlinx.coroutines.test" level="project" />
+    <orderEntry type="library" scope="TEST" name="kotlin-test" level="project" />
   </component>
 </module>
\ No newline at end of file
diff --git a/app-quality-insights/ui/src/com/android/tools/idea/insights/ui/DetailsPanelHeader.kt b/app-quality-insights/ui/src/com/android/tools/idea/insights/ui/DetailsPanelHeader.kt
index 2d1734f..fdec8e2 100644
--- a/app-quality-insights/ui/src/com/android/tools/idea/insights/ui/DetailsPanelHeader.kt
+++ b/app-quality-insights/ui/src/com/android/tools/idea/insights/ui/DetailsPanelHeader.kt
@@ -15,8 +15,13 @@
  */
 package com.android.tools.idea.insights.ui
 
+import com.android.tools.adtui.common.AdtUiUtils
 import com.android.tools.adtui.util.ActionToolbarUtil
 import com.android.tools.idea.insights.AppInsightsIssue
+import com.android.tools.idea.insights.AppInsightsProjectLevelController
+import com.android.tools.idea.insights.IssueVariant
+import com.android.tools.idea.insights.LoadingState
+import com.android.tools.idea.insights.Selection
 import com.intellij.openapi.actionSystem.ActionManager
 import com.intellij.openapi.actionSystem.ActionToolbar
 import com.intellij.openapi.actionSystem.ActionUpdateThread
@@ -27,17 +32,33 @@
 import com.intellij.openapi.editor.Editor
 import com.intellij.openapi.editor.actions.AbstractToggleUseSoftWrapsAction
 import com.intellij.openapi.editor.impl.softwrap.SoftWrapAppliancePlaces
+import com.intellij.openapi.ui.getUserData
+import com.intellij.openapi.ui.putUserData
+import com.intellij.openapi.util.Key
 import com.intellij.ui.JBColor
 import com.intellij.ui.components.JBLabel
 import com.intellij.ui.scale.JBUIScale
+import com.intellij.ui.util.preferredWidth
 import com.intellij.util.ui.JBUI
 import java.awt.BorderLayout
 import java.awt.Dimension
+import java.awt.Font
+import java.awt.event.ComponentAdapter
+import java.awt.event.ComponentEvent
+import javax.swing.Box
+import javax.swing.BoxLayout
 import javax.swing.JPanel
 import javax.swing.border.CompoundBorder
+import kotlinx.coroutines.flow.MutableStateFlow
 import org.jetbrains.annotations.VisibleForTesting
 
-class DetailsPanelHeader(editor: Editor) : JPanel(BorderLayout()) {
+private val KEY = Key.create<Pair<String, String>>("android.aqi.details.header")
+
+class DetailsPanelHeader(
+  editor: Editor,
+  private val controller: AppInsightsProjectLevelController,
+  private val supportsVariants: Boolean
+) : JPanel(BorderLayout()) {
   @VisibleForTesting val titleLabel = JBLabel()
 
   private val wrapAction =
@@ -54,9 +75,27 @@
     ActionManager.getInstance()
       .createActionToolbar("StackTraceToolbar", DefaultActionGroup(wrapAction), true)
 
+  @VisibleForTesting
+  val comboBoxStateFlow = MutableStateFlow<VariantComboBoxState>(DisabledComboBoxState.empty)
+  private val variantComboBox = VariantComboBox(controller.coroutineScope, comboBoxStateFlow)
+  @VisibleForTesting
+  val variantPanel =
+    transparentPanel(BorderLayout()).apply {
+      isVisible = false
+      add(JBLabel("|").apply { border = JBUI.Borders.empty(0, 5) }, BorderLayout.WEST)
+      add(variantComboBox, BorderLayout.CENTER)
+    }
+  private val contentPanel =
+    transparentPanel().apply {
+      layout = BoxLayout(this, BoxLayout.X_AXIS)
+      add(titleLabel)
+      add(Box.createHorizontalStrut(5))
+      add(variantPanel)
+    }
+
   init {
     border = JBUI.Borders.empty()
-    add(titleLabel, BorderLayout.WEST)
+    add(contentPanel, BorderLayout.WEST)
     toolbar.targetComponent = this
     toolbar.layoutPolicy = ActionToolbar.NOWRAP_LAYOUT_POLICY
     toolbar.setReservePlaceAutoPopupIcon(false)
@@ -69,22 +108,97 @@
     border =
       CompoundBorder(JBUI.Borders.customLineBottom(JBColor.border()), JBUI.Borders.emptyLeft(8))
     preferredSize = Dimension(0, JBUIScale.scale(28))
+    variantComboBox.renderer = variantComboBoxListCellRenderer
+    variantComboBox.addItemListener { itemEvent ->
+      (itemEvent.item as? VariantRow)?.let { controller.selectIssueVariant(it.issueVariant) }
+    }
+    addComponentListener(
+      object : ComponentAdapter() {
+        override fun componentResized(e: ComponentEvent) {
+          val (className, methodName) = titleLabel.getUserData(KEY) ?: return
+          titleLabel.text = generateTitleLabelText(className, methodName)
+        }
+      }
+    )
   }
 
-  fun updateWithIssue(issue: AppInsightsIssue?) {
+  fun clear() {
     titleLabel.icon = null
     titleLabel.text = null
     toolbar.component.isVisible = false
+    variantPanel.isVisible = false
+  }
 
-    if (issue == null) return
-
+  fun updateWithIssue(issue: AppInsightsIssue) {
     titleLabel.icon = issue.issueDetails.fatality.getIcon()
     val (className, methodName) = issue.issueDetails.getDisplayTitle()
-    val methodString =
-      if (methodName.isNotEmpty()) {
-        ".<B>$methodName</B>"
-      } else ""
-    titleLabel.text = "<html>$className$methodString</html>"
     toolbar.component.isVisible = true
+    if (supportsVariants) {
+      comboBoxStateFlow.value = DisabledComboBoxState.loading
+      variantPanel.isVisible = true
+      titleLabel.putUserData(KEY, Pair(className, methodName))
+      titleLabel.text = generateTitleLabelText(className, methodName)
+    } else {
+      val methodString =
+        if (methodName.isNotEmpty()) {
+          ".<B>$methodName</B>"
+        } else ""
+      titleLabel.text = "<html>$className$methodString</html>"
+    }
+  }
+
+  fun updateComboBox(
+    issue: AppInsightsIssue,
+    variants: LoadingState.Done<Selection<IssueVariant>?>
+  ) {
+    require(supportsVariants)
+    when (variants) {
+      is LoadingState.Ready -> {
+        comboBoxStateFlow.value =
+          if (variants.value?.items.isNullOrEmpty()) DisabledComboBoxState.empty
+          else PopulatedComboBoxState(issue, variants.value!!)
+      }
+      is LoadingState.Failure -> {
+        comboBoxStateFlow.value = DisabledComboBoxState.failure
+      }
+    }
+  }
+
+  @VisibleForTesting
+  fun generateTitleLabelText(className: String, methodName: String): String {
+    val contentWidth = width - toolbar.component.width
+    var remainingWidth = contentWidth - 5 - variantPanel.preferredWidth - 20
+    if (remainingWidth <= 0) return "<html></html>"
+    val shrunkenMethodText =
+      if (methodName.isNotEmpty()) {
+        val methodFontMetrics = getFontMetrics(titleLabel.font.deriveFont(Font.BOLD))
+        AdtUiUtils.shrinkToFit(
+            methodName,
+            methodFontMetrics,
+            remainingWidth.toFloat(),
+            AdtUiUtils.ShrinkDirection.TRUNCATE_START
+          )
+          .also { remainingWidth -= methodFontMetrics.stringWidth(it) }
+      } else {
+        ""
+      }
+
+    val shrunkenClassText =
+      if (remainingWidth > 0) {
+        val classFontMetrics = getFontMetrics(titleLabel.font)
+        AdtUiUtils.shrinkToFit(
+            "$className.",
+            classFontMetrics,
+            remainingWidth.toFloat(),
+            AdtUiUtils.ShrinkDirection.TRUNCATE_START
+          )
+          .also { remainingWidth -= classFontMetrics.stringWidth(it) }
+      } else ""
+
+    val methodString =
+      if (shrunkenMethodText.isNotEmpty()) {
+        "<B>$shrunkenMethodText</B>"
+      } else ""
+    return "<html>$shrunkenClassText$methodString</html>"
   }
 }
diff --git a/app-quality-insights/ui/src/com/android/tools/idea/insights/ui/VariantComboBox.kt b/app-quality-insights/ui/src/com/android/tools/idea/insights/ui/VariantComboBox.kt
new file mode 100644
index 0000000..ca2c7ac
--- /dev/null
+++ b/app-quality-insights/ui/src/com/android/tools/idea/insights/ui/VariantComboBox.kt
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.insights.ui
+
+import com.android.tools.adtui.model.stdui.DefaultCommonComboBoxModel
+import com.android.tools.adtui.stdui.CommonComboBox
+import com.android.tools.idea.insights.AppInsightsIssue
+import com.android.tools.idea.insights.IssueVariant
+import com.android.tools.idea.insights.Selection
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.launchIn
+import kotlinx.coroutines.flow.onEach
+import org.jetbrains.annotations.VisibleForTesting
+
+/** Represents the different states the variant combobox could have. */
+sealed interface VariantComboBoxState
+
+data class DisabledComboBoxState(val message: String) : VariantComboBoxState {
+  companion object {
+    val loading = DisabledComboBoxState("Loading variants...")
+    val empty = DisabledComboBoxState("No variants available.")
+    val failure = DisabledComboBoxState("Failed to load variants.")
+  }
+}
+
+data class PopulatedComboBoxState(
+  val issue: AppInsightsIssue,
+  val variants: Selection<IssueVariant>
+) : VariantComboBoxState
+
+class VariantComboBox(scope: CoroutineScope, flow: Flow<VariantComboBoxState>) :
+  CommonComboBox<Row, DefaultCommonComboBoxModel<Row>>(
+    DefaultCommonComboBoxModel<Row>("All variants").apply { editable = false }
+  ) {
+  private var isDisabledIndex = false
+  private var currentVariantSelection: Selection<IssueVariant>? = null
+
+  init {
+    flow
+      .distinctUntilChanged()
+      .onEach { state ->
+        when (state) {
+          is DisabledComboBoxState -> {
+            model.removeAllElements()
+            model.addElement(DisabledTextRow(state.message))
+            model.enabled = false
+          }
+          is PopulatedComboBoxState -> {
+            val variantSize = state.variants.items.size
+            if (currentVariantSelection?.items != state.variants.items) {
+              model.removeAllElements()
+              val allItem = state.issue.toVariantRow(variantSize)
+              model.addElement(HeaderRow)
+              model.addElement(allItem)
+              model.addAll(state.variants.items.map { it.toVariantRow() })
+              model.selectedItem = allItem
+            }
+            if (currentVariantSelection?.selected != state.variants.selected) {
+              if (state.variants.selected == null) {
+                model.selectedItem = state.issue.toVariantRow(variantSize)
+              } else {
+                model.selectedItem = state.variants.selected!!.toVariantRow()
+              }
+            }
+            currentVariantSelection = state.variants
+            model.enabled = true
+          }
+        }
+      }
+      .launchIn(scope)
+  }
+
+  // Disable selection on header row
+  override fun setPopupVisible(visible: Boolean) {
+    if (!visible && isDisabledIndex) {
+      isDisabledIndex = false
+    } else {
+      super.setPopupVisible(visible)
+    }
+  }
+
+  override fun setSelectedIndex(anIndex: Int) {
+    if (getItemAt(anIndex) is HeaderRow) {
+      isDisabledIndex = true
+    } else {
+      super.setSelectedIndex(anIndex)
+    }
+  }
+
+  override fun setSelectedItem(anObject: Any?) {
+    if (anObject is HeaderRow) {
+      isDisabledIndex = true
+    } else {
+      super.setSelectedItem(anObject)
+    }
+  }
+}
+
+@VisibleForTesting
+fun AppInsightsIssue.toVariantRow(size: Int) =
+  VariantRow(
+    "All ($size variant${if (size > 1) "s" else ""})",
+    issueDetails.eventsCount,
+    issueDetails.impactedDevicesCount,
+    null
+  )
+
+@VisibleForTesting
+fun IssueVariant.toVariantRow() =
+  VariantRow("Variant ${id.take(4)}", eventsCount, impactedDevicesCount, this)
diff --git a/app-quality-insights/ui/src/com/android/tools/idea/insights/ui/VariantComboBoxListCellRenderer.kt b/app-quality-insights/ui/src/com/android/tools/idea/insights/ui/VariantComboBoxListCellRenderer.kt
new file mode 100644
index 0000000..ce35f08
--- /dev/null
+++ b/app-quality-insights/ui/src/com/android/tools/idea/insights/ui/VariantComboBoxListCellRenderer.kt
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.insights.ui
+
+import com.android.tools.idea.insights.IssueVariant
+import com.intellij.ui.components.JBLabel
+import icons.StudioIcons
+import java.awt.BorderLayout
+import java.awt.Component
+import javax.swing.Box
+import javax.swing.BoxLayout
+import javax.swing.DefaultListCellRenderer
+import javax.swing.Icon
+import javax.swing.JPanel
+import javax.swing.ListCellRenderer
+import javax.swing.SwingConstants
+
+/** Represents a row to be rendered in the variants dropdown. */
+sealed interface Row {
+  fun getRendererComponent(): Component
+}
+
+/** A row containing variant information. */
+data class VariantRow(
+  val name: String,
+  val eventCount: Long,
+  val userCount: Long,
+  val issueVariant: IssueVariant?
+) : Row {
+  override fun getRendererComponent(): Component {
+    textLabel.update(name, null)
+    eventCountLabel.update(
+      eventCount.formatNumberToPrettyString(),
+      StudioIcons.AppQualityInsights.ISSUE
+    )
+    userCountLabel.update(
+      userCount.formatNumberToPrettyString(),
+      StudioIcons.LayoutEditor.Palette.QUICK_CONTACT_BADGE
+    )
+    return rendererComponent
+  }
+  companion object {
+    private val textLabel = JBLabel()
+    private val eventCountLabel = JBLabel()
+    private val userCountLabel = JBLabel()
+    private val rendererComponent =
+      JPanel().apply {
+        layout = BoxLayout(this, BoxLayout.X_AXIS)
+        isOpaque = false
+        add(textLabel)
+        add(Box.createHorizontalGlue())
+        add(eventCountLabel)
+        add(Box.createHorizontalStrut(4))
+        add(userCountLabel)
+      }
+
+    private fun JBLabel.update(value: String, icon: Icon?) {
+      removeAll()
+      this.icon = icon
+      toolTipText = value
+      text = value
+    }
+  }
+}
+
+/** Shown when the dropdown has no variant information. */
+data class DisabledTextRow(val text: String) : Row {
+  override fun getRendererComponent(): Component {
+    textComponent.text = text
+    return textComponent
+  }
+  companion object {
+    private val textComponent =
+      JBLabel().apply {
+        isEnabled = false
+        isOpaque = false
+      }
+  }
+}
+
+/** Represents the header of the variants list. */
+object HeaderRow : Row {
+  private val rendererComponent =
+    JPanel(BorderLayout()).apply {
+      add(
+        JBLabel("VARIANTS").apply {
+          isEnabled = false
+          isOpaque = false
+        },
+        BorderLayout.WEST
+      )
+      add(
+        JBLabel("IMPACT").apply {
+          isEnabled = false
+          isOpaque = false
+          horizontalAlignment = SwingConstants.RIGHT
+        },
+        BorderLayout.EAST
+      )
+      isOpaque = false
+      isEnabled = false
+    }
+
+  override fun getRendererComponent() = rendererComponent
+}
+
+private val defaultRenderer = DefaultListCellRenderer()
+
+val variantComboBoxListCellRenderer =
+  ListCellRenderer<Row> { _, value, _, _, _ ->
+    when (value) {
+      is Row -> value.getRendererComponent()
+      else -> defaultRenderer
+    }
+  }
diff --git a/app-quality-insights/ui/testSrc/com/android/tools/idea/insights/ui/DetailsPanelHeaderTest.kt b/app-quality-insights/ui/testSrc/com/android/tools/idea/insights/ui/DetailsPanelHeaderTest.kt
index 44f4535..a8e0152 100644
--- a/app-quality-insights/ui/testSrc/com/android/tools/idea/insights/ui/DetailsPanelHeaderTest.kt
+++ b/app-quality-insights/ui/testSrc/com/android/tools/idea/insights/ui/DetailsPanelHeaderTest.kt
@@ -15,10 +15,17 @@
  */
 package com.android.tools.idea.insights.ui
 
+import com.android.tools.idea.insights.FakeAppInsightsProjectLevelController
 import com.android.tools.idea.insights.ISSUE1
+import com.android.tools.idea.insights.ISSUE_VARIANT
+import com.android.tools.idea.insights.LoadingState
+import com.android.tools.idea.insights.Selection
 import com.google.common.truth.Truth.assertThat
 import com.intellij.openapi.editor.Editor
 import com.intellij.testFramework.ApplicationRule
+import java.awt.Dimension
+import kotlin.test.assertFailsWith
+import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.mockito.Mockito.mock
@@ -29,14 +36,18 @@
 
   @Test
   fun `header updates with issue`() {
-    val detailsPanelHeader = DetailsPanelHeader(mock(Editor::class.java))
+    val detailsPanelHeader =
+      DetailsPanelHeader(mock(Editor::class.java), FakeAppInsightsProjectLevelController(), true)
+
+    detailsPanelHeader.size = Dimension(500, 200)
+    detailsPanelHeader.toolbar.component.size = Dimension(50, 50)
 
     detailsPanelHeader.updateWithIssue(ISSUE1)
 
     assertThat(detailsPanelHeader.titleLabel.text).isEqualTo("<html>crash.<B>Crash</B></html>")
     assertThat(detailsPanelHeader.toolbar.component.isVisible).isTrue()
 
-    detailsPanelHeader.updateWithIssue(null)
+    detailsPanelHeader.clear()
 
     assertThat(detailsPanelHeader.toolbar.component.isVisible).isFalse()
     assertThat(detailsPanelHeader.titleLabel.text).isNull()
@@ -45,8 +56,67 @@
 
   @Test
   fun `header is shown with bottom border`() {
-    val detailsPanelHeader = DetailsPanelHeader(mock(Editor::class.java))
+    val detailsPanelHeader =
+      DetailsPanelHeader(mock(Editor::class.java), FakeAppInsightsProjectLevelController(), true)
 
     assertThat(detailsPanelHeader.border.getBorderInsets(detailsPanelHeader).bottom).isEqualTo(1)
   }
+
+  @Test
+  fun `header passes issue updates to combobox state flow`() {
+    val detailsPanelHeader =
+      DetailsPanelHeader(mock(Editor::class.java), FakeAppInsightsProjectLevelController(), true)
+    assertThat(detailsPanelHeader.variantPanel.isVisible).isFalse()
+
+    detailsPanelHeader.updateWithIssue(ISSUE1)
+    assertThat(detailsPanelHeader.variantPanel.isVisible).isTrue()
+    assertThat(detailsPanelHeader.comboBoxStateFlow.value).isEqualTo(DisabledComboBoxState.loading)
+
+    detailsPanelHeader.updateComboBox(ISSUE1, LoadingState.Ready(Selection.emptySelection()))
+    assertThat(detailsPanelHeader.variantPanel.isVisible).isTrue()
+    assertThat(detailsPanelHeader.comboBoxStateFlow.value).isEqualTo(DisabledComboBoxState.empty)
+
+    val selection = Selection(null, listOf(ISSUE_VARIANT))
+    detailsPanelHeader.updateComboBox(ISSUE1, LoadingState.Ready(selection))
+    assertThat(detailsPanelHeader.variantPanel.isVisible).isTrue()
+    assertThat(detailsPanelHeader.comboBoxStateFlow.value)
+      .isEqualTo(PopulatedComboBoxState(ISSUE1, selection))
+
+    detailsPanelHeader.updateComboBox(ISSUE1, LoadingState.NetworkFailure("failed"))
+    assertThat(detailsPanelHeader.variantPanel.isVisible).isTrue()
+    assertThat(detailsPanelHeader.comboBoxStateFlow.value).isEqualTo(DisabledComboBoxState.failure)
+
+    detailsPanelHeader.clear()
+    assertThat(detailsPanelHeader.variantPanel.isVisible).isFalse()
+  }
+
+  @Ignore("Investigate sizing discrepancies on different platforms")
+  @Test
+  fun `header width affects class name and method name in title label`() {
+    val detailsPanelHeader =
+      DetailsPanelHeader(mock(Editor::class.java), FakeAppInsightsProjectLevelController(), true)
+
+    detailsPanelHeader.size = Dimension(300, 200)
+    detailsPanelHeader.toolbar.component.size = Dimension(50, 50)
+    assertThat(detailsPanelHeader.generateTitleLabelText("DetailsPanelTest", "testMethod"))
+      .isEqualTo("<html><B>...ethod</B></html>")
+
+    detailsPanelHeader.size = Dimension(350, 200)
+    assertThat(detailsPanelHeader.generateTitleLabelText("DetailsPanelTest", "testMethod"))
+      .isEqualTo("<html>...st.<B>testMethod</B></html>")
+  }
+
+  @Test
+  fun `header should not show variants if variants not supported`() {
+    val detailsPanelHeader =
+      DetailsPanelHeader(mock(Editor::class.java), FakeAppInsightsProjectLevelController(), false)
+    assertThat(detailsPanelHeader.variantPanel.isVisible).isFalse()
+
+    detailsPanelHeader.updateWithIssue(ISSUE1)
+    assertThat(detailsPanelHeader.variantPanel.isVisible).isFalse()
+
+    assertFailsWith<IllegalArgumentException> {
+      detailsPanelHeader.updateComboBox(ISSUE1, LoadingState.Ready(Selection.emptySelection()))
+    }
+  }
 }
diff --git a/app-quality-insights/ui/testSrc/com/android/tools/idea/insights/ui/VariantComboBoxTest.kt b/app-quality-insights/ui/testSrc/com/android/tools/idea/insights/ui/VariantComboBoxTest.kt
new file mode 100644
index 0000000..e5b5eaa
--- /dev/null
+++ b/app-quality-insights/ui/testSrc/com/android/tools/idea/insights/ui/VariantComboBoxTest.kt
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@file:OptIn(ExperimentalCoroutinesApi::class)
+
+package com.android.tools.idea.insights.ui
+
+import com.android.tools.idea.concurrency.createChildScope
+import com.android.tools.idea.insights.ISSUE1
+import com.android.tools.idea.insights.ISSUE_VARIANT
+import com.android.tools.idea.insights.Selection
+import com.google.common.truth.Truth.assertThat
+import com.intellij.testFramework.DisposableRule
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.test.advanceUntilIdle
+import kotlinx.coroutines.test.runTest
+import org.junit.Rule
+import org.junit.Test
+
+class VariantComboBoxTest {
+
+  @get:Rule val disposableRule = DisposableRule()
+
+  @Test
+  fun `selection of header row is disabled in combobox`() = runTest {
+    val scope = createChildScope()
+    val flow = MutableSharedFlow<VariantComboBoxState>(1)
+    val comboBox = VariantComboBox(scope, flow)
+
+    flow.emit(PopulatedComboBoxState(ISSUE1, Selection(null, listOf(ISSUE_VARIANT))))
+
+    advanceUntilIdle()
+
+    val headerRow = comboBox.model.getElementAt(0)
+    assertThat(headerRow).isSameAs(HeaderRow)
+    assertThat(comboBox.selectedIndex).isEqualTo(1)
+
+    // Verify selected item doesn't change when selecting a header row
+    comboBox.selectedIndex = 0
+    assertThat(comboBox.selectedIndex).isEqualTo(1)
+
+    comboBox.selectedItem = headerRow
+    assertThat(comboBox.selectedIndex).isEqualTo(1)
+
+    scope.cancel()
+  }
+
+  @Test
+  fun `combo box shows disabled text when no variants are available`() = runTest {
+    val scope = createChildScope()
+    val flow = MutableSharedFlow<VariantComboBoxState>(1)
+    val comboBox = VariantComboBox(scope, flow)
+
+    flow.emit(DisabledComboBoxState.empty)
+
+    advanceUntilIdle()
+
+    assertThat(comboBox.selectedItem).isEqualTo(DisabledTextRow("No variants available."))
+
+    scope.cancel()
+  }
+
+  @Test
+  fun `combo box shows disabled text when variants fail to load`() = runTest {
+    val scope = createChildScope()
+    val flow = MutableSharedFlow<VariantComboBoxState>(1)
+    val comboBox = VariantComboBox(scope, flow)
+
+    flow.emit(DisabledComboBoxState.failure)
+
+    advanceUntilIdle()
+
+    assertThat(comboBox.selectedItem).isEqualTo(DisabledTextRow("Failed to load variants."))
+
+    scope.cancel()
+  }
+
+  @Test
+  fun `combo box shows loading text when in between requests`() = runTest {
+    val scope = createChildScope()
+    val flow = MutableSharedFlow<VariantComboBoxState>(1)
+    val comboBox = VariantComboBox(scope, flow)
+
+    flow.emit(DisabledComboBoxState.loading)
+
+    advanceUntilIdle()
+
+    assertThat(comboBox.selectedItem).isEqualTo(DisabledTextRow("Loading variants..."))
+
+    scope.cancel()
+  }
+
+  @Test
+  fun `combo box shows selection of variants when they exist`() = runTest {
+    val scope = createChildScope()
+    val flow = MutableSharedFlow<VariantComboBoxState>(1)
+    val comboBox = VariantComboBox(scope, flow)
+
+    val variant1 = ISSUE_VARIANT
+    val variant2 = ISSUE_VARIANT.copy(id = "variant2")
+
+    flow.emit(PopulatedComboBoxState(ISSUE1, Selection(variant2, listOf(variant1, variant2))))
+
+    advanceUntilIdle()
+
+    // Verify list of variants and selected variant.
+    assertThat(comboBox.model.getElementAt(0)).isSameAs(HeaderRow)
+    assertThat(comboBox.model.getElementAt(1)).isEqualTo(ISSUE1.toVariantRow(2))
+    assertThat(comboBox.model.getElementAt(2)).isEqualTo(variant1.toVariantRow())
+    assertThat(comboBox.model.getElementAt(3)).isEqualTo(variant2.toVariantRow())
+    assertThat(comboBox.selectedIndex).isEqualTo(3)
+
+    scope.cancel()
+  }
+}
diff --git a/build-attribution/src/com/android/build/attribution/ui/OpenBuildAnalyzerAction.kt b/build-attribution/src/com/android/build/attribution/ui/OpenBuildAnalyzerAction.kt
index dfcb8f9..f94b650 100644
--- a/build-attribution/src/com/android/build/attribution/ui/OpenBuildAnalyzerAction.kt
+++ b/build-attribution/src/com/android/build/attribution/ui/OpenBuildAnalyzerAction.kt
@@ -17,10 +17,16 @@
 package com.android.build.attribution.ui
 import com.android.build.attribution.BuildAnalyzerStorageManager
 import com.android.build.attribution.ui.analytics.BuildAttributionUiAnalytics
+import com.intellij.openapi.actionSystem.ActionUpdateThread
 import com.intellij.openapi.actionSystem.AnAction
 import com.intellij.openapi.actionSystem.AnActionEvent
 
 class OpenBuildAnalyzerAction : AnAction("Analyze Build Performance") {
+
+  override fun getActionUpdateThread(): ActionUpdateThread {
+    return ActionUpdateThread.BGT
+  }
+
   override fun update(e: AnActionEvent) {
     val project = e.project
     if(project == null) {
diff --git a/build-attribution/src/com/android/build/attribution/ui/OpenBuildAnalyzerResultsAction.kt b/build-attribution/src/com/android/build/attribution/ui/OpenBuildAnalyzerResultsAction.kt
index 8ef5620..f197a55 100644
--- a/build-attribution/src/com/android/build/attribution/ui/OpenBuildAnalyzerResultsAction.kt
+++ b/build-attribution/src/com/android/build/attribution/ui/OpenBuildAnalyzerResultsAction.kt
@@ -18,6 +18,7 @@
 
 import com.android.build.attribution.BuildAnalyzerStorageManager
 import com.android.tools.idea.flags.StudioFlags
+import com.intellij.openapi.actionSystem.ActionUpdateThread
 import com.intellij.openapi.actionSystem.AnAction
 import com.intellij.openapi.actionSystem.AnActionEvent
 import com.intellij.openapi.ui.popup.JBPopupFactory
@@ -28,6 +29,11 @@
  * Opens window with a list of previous Build Analyses results
  */
 class OpenBuildAnalyzerResultsAction : AnAction("Show Results Analysis of Previous Builds") {
+
+  override fun getActionUpdateThread(): ActionUpdateThread {
+    return ActionUpdateThread.BGT
+  }
+
   override fun update(e: AnActionEvent) {
     val project = e.project
     if (!StudioFlags.BUILD_ANALYZER_HISTORY.get() || project == null) {
diff --git a/compose-designer/src/META-INF/compose-designer.xml b/compose-designer/src/META-INF/compose-designer.xml
index a7650d9..11cd899 100644
--- a/compose-designer/src/META-INF/compose-designer.xml
+++ b/compose-designer/src/META-INF/compose-designer.xml
@@ -231,6 +231,12 @@
             use-shortcut-of="ForceRefresh" >
       <add-to-group group-id="Android.Designer.CommonActions" />
     </action>
+
+    <action id="Android.Designer.ReRunUiCheckModeAction"
+            icon="AllIcons.Actions.Refresh"
+            class="com.android.tools.idea.compose.preview.actions.ReRunUiCheckModeAction">
+      <add-to-group group-id="Android.Designer.IssuePanel.ToolbarActions" anchor="first"/>
+    </action>
   </actions>
 
 </idea-plugin>
\ No newline at end of file
diff --git a/compose-designer/src/com/android/tools/idea/compose/preview/ComposePreviewBundle.properties b/compose-designer/src/com/android/tools/idea/compose/preview/ComposePreviewBundle.properties
index bc1515d..9f3af96 100644
--- a/compose-designer/src/com/android/tools/idea/compose/preview/ComposePreviewBundle.properties
+++ b/compose-designer/src/com/android/tools/idea/compose/preview/ComposePreviewBundle.properties
@@ -192,6 +192,8 @@
 
 vertical.layout=Vertical Layout
 grid.layout=Grid Layout
+vertical.groups=Vertical Groups
+grid.groups=Grid Groups
 new.list.layout.title=List
 new.grid.layout.title=Grid
 gallery.mode.title=Gallery
diff --git a/compose-designer/src/com/android/tools/idea/compose/preview/ComposePreviewManager.kt b/compose-designer/src/com/android/tools/idea/compose/preview/ComposePreviewManager.kt
index 98a994b..274d909 100644
--- a/compose-designer/src/com/android/tools/idea/compose/preview/ComposePreviewManager.kt
+++ b/compose-designer/src/com/android/tools/idea/compose/preview/ComposePreviewManager.kt
@@ -109,6 +109,9 @@
   /** Flag to indicate if the preview filter is enabled or not. */
   var isFilterEnabled: Boolean
 
+  /** Flag to indicate if the UI Check filter is enabled or not. */
+  var isUiCheckFilterEnabled: Boolean
+
   /** Flag to indicate whether ATF checks should be run on the preview. */
   val atfChecksEnabled: Boolean
     get() = (currentOrNextMode as? PreviewMode.UiCheck)?.atfChecksEnabled ?: false
@@ -147,6 +150,7 @@
   override val previewedFile: PsiFile? = null
   override var isInspectionTooltipEnabled: Boolean = false
   override var isFilterEnabled: Boolean = false
+  override var isUiCheckFilterEnabled: Boolean = false
   override var mode: PreviewMode = PreviewMode.Default
   override fun setMode(newMode: PreviewMode.Settable) {
     mode = newMode
diff --git a/compose-designer/src/com/android/tools/idea/compose/preview/ComposePreviewRepresentationProvider.kt b/compose-designer/src/com/android/tools/idea/compose/preview/ComposePreviewRepresentationProvider.kt
index ecf752d..f670ea1 100644
--- a/compose-designer/src/com/android/tools/idea/compose/preview/ComposePreviewRepresentationProvider.kt
+++ b/compose-designer/src/com/android/tools/idea/compose/preview/ComposePreviewRepresentationProvider.kt
@@ -19,6 +19,7 @@
 import com.android.tools.idea.common.editor.ToolbarActionGroups
 import com.android.tools.idea.common.surface.DesignSurface
 import com.android.tools.idea.common.type.DesignerTypeRegistrar
+import com.android.tools.idea.compose.preview.actions.ComposeColorBlindAction
 import com.android.tools.idea.compose.preview.actions.ComposeFilterShowHistoryAction
 import com.android.tools.idea.compose.preview.actions.ComposeFilterTextAction
 import com.android.tools.idea.compose.preview.actions.ComposeNotificationGroup
@@ -28,7 +29,9 @@
 import com.android.tools.idea.compose.preview.actions.ShowDebugBoundaries
 import com.android.tools.idea.compose.preview.actions.StopAnimationInspectorAction
 import com.android.tools.idea.compose.preview.actions.StopUiCheckPreviewAction
+import com.android.tools.idea.compose.preview.actions.UiCheckFilteringAction
 import com.android.tools.idea.compose.preview.actions.visibleOnlyInComposeDefaultPreview
+import com.android.tools.idea.compose.preview.actions.visibleOnlyInUiCheck
 import com.android.tools.idea.compose.preview.essentials.ComposePreviewEssentialsModeManager
 import com.android.tools.idea.editors.sourcecode.isKotlinFileType
 import com.android.tools.idea.flags.StudioFlags
@@ -46,6 +49,7 @@
 import com.android.tools.idea.uibuilder.editor.multirepresentation.PreviewRepresentationProvider
 import com.android.tools.idea.uibuilder.editor.multirepresentation.TextEditorWithMultiRepresentationPreview
 import com.android.tools.idea.uibuilder.surface.LayoutManagerSwitcher
+import com.android.tools.idea.uibuilder.surface.NlDesignSurface
 import com.android.tools.preview.ComposePreviewElementInstance
 import com.google.wireless.android.sdk.stats.LayoutEditorState
 import com.intellij.openapi.actionSystem.ActionGroup
@@ -109,9 +113,28 @@
                   it.setMode(PreviewMode.Default)
                 }
               }
+            },
+            additionalActionProvider = {
+              if (StudioFlags.COMPOSE_COLORBLIND_MODE.get() && surface is NlDesignSurface)
+                ComposeColorBlindAction(surface)
+              else null
             }
           )
           .visibleOnlyInStaticPreview(),
+        ComposeViewControlAction(
+            layoutManagerSwitcher = surface.sceneViewLayoutManager as LayoutManagerSwitcher,
+            layoutManagers = BASE_LAYOUT_MANAGER_OPTIONS,
+            isSurfaceLayoutActionEnabled = {
+              !isPreviewRefreshing(it.dataContext) &&
+                // If Essentials Mode is enabled, it should not be possible to switch layout.
+                !ComposePreviewEssentialsModeManager.isEssentialsModeEnabled
+            },
+            onSurfaceLayoutSelected = { _, _ -> },
+            additionalActionProvider = { dataContext ->
+              dataContext.getData(COMPOSE_PREVIEW_MANAGER)?.let { UiCheckFilteringAction(it) }
+            }
+          )
+          .visibleOnlyInUiCheck(),
         StudioFlags.COMPOSE_DEBUG_BOUNDS.ifEnabled { ShowDebugBoundaries() },
       )
     ) {
diff --git a/compose-designer/src/com/android/tools/idea/compose/preview/ComposePreviewViewImpl.kt b/compose-designer/src/com/android/tools/idea/compose/preview/ComposePreviewViewImpl.kt
index a4bb4a7..106afc3 100644
--- a/compose-designer/src/com/android/tools/idea/compose/preview/ComposePreviewViewImpl.kt
+++ b/compose-designer/src/com/android/tools/idea/compose/preview/ComposePreviewViewImpl.kt
@@ -35,6 +35,7 @@
 import com.android.tools.idea.editors.notifications.NotificationPanel
 import com.android.tools.idea.editors.shortcuts.asString
 import com.android.tools.idea.editors.shortcuts.getBuildAndRefreshShortcut
+import com.android.tools.idea.preview.navigation.PreviewNavigationHandler
 import com.android.tools.idea.preview.refreshExistingPreviewElements
 import com.android.tools.idea.preview.updatePreviewsAndRefresh
 import com.android.tools.idea.projectsystem.requestBuild
@@ -148,6 +149,7 @@
     onRenderCompleted: () -> Unit,
     previewElementModelAdapter: ComposePreviewElementModelAdapter,
     modelUpdater: NlModel.NlModelUpdaterInterface,
+    navigationHandler: PreviewNavigationHandler,
     configureLayoutlibSceneManager:
       (PreviewDisplaySettings, LayoutlibSceneManager) -> LayoutlibSceneManager
   ): List<ComposePreviewElementInstance> {
@@ -165,6 +167,7 @@
       onRenderCompleted,
       previewElementModelAdapter,
       modelUpdater,
+      navigationHandler,
       configureLayoutlibSceneManager
     )
   }
diff --git a/compose-designer/src/com/android/tools/idea/compose/preview/Preview.kt b/compose-designer/src/com/android/tools/idea/compose/preview/Preview.kt
index 4be390c..2db1630 100644
--- a/compose-designer/src/com/android/tools/idea/compose/preview/Preview.kt
+++ b/compose-designer/src/com/android/tools/idea/compose/preview/Preview.kt
@@ -24,6 +24,7 @@
 import com.android.tools.idea.common.model.DefaultModelUpdater
 import com.android.tools.idea.common.model.NlModel
 import com.android.tools.idea.common.surface.DelegateInteractionHandler
+import com.android.tools.idea.common.surface.updateSceneViewVisibilities
 import com.android.tools.idea.compose.ComposePreviewElementsModel
 import com.android.tools.idea.compose.preview.animation.ComposePreviewAnimationManager
 import com.android.tools.idea.compose.preview.designinfo.hasDesignInfoProviders
@@ -81,6 +82,7 @@
 import com.android.tools.idea.uibuilder.scene.accessibilityBasedHierarchyParser
 import com.android.tools.idea.uibuilder.surface.LayoutManagerSwitcher
 import com.android.tools.idea.uibuilder.surface.NlDesignSurface
+import com.android.tools.idea.uibuilder.visual.visuallint.VisualLintIssueProvider
 import com.android.tools.idea.uibuilder.visual.visuallint.VisualLintMode
 import com.android.tools.idea.util.toDisplayString
 import com.android.tools.preview.ComposePreviewElementInstance
@@ -118,8 +120,13 @@
 import com.intellij.problems.WolfTheProblemSolver
 import com.intellij.psi.PsiFile
 import com.intellij.psi.SmartPointerManager
-import com.intellij.psi.SmartPsiElementPointer
 import com.intellij.util.ui.UIUtil
+import java.io.File
+import java.time.Duration
+import java.util.concurrent.atomic.AtomicBoolean
+import java.util.concurrent.atomic.AtomicReference
+import javax.swing.JComponent
+import kotlin.properties.Delegates
 import kotlinx.coroutines.CancellationException
 import kotlinx.coroutines.CompletableDeferred
 import kotlinx.coroutines.CoroutineScope
@@ -149,11 +156,6 @@
 import org.jetbrains.kotlin.idea.KotlinLanguage
 import org.jetbrains.kotlin.idea.base.util.module
 import org.jetbrains.kotlin.psi.KtFile
-import java.io.File
-import java.time.Duration
-import java.util.concurrent.atomic.AtomicBoolean
-import java.util.concurrent.atomic.AtomicReference
-import javax.swing.JComponent
 
 /** [Notification] group ID. Must match the `groupNotification` entry of `compose-designer.xml`. */
 const val PREVIEW_NOTIFICATION_GROUP_ID = "Compose Preview Notification"
@@ -536,7 +538,25 @@
   override val availableGroupsFlow: MutableStateFlow<Set<PreviewGroup.Named>> =
     MutableStateFlow(setOf())
 
-  private val navigationHandler = ComposePreviewNavigationHandler()
+  @VisibleForTesting
+  val navigationHandler =
+    ComposePreviewNavigationHandler().apply {
+      Disposer.register(this@ComposePreviewRepresentation, this)
+    }
+
+  override var isUiCheckFilterEnabled: Boolean by
+    Delegates.observable(false) { _, oldValue, newValue ->
+      if (oldValue == newValue) return@observable
+      launch(uiThread) {
+        if (newValue) {
+          surface.updateSceneViewVisibilities {
+            it.sceneManager.model in uiCheckFilterFlow.value.modelsWithErrors
+          }
+        } else {
+          surface.updateSceneViewVisibilities { true }
+        }
+      }
+    }
 
   private val previewElementModelAdapter =
     object : ComposePreviewElementModelAdapter() {
@@ -587,13 +607,35 @@
     uiCheckFilterFlow.value = UiCheckModeFilter.Enabled(instance)
     surface.background = Colors.INTERACTIVE_BACKGROUND_COLOR
     withContext(uiThread) {
-      IssuePanelService.getInstance(project)
-        .startUiCheck(
-          this@ComposePreviewRepresentation,
-          instance.instanceId,
-          instance.displaySettings.name,
-          surface
-        )
+      IssuePanelService.getInstance(project).startUiCheck(
+        this@ComposePreviewRepresentation,
+        instance.instanceId,
+        instance.displaySettings.name,
+        surface,
+        {
+          val models = mutableSetOf<NlModel>()
+          surface.visualLintIssueProvider
+            .getIssues()
+            .map { it.source }
+            .filterIsInstance<VisualLintIssueProvider.VisualLintIssueSource>()
+            .filter { models.addAll(it.models) }
+          uiCheckFilterFlow.value.modelsWithErrors = models
+          if (isUiCheckFilterEnabled) {
+            ApplicationManager.getApplication().invokeLater {
+              surface.updateSceneViewVisibilities { it.sceneManager.model in models }
+              surface.repaint()
+            }
+          }
+        }
+      ) {
+        // Pass preview manager and instance to the tab created for this UI Check preview.
+        // This enables restarting the UI Check mode from an action inside the tab.
+        when (it) {
+          COMPOSE_PREVIEW_MANAGER.name -> this@ComposePreviewRepresentation
+          COMPOSE_PREVIEW_ELEMENT_INSTANCE.name -> instance
+          else -> null
+        }
+      }
     }
     forceRefresh().join()
   }
@@ -643,13 +685,13 @@
     }
   }
   private fun getSlowData(dataId: String): Any? {
-  return when {
-    // The Compose preview NlModels do not point to the actual file but to a synthetic file
-    // generated for Layoutlib. This ensures we return the right file.
-    CommonDataKeys.VIRTUAL_FILE.`is`(dataId) -> psiFilePointer.virtualFile
-    else -> null
+    return when {
+      // The Compose preview NlModels do not point to the actual file but to a synthetic file
+      // generated for Layoutlib. This ensures we return the right file.
+      CommonDataKeys.VIRTUAL_FILE.`is`(dataId) -> psiFilePointer.virtualFile
+      else -> null
+    }
   }
-}
 
   private val delegateInteractionHandler = DelegateInteractionHandler()
   private val sceneComponentProvider = ComposeSceneComponentProvider()
@@ -683,6 +725,7 @@
         composeWorkBench.mainSurface,
         NavigatingInteractionHandler(
           composeWorkBench.mainSurface,
+          navigationHandler,
           isSelectionEnabled = { StudioFlags.COMPOSE_PREVIEW_SELECTION.get() }
         )
       )
@@ -1256,6 +1299,7 @@
         previewElementModelAdapter,
         if (atfChecksEnabled || visualLintingEnabled) accessibilityModelUpdater
         else defaultModelUpdater,
+        navigationHandler,
         this::configureLayoutlibSceneManagerForPreviewElement
       )
     if (progressIndicator.isCanceled) return // Return early if user has cancelled the refresh
@@ -1380,7 +1424,7 @@
             withContext(workerThread) {
               filteredPreviewElementsInstancesFlow.value.toList().sortByDisplayAndSourcePosition()
             }
-          composeWorkBench.hasContent = previewsToRender.isNotEmpty()
+          composeWorkBench.hasContent = previewsToRender.isNotEmpty() || isUiCheckPreview
           if (!needsFullRefresh) {
             requestLogger.debug(
               "No updates on the PreviewElements, just refreshing the existing ones"
@@ -1599,6 +1643,7 @@
    * and generate multiple previews, one per reference device for the user to check.
    */
   sealed class UiCheckModeFilter {
+    var modelsWithErrors: Set<NlModel> = emptySet()
     abstract val basePreviewInstance: ComposePreviewElementInstance?
     abstract fun filterPreviewInstances(
       previewInstances: Collection<ComposePreviewElementInstance>
diff --git a/compose-designer/src/com/android/tools/idea/compose/preview/PreviewDesignSurface.kt b/compose-designer/src/com/android/tools/idea/compose/preview/PreviewDesignSurface.kt
index 158b5cd..79d9a0c 100644
--- a/compose-designer/src/com/android/tools/idea/compose/preview/PreviewDesignSurface.kt
+++ b/compose-designer/src/com/android/tools/idea/compose/preview/PreviewDesignSurface.kt
@@ -84,9 +84,23 @@
     DesignSurface.SceneViewAlignment.LEFT,
   )
 
-/** List of available layouts for the Compose Preview Surface. */
-internal val PREVIEW_LAYOUT_MANAGER_OPTIONS =
-  if (!StudioFlags.COMPOSE_NEW_PREVIEW_LAYOUT.get()) {
+internal val BASE_LAYOUT_MANAGER_OPTIONS =
+  if (StudioFlags.COMPOSE_PREVIEW_GROUP_LAYOUT.get()) {
+    listOf(
+      SurfaceLayoutManagerOption(
+        // TODO(b/289994157) Change name to "List"
+        message("vertical.groups"),
+        GroupedListSurfaceLayoutManager(5, PREVIEW_FRAME_PADDING_PROVIDER, NO_GROUP_TRANSFORM),
+        DesignSurface.SceneViewAlignment.LEFT
+      ),
+      SurfaceLayoutManagerOption(
+        // TODO(b/289994157) Change name to "Grid"
+        message("grid.groups"),
+        GroupedGridSurfaceLayoutManager(5, PREVIEW_FRAME_PADDING_PROVIDER, NO_GROUP_TRANSFORM),
+        DesignSurface.SceneViewAlignment.LEFT,
+      )
+    )
+  } else if (!StudioFlags.COMPOSE_NEW_PREVIEW_LAYOUT.get()) {
     listOf(
       SurfaceLayoutManagerOption(
         message("vertical.layout"),
@@ -107,8 +121,7 @@
           NlConstants.SCREEN_DELTA
         ),
         DesignSurface.SceneViewAlignment.LEFT
-      ),
-      PREVIEW_LAYOUT_GALLERY_OPTION
+      )
     )
   } else {
     listOf(
@@ -121,11 +134,14 @@
         message("new.grid.layout.title"),
         GroupedGridSurfaceLayoutManager(5, PREVIEW_FRAME_PADDING_PROVIDER, NO_GROUP_TRANSFORM),
         DesignSurface.SceneViewAlignment.LEFT,
-      ),
-      PREVIEW_LAYOUT_GALLERY_OPTION
+      )
     )
   }
 
+/** List of available layouts for the Compose Preview Surface. */
+internal val PREVIEW_LAYOUT_MANAGER_OPTIONS =
+  BASE_LAYOUT_MANAGER_OPTIONS + PREVIEW_LAYOUT_GALLERY_OPTION
+
 /** Default layout manager selected in the preview. */
 internal val DEFAULT_PREVIEW_LAYOUT_MANAGER = PREVIEW_LAYOUT_MANAGER_OPTIONS.first().layoutManager
 
@@ -146,8 +162,7 @@
   screenViewProvider: ScreenViewProvider
 ): NlDesignSurface.Builder =
   NlDesignSurface.builder(project, parentDisposable)
-    .setNavigationHandler(navigationHandler)
-    .setActionManagerProvider { surface -> PreviewSurfaceActionManager(surface) }
+    .setActionManagerProvider { surface -> PreviewSurfaceActionManager(surface, navigationHandler) }
     .setInteractionHandlerProvider { delegateInteractionHandler }
     .setActionHandler { surface -> PreviewSurfaceActionHandler(surface) }
     .setSceneManagerProvider { surface, model ->
diff --git a/compose-designer/src/com/android/tools/idea/compose/preview/actions/ActionUtils.kt b/compose-designer/src/com/android/tools/idea/compose/preview/actions/ActionUtils.kt
index ff7f945..18f8376 100644
--- a/compose-designer/src/com/android/tools/idea/compose/preview/actions/ActionUtils.kt
+++ b/compose-designer/src/com/android/tools/idea/compose/preview/actions/ActionUtils.kt
@@ -37,6 +37,16 @@
   }
 }
 
+private class ComposePreviewUiCheckWrapper(actions: List<AnAction>) : DefaultActionGroup(actions) {
+  override fun update(e: AnActionEvent) {
+    super.update(e)
+
+    e.getData(COMPOSE_PREVIEW_MANAGER)?.let {
+      e.presentation.isVisible = it.mode is PreviewMode.UiCheck
+    }
+  }
+}
+
 /**
  * Makes the given action only visible when the Compose preview is not in interactive or animation
  * modes. Returns an [ActionGroup] that handles the visibility.
@@ -45,6 +55,13 @@
   ComposePreviewDefaultWrapper(listOf(this))
 
 /**
+ * Makes the given action only visible when the Compose preview is in UI Check mode. Returns an
+ * [ActionGroup] that handles the visibility.
+ */
+internal fun AnAction.visibleOnlyInUiCheck(): ActionGroup =
+  ComposePreviewUiCheckWrapper(listOf(this))
+
+/**
  * The given disables the actions if any surface is refreshing or if the [sceneView] contains
  * errors.
  */
diff --git a/compose-designer/src/com/android/tools/idea/compose/preview/actions/ComposeViewControlAction.kt b/compose-designer/src/com/android/tools/idea/compose/preview/actions/ComposeViewControlAction.kt
index 9f696ca..1763fcf 100644
--- a/compose-designer/src/com/android/tools/idea/compose/preview/actions/ComposeViewControlAction.kt
+++ b/compose-designer/src/com/android/tools/idea/compose/preview/actions/ComposeViewControlAction.kt
@@ -27,7 +27,6 @@
 import com.android.tools.idea.compose.preview.message
 import com.android.tools.idea.flags.StudioFlags
 import com.android.tools.idea.uibuilder.surface.LayoutManagerSwitcher
-import com.android.tools.idea.uibuilder.surface.NlDesignSurface
 import com.google.common.annotations.VisibleForTesting
 import com.intellij.icons.AllIcons
 import com.intellij.openapi.actionSystem.ActionUpdateThread
@@ -46,7 +45,8 @@
   private val layoutManagerSwitcher: LayoutManagerSwitcher,
   private val layoutManagers: List<SurfaceLayoutManagerOption>,
   private val isSurfaceLayoutActionEnabled: (AnActionEvent) -> Boolean = { true },
-  private val onSurfaceLayoutSelected: (SurfaceLayoutManagerOption, DataContext) -> Unit
+  private val onSurfaceLayoutSelected: (SurfaceLayoutManagerOption, DataContext) -> Unit,
+  private val additionalActionProvider: (DataContext) -> AnAction?
 ) :
   DropDownAction(
     message("action.scene.view.control.title"),
@@ -98,11 +98,9 @@
     // TODO(263038548): Implement Zoom-to-selection when preview is selectable.
     addSeparator()
     add(ShowInspectionTooltipsAction(context))
-    if (StudioFlags.COMPOSE_COLORBLIND_MODE.get()) {
-      (context.getData(DESIGN_SURFACE) as? NlDesignSurface)?.let { surface ->
-        addSeparator()
-        add(ComposeColorBlindAction(surface))
-      }
+    additionalActionProvider(context)?.let {
+      addSeparator()
+      add(it)
     }
     return true
   }
diff --git a/compose-designer/src/com/android/tools/idea/compose/preview/actions/JumpToDefinitionAction.kt b/compose-designer/src/com/android/tools/idea/compose/preview/actions/JumpToDefinitionAction.kt
index 4c24f64..18bf62a 100644
--- a/compose-designer/src/com/android/tools/idea/compose/preview/actions/JumpToDefinitionAction.kt
+++ b/compose-designer/src/com/android/tools/idea/compose/preview/actions/JumpToDefinitionAction.kt
@@ -18,9 +18,9 @@
 import com.android.tools.idea.common.surface.DesignSurface
 import com.android.tools.idea.common.surface.SceneView
 import com.android.tools.idea.compose.preview.message
-import com.android.tools.idea.compose.preview.navigation.ComposePreviewNavigationHandler
 import com.android.tools.idea.concurrency.AndroidCoroutineScope
 import com.android.tools.idea.uibuilder.scene.LayoutlibSceneManager
+import com.android.tools.idea.uibuilder.surface.NavigationHandler
 import com.intellij.openapi.actionSystem.ActionUpdateThread
 import com.intellij.openapi.actionSystem.AnAction
 import com.intellij.openapi.actionSystem.AnActionEvent
@@ -34,7 +34,7 @@
  */
 class JumpToDefinitionAction(
   surface: DesignSurface<LayoutlibSceneManager>,
-  private val composePreviewNavigationHandler: ComposePreviewNavigationHandler,
+  private val navigationHandler: NavigationHandler,
   private val sceneView: SceneView,
   title: String = message("action.jump.to.definition")
 ) : AnAction(title) {
@@ -63,8 +63,6 @@
   }
 
   override fun actionPerformed(e: AnActionEvent) {
-    scope.launch {
-      composePreviewNavigationHandler.handleNavigateWithCoordinates(sceneView, x, y, true)
-    }
+    scope.launch { navigationHandler.handleNavigateWithCoordinates(sceneView, x, y, true) }
   }
 }
diff --git a/compose-designer/src/com/android/tools/idea/compose/preview/actions/PreviewSurfaceActionManager.kt b/compose-designer/src/com/android/tools/idea/compose/preview/actions/PreviewSurfaceActionManager.kt
index d67d364..bda53ff 100644
--- a/compose-designer/src/com/android/tools/idea/compose/preview/actions/PreviewSurfaceActionManager.kt
+++ b/compose-designer/src/com/android/tools/idea/compose/preview/actions/PreviewSurfaceActionManager.kt
@@ -19,15 +19,18 @@
 import com.android.tools.idea.common.editor.ActionManager
 import com.android.tools.idea.common.model.NlComponent
 import com.android.tools.idea.common.surface.DesignSurface
+import com.android.tools.idea.common.surface.InteractiveLabelPanel
+import com.android.tools.idea.common.surface.LabelPanel
+import com.android.tools.idea.common.surface.LayoutData
 import com.android.tools.idea.common.surface.SceneView
 import com.android.tools.idea.compose.preview.essentials.ComposePreviewEssentialsModeManager
 import com.android.tools.idea.compose.preview.message
-import com.android.tools.idea.compose.preview.navigation.ComposePreviewNavigationHandler
 import com.android.tools.idea.preview.actions.EnableInteractiveAction
 import com.android.tools.idea.preview.actions.createStatusIcon
 import com.android.tools.idea.preview.actions.hideIfRenderErrors
 import com.android.tools.idea.preview.actions.visibleOnlyInStaticPreview
 import com.android.tools.idea.uibuilder.scene.LayoutlibSceneManager
+import com.android.tools.idea.uibuilder.surface.NavigationHandler
 import com.android.tools.idea.uibuilder.surface.NlDesignSurface
 import com.intellij.openapi.actionSystem.DefaultActionGroup
 import com.intellij.openapi.actionSystem.IdeActions
@@ -38,7 +41,8 @@
 
 /** [ActionManager] to be used by the Compose Preview. */
 internal class PreviewSurfaceActionManager(
-  private val surface: DesignSurface<LayoutlibSceneManager>
+  private val surface: DesignSurface<LayoutlibSceneManager>,
+  private val navigationHandler: NavigationHandler,
 ) : ActionManager<DesignSurface<LayoutlibSceneManager>>(surface) {
 
   private val sceneManagerProvider: () -> LayoutlibSceneManager? = {
@@ -58,6 +62,14 @@
     registerAction(copyResultImageAction, IdeActions.ACTION_COPY, component)
   }
 
+  override fun createSceneViewLabel(sceneView: SceneView): LabelPanel {
+    return InteractiveLabelPanel(
+      LayoutData.fromSceneView(sceneView),
+      surface,
+      suspend { navigationHandler.handleNavigate(sceneView, false) }
+    )
+  }
+
   override fun getPopupMenuActions(leafComponent: NlComponent?): DefaultActionGroup {
     // Copy Image
     val actionGroup = DefaultActionGroup().apply { add(copyResultImageAction) }
@@ -68,9 +80,8 @@
       actionGroup.add(ZoomToSelectionAction(surface, sceneView))
     }
     // Jump to Definition
-    ((surface as? NlDesignSurface)?.navigationHandler as? ComposePreviewNavigationHandler)?.let {
-      actionGroup.add(JumpToDefinitionAction(surface, it, sceneView))
-    }
+    actionGroup.add(JumpToDefinitionAction(surface, navigationHandler, sceneView))
+
     return actionGroup
   }
 
diff --git a/compose-designer/src/com/android/tools/idea/compose/preview/actions/ReRunUiCheckModeAction.kt b/compose-designer/src/com/android/tools/idea/compose/preview/actions/ReRunUiCheckModeAction.kt
new file mode 100644
index 0000000..0ef57f7
--- /dev/null
+++ b/compose-designer/src/com/android/tools/idea/compose/preview/actions/ReRunUiCheckModeAction.kt
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.compose.preview.actions
+
+import com.android.tools.idea.compose.preview.COMPOSE_PREVIEW_ELEMENT_INSTANCE
+import com.android.tools.idea.compose.preview.COMPOSE_PREVIEW_MANAGER
+import com.android.tools.idea.compose.preview.ComposePreviewManager
+import com.android.tools.idea.preview.modes.PreviewMode
+import com.android.tools.preview.ComposePreviewElementInstance
+import com.intellij.analysis.problemsView.toolWindow.ProblemsView
+import com.intellij.ide.impl.DataManagerImpl
+import com.intellij.openapi.actionSystem.ActionUpdateThread
+import com.intellij.openapi.actionSystem.AnAction
+import com.intellij.openapi.actionSystem.AnActionEvent
+import com.intellij.openapi.actionSystem.DataProvider
+import com.intellij.openapi.fileEditor.FileEditorManager
+import com.intellij.openapi.project.Project
+
+private const val DISABLED_TEXT =
+  "UI Check is running in the background for this composable. Stop UI Check mode."
+private const val ENABLED_TEXT = "Restart UI Check and background linting for this composable."
+
+class ReRunUiCheckModeAction : AnAction() {
+
+  override fun update(e: AnActionEvent) {
+    val project = e.project ?: return
+    val dataContext = uiTabDataContext(project) ?: return
+    val manager = dataContext.getData(COMPOSE_PREVIEW_MANAGER.name) as? ComposePreviewManager
+    e.presentation.isVisible = manager != null
+    manager?.let {
+      if (it.isUiCheckPreview) {
+        e.presentation.isEnabled = false
+        e.presentation.text = DISABLED_TEXT
+      } else {
+        e.presentation.isEnabled = true
+        e.presentation.text = ENABLED_TEXT
+      }
+    }
+    e.presentation.isEnabled = manager?.isUiCheckPreview?.not() ?: false
+
+    super.update(e)
+  }
+
+  override fun actionPerformed(e: AnActionEvent) {
+    val project = e.project ?: return
+    val dataContext = uiTabDataContext(project) ?: return
+    val manager =
+      dataContext.getData(COMPOSE_PREVIEW_MANAGER.name) as? ComposePreviewManager ?: return
+    val instance =
+      dataContext.getData(COMPOSE_PREVIEW_ELEMENT_INSTANCE.name) as? ComposePreviewElementInstance
+        ?: return
+    manager.setMode(PreviewMode.UiCheck(selected = instance))
+    instance.containingFile?.let {
+      FileEditorManager.getInstance(project).openFile(it.virtualFile, true, true)
+    }
+  }
+
+  override fun getActionUpdateThread() = ActionUpdateThread.BGT
+
+  private fun uiTabDataContext(project: Project): DataProvider? {
+    val tabComponent =
+      ProblemsView.getToolWindow(project)?.contentManagerIfCreated?.selectedContent?.component
+        ?: return null
+    return DataManagerImpl.getDataProviderEx(tabComponent)
+  }
+}
diff --git a/compose-designer/src/com/android/tools/idea/compose/preview/actions/UiCheckFilteringAction.kt b/compose-designer/src/com/android/tools/idea/compose/preview/actions/UiCheckFilteringAction.kt
new file mode 100644
index 0000000..380c8b8
--- /dev/null
+++ b/compose-designer/src/com/android/tools/idea/compose/preview/actions/UiCheckFilteringAction.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.compose.preview.actions
+
+import com.android.tools.idea.compose.preview.ComposePreviewManager
+import com.intellij.openapi.actionSystem.ActionUpdateThread
+import com.intellij.openapi.actionSystem.AnActionEvent
+import com.intellij.openapi.actionSystem.ToggleAction
+
+internal class UiCheckFilteringAction(private val previewManager: ComposePreviewManager) :
+  ToggleAction("Show Previews With Problems Only") {
+  override fun isSelected(e: AnActionEvent) = previewManager.isUiCheckFilterEnabled
+
+  override fun setSelected(e: AnActionEvent, state: Boolean) {
+    previewManager.isUiCheckFilterEnabled = state
+  }
+
+  override fun getActionUpdateThread() = ActionUpdateThread.BGT
+}
diff --git a/compose-designer/testSrc/com/android/tools/idea/compose/gradle/datasource/ParametrizedPreviewTest.kt b/compose-designer/testSrc/com/android/tools/idea/compose/gradle/datasource/ParametrizedPreviewTest.kt
index 29598e0..002c686 100644
--- a/compose-designer/testSrc/com/android/tools/idea/compose/gradle/datasource/ParametrizedPreviewTest.kt
+++ b/compose-designer/testSrc/com/android/tools/idea/compose/gradle/datasource/ParametrizedPreviewTest.kt
@@ -23,7 +23,6 @@
 import com.android.tools.idea.compose.preview.SIMPLE_COMPOSE_PROJECT_PATH
 import com.android.tools.idea.compose.preview.SimpleComposeAppPaths
 import com.android.tools.idea.compose.preview.TestComposePreviewView
-import com.android.tools.idea.compose.preview.navigation.ComposePreviewNavigationHandler
 import com.android.tools.idea.compose.preview.renderer.renderPreviewElementForResult
 import com.android.tools.idea.concurrency.awaitStatus
 import com.android.tools.idea.editors.build.ProjectStatus
@@ -278,11 +277,8 @@
         .resolve()
     assertEquals(3, elements.count())
 
-    val navigationHandler = ComposePreviewNavigationHandler()
     val mainSurface =
-      NlDesignSurface.builder(project, projectRule.fixture.testRootDisposable)
-        .setNavigationHandler(navigationHandler)
-        .build()
+      NlDesignSurface.builder(project, projectRule.fixture.testRootDisposable).build()
 
     val composeView = TestComposePreviewView(mainSurface)
     val preview =
diff --git a/compose-designer/testSrc/com/android/tools/idea/compose/gradle/preview/RenderErrorTest.kt b/compose-designer/testSrc/com/android/tools/idea/compose/gradle/preview/RenderErrorTest.kt
index e317ea6..a0c4d9f 100644
--- a/compose-designer/testSrc/com/android/tools/idea/compose/gradle/preview/RenderErrorTest.kt
+++ b/compose-designer/testSrc/com/android/tools/idea/compose/gradle/preview/RenderErrorTest.kt
@@ -26,6 +26,7 @@
 import com.android.tools.idea.compose.preview.ComposePreviewRepresentation
 import com.android.tools.idea.compose.preview.SIMPLE_COMPOSE_PROJECT_PATH
 import com.android.tools.idea.compose.preview.SimpleComposeAppPaths
+import com.android.tools.idea.flags.StudioFlags
 import com.android.tools.idea.preview.modes.PreviewMode
 import com.android.tools.idea.uibuilder.editor.multirepresentation.PreferredVisibility
 import com.android.tools.idea.uibuilder.scene.hasRenderErrors
@@ -196,9 +197,10 @@
     // The visible/invisible state before the update shouldn't affect the final result
     for (visibleBefore in listOf(true, false)) {
       // The animation preview action shouldn't be visible because the preview being used doesn't
-      // contain animations, but the interactive and deploy to device actions should be visible as
-      // there are no render errors.
-      assertEquals(2, countVisibleActions(actions, visibleBefore))
+      // contain animations, but the interactive, ui check and deploy to device actions should be
+      // visible as there are no render errors.
+      val visibleActionCount = if (StudioFlags.NELE_COMPOSE_UI_CHECK_MODE.get()) 3 else 2
+      assertEquals(visibleActionCount, countVisibleActions(actions, visibleBefore))
     }
   }
 
diff --git a/compose-designer/testSrc/com/android/tools/idea/compose/preview/ComposePreviewRepresentationTest.kt b/compose-designer/testSrc/com/android/tools/idea/compose/preview/ComposePreviewRepresentationTest.kt
index d5910d6..1e18329 100644
--- a/compose-designer/testSrc/com/android/tools/idea/compose/preview/ComposePreviewRepresentationTest.kt
+++ b/compose-designer/testSrc/com/android/tools/idea/compose/preview/ComposePreviewRepresentationTest.kt
@@ -20,8 +20,9 @@
 import com.android.tools.idea.common.surface.DesignSurface
 import com.android.tools.idea.common.surface.DesignSurfaceListener
 import com.android.tools.idea.compose.ComposeProjectRule
+import com.android.tools.idea.compose.preview.actions.ReRunUiCheckModeAction
 import com.android.tools.idea.compose.preview.gallery.ComposeGalleryMode
-import com.android.tools.idea.compose.preview.navigation.ComposePreviewNavigationHandler
+import com.android.tools.idea.concurrency.AndroidDispatchers.uiThread
 import com.android.tools.idea.concurrency.AndroidDispatchers.workerThread
 import com.android.tools.idea.concurrency.awaitStatus
 import com.android.tools.idea.editors.build.ProjectStatus
@@ -47,6 +48,7 @@
 import com.intellij.openapi.util.Disposer
 import com.intellij.openapi.wm.RegisterToolWindowTask
 import com.intellij.openapi.wm.ToolWindowManager
+import com.intellij.testFramework.TestActionEvent
 import com.intellij.testFramework.assertInstanceOf
 import com.intellij.testFramework.runInEdtAndWait
 import java.util.UUID
@@ -55,6 +57,7 @@
 import javax.swing.JPanel
 import kotlin.time.Duration.Companion.seconds
 import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
 import kotlinx.coroutines.runBlocking
 import kotlinx.coroutines.withContext
 import org.junit.After
@@ -104,7 +107,7 @@
     Logger.getInstance(FastPreviewManager::class.java).setLevel(LogLevel.ALL)
     Logger.getInstance(ProjectStatus::class.java).setLevel(LogLevel.ALL)
     logger.info("setup")
-    val testProjectSystem = TestProjectSystem(project)
+    val testProjectSystem = TestProjectSystem(project).apply { usesCompose = true }
     runInEdtAndWait { testProjectSystem.useInTests() }
     logger.info("setup complete")
     ToolWindowManager.getInstance(project)
@@ -145,11 +148,7 @@
         )
       }
 
-      val navigationHandler = ComposePreviewNavigationHandler()
-      val mainSurface =
-        NlDesignSurface.builder(project, fixture.testRootDisposable)
-          .setNavigationHandler(navigationHandler)
-          .build()
+      val mainSurface = NlDesignSurface.builder(project, fixture.testRootDisposable).build()
       val modelRenderedLatch = CountDownLatch(2)
 
       mainSurface.addListener(
@@ -181,7 +180,9 @@
         delayWhileRefreshingOrDumb(preview)
       }
 
-      mainSurface.models.forEach { assertTrue(navigationHandler.defaultNavigationMap.contains(it)) }
+      mainSurface.models.forEach {
+        assertTrue(preview.navigationHandler.defaultNavigationMap.contains(it))
+      }
 
       assertThat(preview.availableGroupsFlow.value.map { it.displayName }).containsExactly("groupA")
 
@@ -224,11 +225,7 @@
         )
       }
 
-      val navigationHandler = ComposePreviewNavigationHandler()
-      val mainSurface =
-        NlDesignSurface.builder(project, fixture.testRootDisposable)
-          .setNavigationHandler(navigationHandler)
-          .build()
+      val mainSurface = NlDesignSurface.builder(project, fixture.testRootDisposable).build()
       val modelRenderedLatch = CountDownLatch(2)
 
       mainSurface.addListener(
@@ -322,6 +319,13 @@
       // Check that the UI Check tab has been created
       assertEquals(2, contentManager.contents.size)
       assertNotNull(contentManager.findContent(uiCheckElement.displaySettings.name))
+      val rerunAction = ReRunUiCheckModeAction()
+      run {
+        val actionEvent = TestActionEvent.createTestEvent()
+        rerunAction.update(actionEvent)
+        assertTrue(actionEvent.presentation.isVisible)
+        assertFalse(actionEvent.presentation.isEnabled)
+      }
 
       // Stop UI Check mode
       preview.setMode(PreviewMode.Default)
@@ -354,6 +358,53 @@
       // Check that the UI Check tab is still present
       assertEquals(2, contentManager.contents.size)
       assertNotNull(contentManager.findContent(uiCheckElement.displaySettings.name))
+      run {
+        val actionEvent = TestActionEvent.createTestEvent()
+        rerunAction.update(actionEvent)
+        assertTrue(actionEvent.presentation.isEnabledAndVisible)
+      }
+
+      // Re-run UI check with the problems panel action
+      launch(uiThread) { rerunAction.actionPerformed(TestActionEvent.createTestEvent()) }
+      delayUntilCondition(250) { preview.isUiCheckPreview }
+      preview.filteredPreviewElementsInstancesFlowForTest().awaitStatus(
+        "Failed set uiCheckMode",
+        5.seconds
+      ) {
+        it.size > 2
+      }
+      assertEquals(
+        """
+          TestKt.Preview1
+          spec:id=reference_phone,shape=Normal,width=411,height=891,unit=dp,dpi=420
+          PreviewDisplaySettings(name=Preview1 - _device_class_phone, group=Screen sizes, showDecoration=true, showBackground=false, backgroundColor=null, displayPositioning=NORMAL)
+
+          TestKt.Preview1
+          spec:shape=Normal,width=673,height=841,unit=dp,dpi=480
+          PreviewDisplaySettings(name=Preview1 - _device_class_foldable, group=Screen sizes, showDecoration=true, showBackground=false, backgroundColor=null, displayPositioning=NORMAL)
+
+          TestKt.Preview1
+          spec:shape=Normal,width=1280,height=800,unit=dp,dpi=420
+          PreviewDisplaySettings(name=Preview1 - _device_class_tablet, group=Screen sizes, showDecoration=true, showBackground=false, backgroundColor=null, displayPositioning=NORMAL)
+
+          TestKt.Preview1
+          spec:shape=Normal,width=1920,height=1080,unit=dp,dpi=420
+          PreviewDisplaySettings(name=Preview1 - _device_class_desktop, group=Screen sizes, showDecoration=true, showBackground=false, backgroundColor=null, displayPositioning=NORMAL)
+
+          TestKt.Preview1
+          spec:parent=_device_class_phone,orientation=landscape
+          PreviewDisplaySettings(name=Preview1 - _device_class_phone-landscape, group=Screen sizes, showDecoration=true, showBackground=false, backgroundColor=null, displayPositioning=NORMAL)
+
+        """
+          .trimIndent(),
+        preview.filteredPreviewElementsInstancesFlowForTest().value.joinToString("\n") {
+          "${it.methodFqn}\n${it.configuration.deviceSpec}\n${it.displaySettings}\n"
+        }
+      )
+
+      // Stop UI Check mode
+      preview.setMode(PreviewMode.Default)
+      delayUntilCondition(250) { preview.isInNormalMode }
 
       // Restart UI Check mode on the same preview
       preview.setMode(PreviewMode.UiCheck(uiCheckElement))
@@ -391,11 +442,7 @@
         )
       }
 
-      val navigationHandler = ComposePreviewNavigationHandler()
-      val mainSurface =
-        NlDesignSurface.builder(project, fixture.testRootDisposable)
-          .setNavigationHandler(navigationHandler)
-          .build()
+      val mainSurface = NlDesignSurface.builder(project, fixture.testRootDisposable).build()
       val modelRenderedLatch = CountDownLatch(2)
 
       mainSurface.addListener(
diff --git a/compose-designer/testSrc/com/android/tools/idea/compose/preview/ComposePreviewViewImplTest.kt b/compose-designer/testSrc/com/android/tools/idea/compose/preview/ComposePreviewViewImplTest.kt
index f22a4b0e..c962290 100644
--- a/compose-designer/testSrc/com/android/tools/idea/compose/preview/ComposePreviewViewImplTest.kt
+++ b/compose-designer/testSrc/com/android/tools/idea/compose/preview/ComposePreviewViewImplTest.kt
@@ -254,6 +254,7 @@
         },
         testPreviewElementModelAdapter,
         DefaultModelUpdater(),
+        navigationHandler = ComposePreviewNavigationHandler(),
         ::configureLayoutlibSceneManagerForPreviewElement
       )
     }
diff --git a/compose-designer/testSrc/com/android/tools/idea/compose/preview/TestComposePreviewManager.kt b/compose-designer/testSrc/com/android/tools/idea/compose/preview/TestComposePreviewManager.kt
index 37272e7..40dcc59 100644
--- a/compose-designer/testSrc/com/android/tools/idea/compose/preview/TestComposePreviewManager.kt
+++ b/compose-designer/testSrc/com/android/tools/idea/compose/preview/TestComposePreviewManager.kt
@@ -51,6 +51,8 @@
 
   override var isFilterEnabled: Boolean = false
 
+  override var isUiCheckFilterEnabled: Boolean = false
+
   override var atfChecksEnabled: Boolean = false
 
   override var mode: PreviewMode = PreviewMode.Default
diff --git a/compose-designer/testSrc/com/android/tools/idea/compose/preview/actions/ComposeViewControlActionTest.kt b/compose-designer/testSrc/com/android/tools/idea/compose/preview/actions/ComposeViewControlActionTest.kt
index 799862d..3a8bfe4 100644
--- a/compose-designer/testSrc/com/android/tools/idea/compose/preview/actions/ComposeViewControlActionTest.kt
+++ b/compose-designer/testSrc/com/android/tools/idea/compose/preview/actions/ComposeViewControlActionTest.kt
@@ -93,7 +93,8 @@
       ComposeViewControlAction(
         EmptyLayoutManagerSwitcher,
         options,
-        onSurfaceLayoutSelected = { _, _ -> }
+        onSurfaceLayoutSelected = { _, _ -> },
+        additionalActionProvider = { _ -> ComposeColorBlindAction(designSurfaceMock) }
       )
     viewControlAction.updateActions(context)
 
@@ -146,7 +147,8 @@
       ComposeViewControlAction(
         EmptyLayoutManagerSwitcher,
         options,
-        onSurfaceLayoutSelected = { _, _ -> }
+        onSurfaceLayoutSelected = { _, _ -> },
+        additionalActionProvider = { _ -> ComposeColorBlindAction(designSurfaceMock) }
       )
     viewControlAction.updateActions(context)
 
@@ -206,7 +208,8 @@
       ComposeViewControlAction(
         EmptyLayoutManagerSwitcher,
         options,
-        onSurfaceLayoutSelected = { _, _ -> }
+        onSurfaceLayoutSelected = { _, _ -> },
+        additionalActionProvider = { _ -> ComposeColorBlindAction(designSurfaceMock) }
       )
     viewControlAction.updateActions(context)
 
@@ -269,7 +272,8 @@
       ComposeViewControlAction(
         EmptyLayoutManagerSwitcher,
         listOf(createOption("Layout A", EmptySurfaceLayoutManager())),
-        onSurfaceLayoutSelected = { _, _ -> }
+        onSurfaceLayoutSelected = { _, _ -> },
+        additionalActionProvider = { _ -> null }
       )
 
     manager.currentStatus = nonRefreshingStatus
@@ -300,7 +304,7 @@
     val option = listOf(SurfaceLayoutManagerOption("Layout A", EmptySurfaceLayoutManager()))
 
     var enabled = true
-    val action = ComposeViewControlAction(switcher, option, { enabled }) { _, _ -> }
+    val action = ComposeViewControlAction(switcher, option, { enabled }, { _, _ -> }) { _ -> null }
     val presentation = Presentation()
 
     // It should always not be multi-choice no matter it is enabled or not.
diff --git a/compose-ide-plugin/resources/messages/ComposeBundle.properties b/compose-ide-plugin/resources/messages/ComposeBundle.properties
index c02d985..e367be5 100644
--- a/compose-ide-plugin/resources/messages/ComposeBundle.properties
+++ b/compose-ide-plugin/resources/messages/ComposeBundle.properties
@@ -33,6 +33,8 @@
 separate.preview.usages=Separate @Preview Usages
 usage.group.in.preview.function=@Preview usages
 usage.group.in.nonpreview.function=Production usages
+compose.color.picker.name=Compose color picker
+compose.color.picker.tooltip=Change color
 
 # British spelling is used to be consistent with KotlinDebuggerCoroutinesBundle.properties optimised.variable.message
 recomposition.optimised.variable.message={0} was optimised out
diff --git a/compose-ide-plugin/src/META-INF/plugin.k2.xml b/compose-ide-plugin/src/META-INF/plugin.k2.xml
index ef6dbc7..1def879 100644
--- a/compose-ide-plugin/src/META-INF/plugin.k2.xml
+++ b/compose-ide-plugin/src/META-INF/plugin.k2.xml
@@ -17,6 +17,5 @@
 <idea-plugin>
   <extensions defaultExtensionNs="org.jetbrains.kotlin">
     <codeinsight.quickfix.registrar implementation="com.android.tools.compose.aa.intentions.ComposeIdePluginQuickFixRegistrar"/>
-    <!-- TODO (b/279035026): K2 Implementation -->
   </extensions>
 </idea-plugin>
diff --git a/compose-ide-plugin/src/META-INF/plugin.xml b/compose-ide-plugin/src/META-INF/plugin.xml
index 74a40d9..187ff98 100644
--- a/compose-ide-plugin/src/META-INF/plugin.xml
+++ b/compose-ide-plugin/src/META-INF/plugin.xml
@@ -31,7 +31,6 @@
   <extensions defaultExtensionNs="com.intellij">
     <dependencySupport coordinate="androidx.compose.runtime:runtime" kind="java" displayName="Jetpack Compose"/>
 
-    <annotator language="kotlin" implementationClass="com.android.tools.compose.ComposeColorAnnotator"/>
     <annotator language="kotlin" implementationClass="com.android.tools.compose.code.ComposeStateReadAnnotator"/>
 
     <additionalTextAttributes scheme="Default" file="colorschemes/ComposableHighlighterExtensionColorSchemeDefault.xml"/>
@@ -156,6 +155,8 @@
 
     <codeInsight.lineMarkerProvider language="kotlin"
                                     implementationClass="com.android.tools.compose.code.ComposeLineMarkerProviderDescriptor" />
+    <codeInsight.lineMarkerProvider language="kotlin"
+                                    implementationClass="com.android.tools.compose.ComposeColorLineMarkerProviderDescriptor" />
 
     <usageGroupingRuleProvider implementation="com.android.tools.compose.ComposeUsageGroupingRuleProvider" />
   </extensions>
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposableElementRefactoringElementListenerProvider.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposableElementRefactoringElementListenerProvider.kt
index 22f6154..44291a9 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/ComposableElementRefactoringElementListenerProvider.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/ComposableElementRefactoringElementListenerProvider.kt
@@ -24,17 +24,17 @@
 import org.jetbrains.kotlin.psi.KtFile
 import org.jetbrains.kotlin.psi.KtNamedFunction
 
-/**
- * Renames KtFile if a @Composable function with the same name was renamed.
- */
+/** Renames KtFile if a @Composable function with the same name was renamed. */
 class ComposableElementAutomaticRenamerFactory : AutomaticRenamerFactory {
 
   override fun isApplicable(element: PsiElement): Boolean {
-    if (element.getModuleSystem()?.usesCompose != true ||
+    if (
+      element.getModuleSystem()?.usesCompose != true ||
         element !is KtNamedFunction ||
         element.parent !is KtFile ||
         !element.isComposableFunction()
-    ) return false
+    )
+      return false
 
     val virtualFile = element.containingKtFile.virtualFile
     return virtualFile?.nameWithoutExtension == element.name
@@ -46,7 +46,11 @@
 
   override fun setEnabled(enabled: Boolean) {}
 
-  override fun createRenamer(element: PsiElement, newName: String?, usages: MutableCollection<UsageInfo>?): AutomaticRenamer {
+  override fun createRenamer(
+    element: PsiElement,
+    newName: String?,
+    usages: MutableCollection<UsageInfo>?
+  ): AutomaticRenamer {
     return object : AutomaticRenamer() {
       init {
         val file = element.containingFile
@@ -56,9 +60,10 @@
 
       override fun getDialogTitle() = ComposeBundle.message("rename.file")
 
-      override fun getDialogDescription() = ComposeBundle.message("rename.files.with.following.names")
+      override fun getDialogDescription() =
+        ComposeBundle.message("rename.files.with.following.names")
 
       override fun entityName() = ComposeBundle.message("file.name")
     }
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposableFunctionExtractableAnalyser.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposableFunctionExtractableAnalyser.kt
index e67ae09..4ff7460 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/ComposableFunctionExtractableAnalyser.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/ComposableFunctionExtractableAnalyser.kt
@@ -31,20 +31,24 @@
 import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
 
 /**
- * Adds [COMPOSABLE_FQ_NAME] annotation to a function when it's extracted from a function annotated with [COMPOSABLE_FQ_NAME]
- * or Composable context.
+ * Adds [COMPOSABLE_FQ_NAME] annotation to a function when it's extracted from a function annotated
+ * with [COMPOSABLE_FQ_NAME] or Composable context.
  */
 class ComposableFunctionExtractableAnalyser : AdditionalExtractableAnalyser {
   /**
-   * Returns @Composable annotation of type of given KtLambdaArgument if there is any otherwise returns null.
+   * Returns @Composable annotation of type of given KtLambdaArgument if there is any otherwise
+   * returns null.
    *
-   * Example: fun myFunction(context: @Composable () -> Unit)
-   * If given [KtLambdaArgument] corresponds to context parameter function returns [AnnotationDescriptor] for @Composable.
+   * Example: fun myFunction(context: @Composable () -> Unit) If given [KtLambdaArgument]
+   * corresponds to context parameter function returns [AnnotationDescriptor] for @Composable.
    */
-  private fun KtLambdaArgument.getComposableAnnotation(bindingContext: BindingContext): AnnotationDescriptor? {
+  private fun KtLambdaArgument.getComposableAnnotation(
+    bindingContext: BindingContext
+  ): AnnotationDescriptor? {
     val callExpression = parent as KtCallExpression
     val resolvedCall = callExpression.getResolvedCall(bindingContext)
-    val argument = (resolvedCall?.getArgumentMapping(this) as? ArgumentMatch)?.valueParameter ?: return null
+    val argument =
+      (resolvedCall?.getArgumentMapping(this) as? ArgumentMatch)?.valueParameter ?: return null
     return argument.type.annotations.findAnnotation(ComposeFqNames.Composable)
   }
 
@@ -56,13 +60,15 @@
     val bindingContext = descriptor.extractionData.bindingContext ?: return descriptor
     val sourceFunction = descriptor.extractionData.targetSibling
     if (sourceFunction is KtAnnotated) {
-      val composableAnnotation = sourceFunction.findAnnotation(ComposeFqNames.Composable)?.resolveToDescriptorIfAny()
+      val composableAnnotation =
+        sourceFunction.findAnnotation(ComposeFqNames.Composable)?.resolveToDescriptorIfAny()
       if (composableAnnotation != null) {
         return descriptor.copy(annotations = descriptor.annotations + composableAnnotation)
       }
     }
     val outsideLambda = descriptor.extractionData.commonParent.parentOfType<KtLambdaArgument>(true)
-    val composableAnnotation = outsideLambda?.getComposableAnnotation(bindingContext) ?: return descriptor
+    val composableAnnotation =
+      outsideLambda?.getComposableAnnotation(bindingContext) ?: return descriptor
     return descriptor.copy(annotations = descriptor.annotations + composableAnnotation)
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposableHighlighterExtension.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposableHighlighterExtension.kt
index c46a77a..e685b8e 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/ComposableHighlighterExtension.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/ComposableHighlighterExtension.kt
@@ -29,35 +29,56 @@
 /**
  * Used to apply styles for calls to @Composable functions.
  *
- * JetBrains documentation recommends doing highlighting such as this using [com.intellij.lang.annotation.Annotator] (guidance available at
- * https://plugins.jetbrains.com/docs/intellij/syntax-highlighting-and-error-highlighting.html#annotator). But it turns out that the Kotlin
- * plugin is running its syntax highlighting using a different mechanism which can run in parallel with annotators. That doesn't matter for
- * annotators that don't conflict with the built-in highlighting, but in the case of Compose we are overriding some of the standard function
- * colors, and so we need to ensure that Compose highlighting takes precedence.
+ * JetBrains documentation recommends doing highlighting such as this using
+ * [com.intellij.lang.annotation.Annotator] (guidance available at
+ * https://plugins.jetbrains.com/docs/intellij/syntax-highlighting-and-error-highlighting.html#annotator).
+ * But it turns out that the Kotlin plugin is running its syntax highlighting using a different
+ * mechanism which can run in parallel with annotators. That doesn't matter for annotators that
+ * don't conflict with the built-in highlighting, but in the case of Compose we are overriding some
+ * of the standard function colors, and so we need to ensure that Compose highlighting takes
+ * precedence.
  *
- * Luckily, the Kotlin plugin provides its own extension mechanism, which is implemented here with [HighlighterExtension]. When this code
- * returns Composable function highlighting for a given method call, it will always be used instead of the default Kotlin highlighting.
+ * Luckily, the Kotlin plugin provides its own extension mechanism, which is implemented here with
+ * [HighlighterExtension]. When this code returns Composable function highlighting for a given
+ * method call, it will always be used instead of the default Kotlin highlighting.
  */
 class ComposableHighlighterExtension : KotlinHighlightingVisitorExtension() {
   companion object {
     const val COMPOSABLE_CALL_TEXT_ATTRIBUTES_NAME = "ComposableCallTextAttributes"
     val COMPOSABLE_CALL_TEXT_ATTRIBUTES_KEY: TextAttributesKey =
-      TextAttributesKey.createTextAttributesKey(COMPOSABLE_CALL_TEXT_ATTRIBUTES_NAME, DefaultLanguageHighlighterColors.FUNCTION_CALL)
-    val COMPOSABLE_CALL_TEXT_TYPE: HighlightInfoType = HighlightInfoType.HighlightInfoTypeImpl(HighlightInfoType.SYMBOL_TYPE_SEVERITY, COMPOSABLE_CALL_TEXT_ATTRIBUTES_KEY, false)
+      TextAttributesKey.createTextAttributesKey(
+        COMPOSABLE_CALL_TEXT_ATTRIBUTES_NAME,
+        DefaultLanguageHighlighterColors.FUNCTION_CALL
+      )
+    val COMPOSABLE_CALL_TEXT_TYPE: HighlightInfoType =
+      HighlightInfoType.HighlightInfoTypeImpl(
+        HighlightInfoType.SYMBOL_TYPE_SEVERITY,
+        COMPOSABLE_CALL_TEXT_ATTRIBUTES_KEY,
+        false
+      )
   }
 
-  override fun highlightDeclaration(elementToHighlight: PsiElement, descriptor: DeclarationDescriptor): HighlightInfoType? = null
+  override fun highlightDeclaration(
+    elementToHighlight: PsiElement,
+    descriptor: DeclarationDescriptor
+  ): HighlightInfoType? = null
 
-  override fun highlightCall(elementToHighlight: PsiElement, resolvedCall: ResolvedCall<*>): HighlightInfoType? {
+  override fun highlightCall(
+    elementToHighlight: PsiElement,
+    resolvedCall: ResolvedCall<*>
+  ): HighlightInfoType? {
     if (!resolvedCall.isComposableInvocation()) return null
 
     // For composable invocations, highlight if either:
     // 1. compose is enabled for the current module, or
     // 2. the file is part of a library's source code.
-    return if (isComposeEnabled(elementToHighlight) || isInLibrarySource(elementToHighlight)) COMPOSABLE_CALL_TEXT_TYPE else null
+    return if (isComposeEnabled(elementToHighlight) || isInLibrarySource(elementToHighlight))
+      COMPOSABLE_CALL_TEXT_TYPE
+    else null
   }
 
   private fun isInLibrarySource(element: PsiElement) =
     element.containingFile.virtualFile != null &&
-    ProjectFileIndex.getInstance(element.project).isInLibrarySource(element.containingFile.virtualFile)
+      ProjectFileIndex.getInstance(element.project)
+        .isInLibrarySource(element.containingFile.virtualFile)
 }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposableIconProvider.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposableIconProvider.kt
index 51aa796..7a5b12a 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/ComposableIconProvider.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/ComposableIconProvider.kt
@@ -19,16 +19,17 @@
 import com.intellij.psi.PsiElement
 import com.intellij.ui.RowIcon
 import icons.StudioIcons.Compose.Editor.COMPOSABLE_FUNCTION
+import javax.swing.Icon
 import org.jetbrains.kotlin.idea.KotlinIconProvider
 import org.jetbrains.kotlin.idea.util.hasMatchingExpected
 import org.jetbrains.kotlin.psi.KtDeclaration
 import org.jetbrains.kotlin.psi.KtFunction
 import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
-import javax.swing.Icon
 
 /**
- * Returns Composable function icon for [KtFunction] elements that are composable, or null otherwise to allow fallback to any
- * other providers. This may be used in various places across the IDE; one example is in the "Add Import" menu.
+ * Returns Composable function icon for [KtFunction] elements that are composable, or null otherwise
+ * to allow fallback to any other providers. This may be used in various places across the IDE; one
+ * example is in the "Add Import" menu.
  */
 class ComposableIconProvider : KotlinIconProvider() {
 
@@ -48,8 +49,9 @@
     return declaration.hasActualModifier() && declaration.hasMatchingExpected()
   }
 
-  private fun createRowIcon(baseIcon: Icon, visibilityIcon: Icon): RowIcon = RowIcon(2).apply {
-    setIcon(baseIcon, /* layer = */ 0)
-    setIcon(visibilityIcon, /* layer = */ 1)
-  }
+  private fun createRowIcon(baseIcon: Icon, visibilityIcon: Icon): RowIcon =
+    RowIcon(2).apply {
+      setIcon(baseIcon, /* layer = */ 0)
+      setIcon(visibilityIcon, /* layer = */ 1)
+    }
 }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposableItemPresentationProvider.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposableItemPresentationProvider.kt
index 1434e6a..9ecc30c 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/ComposableItemPresentationProvider.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/ComposableItemPresentationProvider.kt
@@ -22,10 +22,11 @@
 import org.jetbrains.kotlin.psi.KtFunction
 
 /**
- * [ItemPresentationProvider] which overrides default behavior for displaying a method in a menu (eg, in "Add Imports").
+ * [ItemPresentationProvider] which overrides default behavior for displaying a method in a menu
+ * (eg, in "Add Imports").
  *
- * Composable methods will be displayed as "@Composable FunctionName". Other functions will maintain default display text (ie,
- * "functionName(arg1, arg2)".
+ * Composable methods will be displayed as "@Composable FunctionName". Other functions will maintain
+ * default display text (ie, "functionName(arg1, arg2)".
  */
 class ComposableItemPresentationProvider : ItemPresentationProvider<KtFunction> {
   override fun getPresentation(function: KtFunction): ItemPresentation? {
@@ -37,10 +38,11 @@
   }
 
   /**
-   * Presentation for composable functions. Based on the default [KotlinFunctionPresentation], with modifications to how the function name
-   * is presented.
-   * */
-  private class ComposableFunctionPresentation(private val function: KtFunction) : KotlinFunctionPresentation(function) {
+   * Presentation for composable functions. Based on the default [KotlinFunctionPresentation], with
+   * modifications to how the function name is presented.
+   */
+  private class ComposableFunctionPresentation(private val function: KtFunction) :
+    KotlinFunctionPresentation(function) {
     override fun getPresentableText(): String {
       return buildString {
         append("@Composable")
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposeAutoDocumentation.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposeAutoDocumentation.kt
index 4a671e8..0dd9f54 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/ComposeAutoDocumentation.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/ComposeAutoDocumentation.kt
@@ -33,32 +33,33 @@
 import com.intellij.openapi.startup.StartupActivity
 import com.intellij.psi.PsiElement
 import com.intellij.util.Alarm
+import java.beans.PropertyChangeListener
 import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject
 import org.jetbrains.kotlin.psi.KtNamedFunction
 import org.jetbrains.kotlin.psi.psiUtil.containingClass
-import java.beans.PropertyChangeListener
 
-/**
- * Automatically shows quick documentation for Compose functions during code completion
- */
+/** Automatically shows quick documentation for Compose functions during code completion */
 class ComposeAutoDocumentation(private val project: Project) {
   private var documentationOpenedByCompose = false
 
   private val lookupListener = PropertyChangeListener { evt ->
-    if (LookupManager.PROP_ACTIVE_LOOKUP == evt.propertyName &&
-        evt.newValue is Lookup) {
+    if (LookupManager.PROP_ACTIVE_LOOKUP == evt.propertyName && evt.newValue is Lookup) {
       val lookup = evt.newValue as Lookup
 
-      val moduleSystem = FileDocumentManager.getInstance().getFile(lookup.editor.document)
-        ?.let { ModuleUtilCore.findModuleForFile(it, lookup.project) }
-        ?.getModuleSystem()
+      val moduleSystem =
+        FileDocumentManager.getInstance()
+          .getFile(lookup.editor.document)
+          ?.let { ModuleUtilCore.findModuleForFile(it, lookup.project) }
+          ?.getModuleSystem()
 
       if (moduleSystem?.usesCompose == true) {
-        lookup.addLookupListener(object : LookupListener {
-          override fun currentItemChanged(event: LookupEvent) {
-            showJavaDoc(lookup)
+        lookup.addLookupListener(
+          object : LookupListener {
+            override fun currentItemChanged(event: LookupEvent) {
+              showJavaDoc(lookup)
+            }
           }
-        })
+        )
       }
     }
   }
@@ -75,15 +76,17 @@
 
   companion object {
     @JvmStatic
-    fun getInstance(project: Project): ComposeAutoDocumentation = project.getService(ComposeAutoDocumentation::class.java)
+    fun getInstance(project: Project): ComposeAutoDocumentation =
+      project.getService(ComposeAutoDocumentation::class.java)
 
     @VisibleForTesting
     internal fun PsiElement?.shouldShowDocumentation(): Boolean =
       when {
         this == null -> false
         isComposableFunction() -> true
-        this is KtNamedFunction -> receiverTypeReference?.text == "androidx.compose.ui.Modifier" ||
-                                   containingClass()?.fqName?.asString() == "androidx.compose.ui.Modifier"
+        this is KtNamedFunction ->
+          receiverTypeReference?.text == "androidx.compose.ui.Modifier" ||
+            containingClass()?.fqName?.asString() == "androidx.compose.ui.Modifier"
         else -> false
       }
   }
@@ -99,18 +102,26 @@
       return
     }
 
-    // If we open doc when lookup is not visible, doc will have wrong parent window (editor window instead of lookup).
+    // If we open doc when lookup is not visible, doc will have wrong parent window (editor window
+    // instead of lookup).
     if ((lookup as? LookupImpl)?.isVisible != true) {
-      Alarm().addRequest({ showJavaDoc(lookup) }, CodeInsightSettings.getInstance().JAVADOC_INFO_DELAY)
+      Alarm()
+        .addRequest({ showJavaDoc(lookup) }, CodeInsightSettings.getInstance().JAVADOC_INFO_DELAY)
       return
     }
 
     val docManager = DocumentationManager.getInstance(project)
-    val psiElement = lookup.currentItem?.let { it.psiElement ?: (it.`object` as? DeclarationLookupObject)?.psiElement }
+    val psiElement =
+      lookup.currentItem?.let {
+        it.psiElement ?: (it.`object` as? DeclarationLookupObject)?.psiElement
+      }
     if (!psiElement.shouldShowDocumentation()) {
-      // Close documentation for not composable function if it was opened by [AndroidComposeAutoDocumentation].
-      // Case docManager.docInfoHint?.isFocused == true: user clicked on doc window and after that clicked on lookup and selected another
-      // element. Due to bug docManager.docInfoHint?.isFocused == true even after clicking on lookup element, in that case if we close
+      // Close documentation for not composable function if it was opened by
+      // [AndroidComposeAutoDocumentation].
+      // Case docManager.docInfoHint?.isFocused == true: user clicked on doc window and after that
+      // clicked on lookup and selected another
+      // element. Due to bug docManager.docInfoHint?.isFocused == true even after clicking on lookup
+      // element, in that case if we close
       // docManager.docInfoHint, lookup will be closed as well.
       if (documentationOpenedByCompose && docManager.docInfoHint?.isFocused == false) {
         docManager.docInfoHint?.cancel()
@@ -120,18 +131,20 @@
     }
 
     // It's composable function and documentation already opened
-    if (docManager.docInfoHint != null) return  // will auto-update
+    if (docManager.docInfoHint != null) return // will auto-update
 
     val currentItem = lookup.currentItem
-    if (currentItem != null && currentItem.isValid && CompletionService.getCompletionService().currentCompletion != null) {
+    if (
+      currentItem != null &&
+        currentItem.isValid &&
+        CompletionService.getCompletionService().currentCompletion != null
+    ) {
       try {
         docManager.showJavaDocInfo(lookup.editor, lookup.psiFile, false) {
           documentationOpenedByCompose = false
         }
         documentationOpenedByCompose = true
-      }
-      catch (ignored: IndexNotReadyException) {
-      }
+      } catch (ignored: IndexNotReadyException) {}
     }
   }
 }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposeBundle.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposeBundle.kt
index 97720aa..44f41f7 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/ComposeBundle.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/ComposeBundle.kt
@@ -16,10 +16,10 @@
 package com.android.tools.compose
 
 import com.intellij.AbstractBundle
-import org.jetbrains.annotations.PropertyKey
 import java.lang.ref.Reference
 import java.lang.ref.SoftReference
 import java.util.ResourceBundle
+import org.jetbrains.annotations.PropertyKey
 
 private const val BUNDLE_NAME = "messages.ComposeBundle"
 
@@ -37,8 +37,11 @@
     }
 
     @JvmStatic
-    fun message(@PropertyKey(resourceBundle = BUNDLE_NAME) key: String, vararg params: Any?): String {
+    fun message(
+      @PropertyKey(resourceBundle = BUNDLE_NAME) key: String,
+      vararg params: Any?
+    ): String {
       return AbstractBundle.message(getBundle(), key, *params)
     }
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposeColorAnnotator.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposeColorAnnotator.kt
deleted file mode 100644
index 4a36664..0000000
--- a/compose-ide-plugin/src/com/android/tools/compose/ComposeColorAnnotator.kt
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tools.compose
-
-import com.android.ide.common.rendering.api.ResourceReference
-import com.android.tools.adtui.LightCalloutPopup
-import com.android.tools.idea.projectsystem.getModuleSystem
-import com.android.tools.idea.ui.resourcechooser.colorpicker2.ColorPickerBuilder
-import com.android.tools.idea.ui.resourcechooser.colorpicker2.ColorPickerListener
-import com.android.tools.idea.ui.resourcechooser.colorpicker2.internal.MaterialColorPaletteProvider
-import com.android.tools.idea.ui.resourcechooser.colorpicker2.internal.MaterialGraphicalColorPipetteProvider
-import com.intellij.lang.annotation.AnnotationHolder
-import com.intellij.lang.annotation.Annotator
-import com.intellij.lang.annotation.HighlightSeverity
-import com.intellij.openapi.actionSystem.AnAction
-import com.intellij.openapi.actionSystem.AnActionEvent
-import com.intellij.openapi.actionSystem.CommonDataKeys
-import com.intellij.openapi.application.ApplicationManager
-import com.intellij.openapi.command.WriteCommandAction
-import com.intellij.openapi.editor.markup.GutterIconRenderer
-import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiTypes
-import com.intellij.util.ui.ColorIcon
-import org.jetbrains.annotations.VisibleForTesting
-import org.jetbrains.kotlin.analysis.api.analyze
-import org.jetbrains.kotlin.analysis.api.components.KtConstantEvaluationMode
-import org.jetbrains.kotlin.idea.base.plugin.isK2Plugin
-import org.jetbrains.kotlin.idea.inspections.AbstractRangeInspection.Companion.constantValueOrNull
-import org.jetbrains.kotlin.psi.KtCallElement
-import org.jetbrains.kotlin.psi.KtCallExpression
-import org.jetbrains.kotlin.psi.KtExpression
-import org.jetbrains.kotlin.psi.KtPsiFactory
-import org.jetbrains.kotlin.psi.KtValueArgument
-import org.jetbrains.uast.UCallExpression
-import org.jetbrains.uast.UElement
-import org.jetbrains.uast.UExpression
-import org.jetbrains.uast.UastCallKind
-import org.jetbrains.uast.toUElement
-import java.awt.Color
-import java.awt.MouseInfo
-import java.util.Locale
-import javax.swing.Icon
-
-private const val ICON_SIZE = 8
-
-/**
- * [Annotator] to place color gutter icons for compose color declarations.
- * It does this by looking at the parameters of the Color() method and so does not work is the parameters are references.
- * It also does not work predefined colors. eg. Color.White
- */
-class ComposeColorAnnotator : Annotator {
-
-  override fun annotate(element: PsiElement, holder: AnnotationHolder) {
-    when {
-      element.getModuleSystem()?.usesCompose != true -> return
-      element is KtCallElement -> {
-        val uElement = element.toUElement(UCallExpression::class.java) ?: return
-        val returnType = uElement.returnType ?: return
-        if (uElement.kind != UastCallKind.METHOD_CALL || returnType != PsiTypes.longType() || COLOR_METHOD != uElement.methodName) {
-          return
-        }
-
-        // Resolve the MethodCall expression after the faster checks
-        val fqName = uElement.resolve()?.containingClass?.qualifiedName ?: return
-        if (fqName == COMPOSE_COLOR_CLASS) {
-          val color = getColor(uElement) ?: return
-          holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
-            .gutterIconRenderer(ColorIconRenderer(uElement, color))
-            .create()
-        }
-      }
-    }
-  }
-
-  private fun getColor(uElement: UElement): Color? {
-    val callElement = uElement as? UCallExpression ?: return null
-    val arguments = (uElement.sourcePsi as? KtCallExpression)?.valueArguments ?: return null
-    return when (getConstructorType(callElement.valueArguments)) {
-      ComposeColorConstructor.INT -> getColorInt(arguments)
-      ComposeColorConstructor.LONG -> getColorLong(arguments)
-      ComposeColorConstructor.INT_X3 -> getColorIntX3(arguments)
-      ComposeColorConstructor.INT_X4 -> getColorIntX4(arguments)
-      ComposeColorConstructor.FLOAT_X3 -> getColorFloatX3(arguments)
-      ComposeColorConstructor.FLOAT_X4 -> getColorFloatX4(arguments)
-      // TODO: Provide the color preview for ComposeColorConstructor.FLOAT_X4_COLORSPACE constructor.
-      ComposeColorConstructor.FLOAT_X4_COLORSPACE -> null
-      else -> null
-    }
-  }
-}
-
-/**
- * Simplified version of [AndroidAnnotatorUtil.ColorRenderer] that does not work on [ResourceReference] but still displays the same color
- * picker.
- * TODO(lukeegan): Implement for ComposeColorConstructor.FLOAT_X4_COLORSPACE Color parameter
- */
-data class ColorIconRenderer(val element: UCallExpression, val color: Color) : GutterIconRenderer() {
-
-  override fun getIcon(): Icon {
-    return ColorIcon(ICON_SIZE, color)
-  }
-
-  override fun getClickAction(): AnAction? {
-    val project = element.sourcePsi?.project ?: return null
-    val setColorTask: (Color) -> Unit = getSetColorTask() ?: return null
-
-    val pickerListener = ColorPickerListener { color, _ ->
-      ApplicationManager.getApplication().invokeLater({
-        WriteCommandAction.runWriteCommandAction(project, "Change Color", null, { setColorTask.invoke(color) })
-      }, project.disposed)
-    }
-    return object : AnAction() {
-      override fun actionPerformed(e: AnActionEvent) {
-        val editor = e.getData(CommonDataKeys.EDITOR)
-        if (editor != null) {
-          val dialog = LightCalloutPopup()
-          val colorPicker = ColorPickerBuilder()
-            .setOriginalColor(color)
-            .addSaturationBrightnessComponent()
-            .addColorAdjustPanel(MaterialGraphicalColorPipetteProvider())
-            .addColorValuePanel().withFocus()
-            .addSeparator()
-            .addCustomComponent(MaterialColorPaletteProvider)
-            .addColorPickerListener(pickerListener)
-            .focusWhenDisplay(true)
-            .setFocusCycleRoot(true)
-            .build()
-          dialog.show(colorPicker, null, MouseInfo.getPointerInfo().location)
-        }
-      }
-    }
-  }
-
-  @VisibleForTesting
-  fun getSetColorTask(): ((Color) -> Unit)? {
-    val ktCallExpression = element.sourcePsi as? KtCallExpression ?: return null
-    val constructorType = getConstructorType(element.valueArguments) ?: return null
-    // No matter what the original format is, we make the format become one of:
-    // - (0xAARRGGBB)
-    // - (color = 0xAARRGGBB)
-    // or
-    // - ([0..255], [0..255], [0..255], [0.255])
-    // - (red = [0..255], green = [0..255], blue = [0..255], alpha = [0.255])
-    // or
-    // - ([0x00..0xFF], [0x00..0xFF], [0x00..0xFF], [0x00..0xFF])
-    // - (red = [0x00..0xFF], green =[0x00..0xFF], blue = [0x00..0xFF], alpha = [0x00..0xFF])
-    // or
-    // - ([0.0f..1.0f], [0.0f..1.0f], [0.0f..1.0f], [0.0f..1.0f])
-    // - (red = [0.0f..1.0f], green = [0.0f..1.0f], blue = [0.0f..1.0f], alpha = [0.0f..1.0f])
-    // , depends on the original value type and numeral system.
-    return when(constructorType) {
-      ComposeColorConstructor.INT,
-      ComposeColorConstructor.LONG -> { color: Color ->
-        val valueArgumentList = ktCallExpression.valueArgumentList
-        if (valueArgumentList != null) {
-          val needsArgumentName = valueArgumentList.arguments.any { it.getArgumentName() != null }
-          val hexString = "0x${String.format("%08X", color.rgb)}"
-          val argumentText = if (needsArgumentName) "(color = $hexString)" else "($hexString)"
-          valueArgumentList.replace(KtPsiFactory(ktCallExpression.project).createCallArguments(argumentText))
-        }
-      }
-      ComposeColorConstructor.INT_X3,
-      ComposeColorConstructor.INT_X4 -> { color: Color ->
-        val valueArgumentList = ktCallExpression.valueArgumentList
-        if (valueArgumentList != null) {
-          val needsArgumentName = valueArgumentList.arguments.any { it.getArgumentName() != null }
-          val hasHexFormat = valueArgumentList.arguments.any { it.getArgumentExpression()?.text?.startsWith("0x") ?: false }
-          val red = if (hasHexFormat) color.red.toHexString() else color.red.toString()
-          val green = if (hasHexFormat) color.green.toHexString() else color.green.toString()
-          val blue = if (hasHexFormat) color.blue.toHexString() else color.blue.toString()
-          val alpha = if (hasHexFormat) color.alpha.toHexString() else color.alpha.toString()
-
-          val argumentText =
-            if (needsArgumentName) "(red = $red, green = $green, blue = $blue, alpha = $alpha)" else "($red, $green, $blue, $alpha)"
-          valueArgumentList.replace(KtPsiFactory(ktCallExpression.project).createCallArguments(argumentText))
-        }
-      }
-      ComposeColorConstructor.FLOAT_X3,
-      ComposeColorConstructor.FLOAT_X4 -> { color: Color ->
-        val valueArgumentList = ktCallExpression.valueArgumentList
-        if (valueArgumentList != null) {
-          val needsArgumentName = valueArgumentList.arguments.any { it.getArgumentName() != null }
-          val red = (color.red / 255f).toRoundString()
-          val green = (color.green / 255f).toRoundString()
-          val blue = (color.blue / 255f).toRoundString()
-          val alpha = (color.alpha / 255f).toRoundString()
-
-          val argumentText =
-            if (needsArgumentName) "(red = ${red}f, green = ${green}f, blue = ${blue}f, alpha = ${alpha}f)"
-            else "(${red}f, ${green}f, ${blue}f, ${alpha}f)"
-          valueArgumentList.replace(KtPsiFactory(ktCallExpression.project).createCallArguments(argumentText))
-        }
-      }
-      ComposeColorConstructor.FLOAT_X4_COLORSPACE -> null // TODO: support ComposeColorConstructor.FLOAT_X4_COLORSPACE in the future.
-    }
-  }
-}
-
-private const val COLOR_METHOD = "Color"
-private const val COMPOSE_COLOR_CLASS = "androidx.compose.ui.graphics.ColorKt"
-
-private const val ARG_NAME_RED = "red"
-private const val ARG_NAME_GREEN = "green"
-private const val ARG_NAME_BLUE = "blue"
-private const val ARG_NAME_ALPHA = "alpha"
-
-private val ARGS_RGB = listOf(ARG_NAME_RED, ARG_NAME_GREEN, ARG_NAME_BLUE)
-private val ARGS_RGBA = listOf(ARG_NAME_RED, ARG_NAME_GREEN, ARG_NAME_BLUE, ARG_NAME_ALPHA)
-
-enum class ComposeColorConstructor {
-  INT, LONG, INT_X3, INT_X4, FLOAT_X3, FLOAT_X4, FLOAT_X4_COLORSPACE
-}
-
-private fun getColorInt(arguments: List<KtValueArgument>): Color? {
-  val colorValue = arguments.first().getArgumentExpression()?.evaluateToConstantOrNull<Int>() ?: return null
-  return Color(colorValue, true)
-}
-
-private fun getColorLong(arguments: List<KtValueArgument>): Color? {
-  val colorValue = arguments.first().getArgumentExpression()?.evaluateToConstantOrNull<Long>() ?: return null
-  return Color(colorValue.toInt(), true)
-}
-
-private fun getColorIntX3(arguments: List<KtValueArgument>): Color? {
-  val rgbValues = getNamedValues<Int>(ARGS_RGB, arguments) ?: return null
-  return intColorMapToColor(rgbValues)
-}
-
-private fun getColorIntX4(arguments: List<KtValueArgument>): Color? {
-  val rgbaValues = getNamedValues<Int>(ARGS_RGBA, arguments) ?: return null
-  return intColorMapToColor(rgbaValues)
-}
-
-private fun getColorFloatX3(arguments: List<KtValueArgument>): Color? {
-  val rgbValues = getNamedValues<Float>(ARGS_RGB, arguments) ?: return null
-  return floatColorMapToColor(rgbValues)
-}
-
-private fun getColorFloatX4(arguments: List<KtValueArgument>): Color? {
-  val rgbaValues = getNamedValues<Float>(ARGS_RGBA, arguments) ?: return null
-  return floatColorMapToColor(rgbaValues)
-}
-
-/**
- * This function return the name-value pair for the request arguments names by extracting the given ktValueArguments.
- */
-private inline fun <reified T> getNamedValues(requestArgumentNames: List<String>, ktValueArgument: List<KtValueArgument>): Map<String, T>? {
-  val namedValues = mutableMapOf<String, T>()
-
-  val unnamedValue = mutableListOf<T>()
-  for (argument in ktValueArgument) {
-    val (name, value) = getArgumentNameValuePair<T>(argument) ?: return null
-    if (name != null) {
-      namedValues[name] = value
-    }
-    else {
-      unnamedValue.add(value)
-    }
-  }
-
-  val unnamedArgument = requestArgumentNames.filterNot { it in namedValues.keys }.toList()
-  if (unnamedArgument.size != unnamedValue.size) {
-    // The number of argument values doesn't match the given KtValueArgument.
-    return null
-  }
-
-  for (index in unnamedArgument.indices) {
-    // Fill the unnamed argument value from KtValueArgument.
-    namedValues[unnamedArgument[index]] = unnamedValue[index]
-  }
-  if (namedValues.keys != requestArgumentNames.toSet()) {
-    // Has the redundant or missed argument(s).
-    return null
-  }
-  return namedValues
-}
-
-private inline fun <reified T> getArgumentNameValuePair(valueArgument: KtValueArgument): Pair<String?, T>? {
-    val name = valueArgument.getArgumentName()?.asName?.asString()
-    val value = valueArgument.getArgumentExpression()?.evaluateToConstantOrNull<T>() ?: return null
-    return name to value
-}
-
-private inline fun <reified T> KtExpression.evaluateToConstantOrNull(): T? {
-  return if (isK2Plugin()) {
-    analyze(this) {
-      evaluate(KtConstantEvaluationMode.CONSTANT_EXPRESSION_EVALUATION)?.value as? T ?: return null
-    }
-  } else {
-    constantValueOrNull()?.value as? T ?: return null
-  }
-}
-
-private fun Int.toHexString(): String = "0x${(Integer.toHexString(this)).uppercase(Locale.getDefault())}"
-
-// Note: toFloat() then toString() is for removing the tail zero(s).
-private fun Float.toRoundString(decimals: Int = 3): String = "%.${decimals}f".format(this).toFloat().toString()
-
-private typealias IntColorMap = Map<String, Int>
-private fun intColorMapToColor(intColorMap: IntColorMap): Color? {
-  val red = intColorMap[ARG_NAME_RED] ?: return null
-  val green = intColorMap[ARG_NAME_GREEN] ?: return null
-  val blue = intColorMap[ARG_NAME_BLUE] ?: return null
-  val alpha = intColorMap[ARG_NAME_ALPHA]
-  return if (alpha == null) Color(red, green, blue) else Color(red, green, blue, alpha)
-}
-
-private typealias FloatColorMap = Map<String, Float>
-private fun floatColorMapToColor(floatColorMap: FloatColorMap): Color? {
-  val red = floatColorMap[ARG_NAME_RED] ?: return null
-  val green = floatColorMap[ARG_NAME_GREEN] ?: return null
-  val blue = floatColorMap[ARG_NAME_BLUE] ?: return null
-  val alpha = floatColorMap[ARG_NAME_ALPHA]
-  return if (alpha == null) Color(red, green, blue) else Color(red, green, blue, alpha)
-}
-
-private fun getConstructorType(arguments: List<UExpression>): ComposeColorConstructor? {
-  val paramType = arguments.firstOrNull()?.getExpressionType() ?: return null
-  return when (arguments.size) {
-    1 -> if (PsiTypes.intType() == paramType) ComposeColorConstructor.INT else ComposeColorConstructor.LONG
-    3 -> if (PsiTypes.intType() == paramType) ComposeColorConstructor.INT_X3 else ComposeColorConstructor.FLOAT_X3
-    4 -> if (PsiTypes.intType() == paramType) ComposeColorConstructor.INT_X4 else ComposeColorConstructor.FLOAT_X4
-    5 -> ComposeColorConstructor.FLOAT_X4_COLORSPACE
-    else -> null
-  }
-}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposeColorLineMarkerProviderDescriptor.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposeColorLineMarkerProviderDescriptor.kt
new file mode 100644
index 0000000..deb3303
--- /dev/null
+++ b/compose-ide-plugin/src/com/android/tools/compose/ComposeColorLineMarkerProviderDescriptor.kt
@@ -0,0 +1,378 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.compose
+
+import com.android.ide.common.rendering.api.ResourceReference
+import com.android.tools.adtui.LightCalloutPopup
+import com.android.tools.idea.ui.resourcechooser.colorpicker2.ColorPickerBuilder
+import com.android.tools.idea.ui.resourcechooser.colorpicker2.ColorPickerListener
+import com.android.tools.idea.ui.resourcechooser.colorpicker2.internal.MaterialColorPaletteProvider
+import com.android.tools.idea.ui.resourcechooser.colorpicker2.internal.MaterialGraphicalColorPipetteProvider
+import com.intellij.codeInsight.daemon.GutterIconNavigationHandler
+import com.intellij.codeInsight.daemon.LineMarkerInfo
+import com.intellij.codeInsight.daemon.LineMarkerProviderDescriptor
+import com.intellij.openapi.application.ApplicationManager
+import com.intellij.openapi.command.WriteCommandAction
+import com.intellij.openapi.editor.markup.GutterIconRenderer
+import com.intellij.psi.PsiElement
+import com.intellij.psi.PsiTypes
+import com.intellij.psi.util.elementType
+import com.intellij.util.ui.ColorIcon
+import java.awt.Color
+import java.awt.MouseInfo
+import java.awt.event.MouseEvent
+import java.util.Locale
+import org.jetbrains.annotations.VisibleForTesting
+import org.jetbrains.kotlin.analysis.api.analyze
+import org.jetbrains.kotlin.analysis.api.components.KtConstantEvaluationMode
+import org.jetbrains.kotlin.idea.base.plugin.isK2Plugin
+import org.jetbrains.kotlin.idea.editor.fixers.range
+import org.jetbrains.kotlin.idea.inspections.AbstractRangeInspection.Companion.constantValueOrNull
+import org.jetbrains.kotlin.lexer.KtTokens
+import org.jetbrains.kotlin.psi.KtCallExpression
+import org.jetbrains.kotlin.psi.KtExpression
+import org.jetbrains.kotlin.psi.KtPsiFactory
+import org.jetbrains.kotlin.psi.KtValueArgument
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UExpression
+import org.jetbrains.uast.UastCallKind
+import org.jetbrains.uast.toUElement
+
+private const val ICON_SIZE = 8
+
+class ComposeColorLineMarkerProviderDescriptor : LineMarkerProviderDescriptor() {
+  override fun getName() = ComposeBundle.message("compose.color.picker.name")
+
+  override fun getLineMarkerInfo(element: PsiElement): LineMarkerInfo<*>? {
+    if (element.elementType != KtTokens.IDENTIFIER || !isComposeEnabled(element)) return null
+
+    val uElement =
+      (element.parent.parent as? KtCallExpression)?.toUElement(UCallExpression::class.java)
+        ?: return null
+    if (!uElement.isColorCall()) return null
+
+    val color = getColor(uElement) ?: return null
+    val iconRenderer = ColorIconRenderer(uElement, color)
+    return LineMarkerInfo(
+      element,
+      element.range,
+      iconRenderer.icon,
+      { ComposeBundle.message("compose.color.picker.tooltip") },
+      iconRenderer,
+      GutterIconRenderer.Alignment.RIGHT,
+      { ComposeBundle.message("compose.color.picker.tooltip") },
+    )
+  }
+
+  private fun UCallExpression.isColorCall() =
+    kind == UastCallKind.METHOD_CALL &&
+      returnType == PsiTypes.longType() &&
+      COLOR_METHOD == methodName &&
+      // Resolve the MethodCall expression after the faster checks
+      resolve()?.containingClass?.qualifiedName == COMPOSE_COLOR_CLASS
+
+  private fun getColor(uElement: UCallExpression): Color? {
+    val arguments = (uElement.sourcePsi as? KtCallExpression)?.valueArguments ?: return null
+    return when (getConstructorType(uElement.valueArguments)) {
+      ComposeColorConstructor.INT -> getColorInt(arguments)
+      ComposeColorConstructor.LONG -> getColorLong(arguments)
+      ComposeColorConstructor.INT_X3 -> getColorIntX3(arguments)
+      ComposeColorConstructor.INT_X4 -> getColorIntX4(arguments)
+      ComposeColorConstructor.FLOAT_X3 -> getColorFloatX3(arguments)
+      ComposeColorConstructor.FLOAT_X4 -> getColorFloatX4(arguments)
+      // TODO: Provide the color preview for ComposeColorConstructor.FLOAT_X4_COLORSPACE
+      // constructor.
+      ComposeColorConstructor.FLOAT_X4_COLORSPACE -> null
+      else -> null
+    }
+  }
+}
+
+/**
+ * Simplified version of [AndroidAnnotatorUtil.ColorRenderer] that does not work on
+ * [ResourceReference] but still displays the same color picker.
+ *
+ * TODO(lukeegan): Implement for ComposeColorConstructor.FLOAT_X4_COLORSPACE Color parameter
+ */
+data class ColorIconRenderer(val element: UCallExpression, val color: Color) :
+  GutterIconNavigationHandler<PsiElement> {
+
+  val icon = ColorIcon(ICON_SIZE, color)
+
+  override fun navigate(e: MouseEvent?, elt: PsiElement?) {
+    val project = element.sourcePsi?.project ?: return
+    val setColorTask: (Color) -> Unit = getSetColorTask() ?: return
+
+    val pickerListener = ColorPickerListener { color, _ ->
+      ApplicationManager.getApplication()
+        .invokeLater(
+          {
+            WriteCommandAction.runWriteCommandAction(
+              project,
+              "Change Color",
+              null,
+              { setColorTask.invoke(color) }
+            )
+          },
+          project.disposed
+        )
+    }
+
+    val dialog = LightCalloutPopup()
+    val colorPicker =
+      ColorPickerBuilder()
+        .setOriginalColor(color)
+        .addSaturationBrightnessComponent()
+        .addColorAdjustPanel(MaterialGraphicalColorPipetteProvider())
+        .addColorValuePanel()
+        .withFocus()
+        .addSeparator()
+        .addCustomComponent(MaterialColorPaletteProvider)
+        .addColorPickerListener(pickerListener)
+        .focusWhenDisplay(true)
+        .setFocusCycleRoot(true)
+        .build()
+    dialog.show(colorPicker, null, MouseInfo.getPointerInfo().location)
+  }
+
+  @VisibleForTesting
+  fun getSetColorTask(): ((Color) -> Unit)? {
+    val ktCallExpression = element.sourcePsi as? KtCallExpression ?: return null
+    val constructorType = getConstructorType(element.valueArguments) ?: return null
+    // No matter what the original format is, we make the format become one of:
+    // - (0xAARRGGBB)
+    // - (color = 0xAARRGGBB)
+    // or
+    // - ([0..255], [0..255], [0..255], [0.255])
+    // - (red = [0..255], green = [0..255], blue = [0..255], alpha = [0.255])
+    // or
+    // - ([0x00..0xFF], [0x00..0xFF], [0x00..0xFF], [0x00..0xFF])
+    // - (red = [0x00..0xFF], green =[0x00..0xFF], blue = [0x00..0xFF], alpha = [0x00..0xFF])
+    // or
+    // - ([0.0f..1.0f], [0.0f..1.0f], [0.0f..1.0f], [0.0f..1.0f])
+    // - (red = [0.0f..1.0f], green = [0.0f..1.0f], blue = [0.0f..1.0f], alpha = [0.0f..1.0f])
+    // , depends on the original value type and numeral system.
+    return when (constructorType) {
+      ComposeColorConstructor.INT,
+      ComposeColorConstructor.LONG -> { color: Color ->
+          val valueArgumentList = ktCallExpression.valueArgumentList
+          if (valueArgumentList != null) {
+            val needsArgumentName = valueArgumentList.arguments.any { it.getArgumentName() != null }
+            val hexString = "0x${String.format("%08X", color.rgb)}"
+            val argumentText = if (needsArgumentName) "(color = $hexString)" else "($hexString)"
+            valueArgumentList.replace(
+              KtPsiFactory(ktCallExpression.project).createCallArguments(argumentText)
+            )
+          }
+        }
+      ComposeColorConstructor.INT_X3,
+      ComposeColorConstructor.INT_X4 -> { color: Color ->
+          val valueArgumentList = ktCallExpression.valueArgumentList
+          if (valueArgumentList != null) {
+            val needsArgumentName = valueArgumentList.arguments.any { it.getArgumentName() != null }
+            val hasHexFormat =
+              valueArgumentList.arguments.any {
+                it.getArgumentExpression()?.text?.startsWith("0x") ?: false
+              }
+            val red = if (hasHexFormat) color.red.toHexString() else color.red.toString()
+            val green = if (hasHexFormat) color.green.toHexString() else color.green.toString()
+            val blue = if (hasHexFormat) color.blue.toHexString() else color.blue.toString()
+            val alpha = if (hasHexFormat) color.alpha.toHexString() else color.alpha.toString()
+
+            val argumentText =
+              if (needsArgumentName) "(red = $red, green = $green, blue = $blue, alpha = $alpha)"
+              else "($red, $green, $blue, $alpha)"
+            valueArgumentList.replace(
+              KtPsiFactory(ktCallExpression.project).createCallArguments(argumentText)
+            )
+          }
+        }
+      ComposeColorConstructor.FLOAT_X3,
+      ComposeColorConstructor.FLOAT_X4 -> { color: Color ->
+          val valueArgumentList = ktCallExpression.valueArgumentList
+          if (valueArgumentList != null) {
+            val needsArgumentName = valueArgumentList.arguments.any { it.getArgumentName() != null }
+            val red = (color.red / 255f).toRoundString()
+            val green = (color.green / 255f).toRoundString()
+            val blue = (color.blue / 255f).toRoundString()
+            val alpha = (color.alpha / 255f).toRoundString()
+
+            val argumentText =
+              if (needsArgumentName)
+                "(red = ${red}f, green = ${green}f, blue = ${blue}f, alpha = ${alpha}f)"
+              else "(${red}f, ${green}f, ${blue}f, ${alpha}f)"
+            valueArgumentList.replace(
+              KtPsiFactory(ktCallExpression.project).createCallArguments(argumentText)
+            )
+          }
+        }
+      ComposeColorConstructor.FLOAT_X4_COLORSPACE ->
+        null // TODO: support ComposeColorConstructor.FLOAT_X4_COLORSPACE in the future.
+    }
+  }
+}
+
+private const val COLOR_METHOD = "Color"
+private const val COMPOSE_COLOR_CLASS = "androidx.compose.ui.graphics.ColorKt"
+
+private const val ARG_NAME_RED = "red"
+private const val ARG_NAME_GREEN = "green"
+private const val ARG_NAME_BLUE = "blue"
+private const val ARG_NAME_ALPHA = "alpha"
+
+private val ARGS_RGB = listOf(ARG_NAME_RED, ARG_NAME_GREEN, ARG_NAME_BLUE)
+private val ARGS_RGBA = listOf(ARG_NAME_RED, ARG_NAME_GREEN, ARG_NAME_BLUE, ARG_NAME_ALPHA)
+
+enum class ComposeColorConstructor {
+  INT,
+  LONG,
+  INT_X3,
+  INT_X4,
+  FLOAT_X3,
+  FLOAT_X4,
+  FLOAT_X4_COLORSPACE
+}
+
+private fun getColorInt(arguments: List<KtValueArgument>): Color? {
+  val colorValue =
+    arguments.first().getArgumentExpression()?.evaluateToConstantOrNull<Int>() ?: return null
+  return Color(colorValue, true)
+}
+
+private fun getColorLong(arguments: List<KtValueArgument>): Color? {
+  val colorValue =
+    arguments.first().getArgumentExpression()?.evaluateToConstantOrNull<Long>() ?: return null
+  return Color(colorValue.toInt(), true)
+}
+
+private fun getColorIntX3(arguments: List<KtValueArgument>): Color? {
+  val rgbValues = getNamedValues<Int>(ARGS_RGB, arguments) ?: return null
+  return intColorMapToColor(rgbValues)
+}
+
+private fun getColorIntX4(arguments: List<KtValueArgument>): Color? {
+  val rgbaValues = getNamedValues<Int>(ARGS_RGBA, arguments) ?: return null
+  return intColorMapToColor(rgbaValues)
+}
+
+private fun getColorFloatX3(arguments: List<KtValueArgument>): Color? {
+  val rgbValues = getNamedValues<Float>(ARGS_RGB, arguments) ?: return null
+  return floatColorMapToColor(rgbValues)
+}
+
+private fun getColorFloatX4(arguments: List<KtValueArgument>): Color? {
+  val rgbaValues = getNamedValues<Float>(ARGS_RGBA, arguments) ?: return null
+  return floatColorMapToColor(rgbaValues)
+}
+
+/**
+ * This function return the name-value pair for the request arguments names by extracting the given
+ * ktValueArguments.
+ */
+private inline fun <reified T> getNamedValues(
+  requestArgumentNames: List<String>,
+  ktValueArgument: List<KtValueArgument>
+): Map<String, T>? {
+  val namedValues = mutableMapOf<String, T>()
+
+  val unnamedValue = mutableListOf<T>()
+  for (argument in ktValueArgument) {
+    val (name, value) = getArgumentNameValuePair<T>(argument) ?: return null
+    if (name != null) {
+      namedValues[name] = value
+    } else {
+      unnamedValue.add(value)
+    }
+  }
+
+  val unnamedArgument = requestArgumentNames.filterNot { it in namedValues.keys }.toList()
+  if (unnamedArgument.size != unnamedValue.size) {
+    // The number of argument values doesn't match the given KtValueArgument.
+    return null
+  }
+
+  for (index in unnamedArgument.indices) {
+    // Fill the unnamed argument value from KtValueArgument.
+    namedValues[unnamedArgument[index]] = unnamedValue[index]
+  }
+  if (namedValues.keys != requestArgumentNames.toSet()) {
+    // Has the redundant or missed argument(s).
+    return null
+  }
+  return namedValues
+}
+
+private inline fun <reified T> getArgumentNameValuePair(
+  valueArgument: KtValueArgument
+): Pair<String?, T>? {
+  val name = valueArgument.getArgumentName()?.asName?.asString()
+  val value = valueArgument.getArgumentExpression()?.evaluateToConstantOrNull<T>() ?: return null
+  return name to value
+}
+
+private inline fun <reified T> KtExpression.evaluateToConstantOrNull(): T? {
+  return if (isK2Plugin()) {
+    analyze(this) {
+      evaluate(KtConstantEvaluationMode.CONSTANT_EXPRESSION_EVALUATION)?.value as? T ?: return null
+    }
+  } else {
+    constantValueOrNull()?.value as? T ?: return null
+  }
+}
+
+private fun Int.toHexString(): String =
+  "0x${(Integer.toHexString(this)).uppercase(Locale.getDefault())}"
+
+// Note: toFloat() then toString() is for removing the tail zero(s).
+private fun Float.toRoundString(decimals: Int = 3): String =
+  "%.${decimals}f".format(this).toFloat().toString()
+
+private typealias IntColorMap = Map<String, Int>
+
+private fun intColorMapToColor(intColorMap: IntColorMap): Color? {
+  val red = intColorMap[ARG_NAME_RED] ?: return null
+  val green = intColorMap[ARG_NAME_GREEN] ?: return null
+  val blue = intColorMap[ARG_NAME_BLUE] ?: return null
+  val alpha = intColorMap[ARG_NAME_ALPHA]
+  return if (alpha == null) Color(red, green, blue) else Color(red, green, blue, alpha)
+}
+
+private typealias FloatColorMap = Map<String, Float>
+
+private fun floatColorMapToColor(floatColorMap: FloatColorMap): Color? {
+  val red = floatColorMap[ARG_NAME_RED] ?: return null
+  val green = floatColorMap[ARG_NAME_GREEN] ?: return null
+  val blue = floatColorMap[ARG_NAME_BLUE] ?: return null
+  val alpha = floatColorMap[ARG_NAME_ALPHA]
+  return if (alpha == null) Color(red, green, blue) else Color(red, green, blue, alpha)
+}
+
+private fun getConstructorType(arguments: List<UExpression>): ComposeColorConstructor? {
+  val paramType = arguments.firstOrNull()?.getExpressionType() ?: return null
+  return when (arguments.size) {
+    1 ->
+      if (PsiTypes.intType() == paramType) ComposeColorConstructor.INT
+      else ComposeColorConstructor.LONG
+    3 ->
+      if (PsiTypes.intType() == paramType) ComposeColorConstructor.INT_X3
+      else ComposeColorConstructor.FLOAT_X3
+    4 ->
+      if (PsiTypes.intType() == paramType) ComposeColorConstructor.INT_X4
+      else ComposeColorConstructor.FLOAT_X4
+    5 -> ComposeColorConstructor.FLOAT_X4_COLORSPACE
+    else -> null
+  }
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposeColorSettingsPage.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposeColorSettingsPage.kt
index 1da9388..97e939f 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/ComposeColorSettingsPage.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/ComposeColorSettingsPage.kt
@@ -23,62 +23,66 @@
 import com.intellij.openapi.options.colors.AttributesDescriptor
 import com.intellij.openapi.options.colors.ColorDescriptor
 import com.intellij.openapi.options.colors.ColorSettingsPage
+import javax.swing.Icon
 import org.jetbrains.kotlin.idea.highlighter.KotlinColorSettingsPage
 import org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingColors
-import javax.swing.Icon
 
 // This class is used by AndroidStudio to allow the user to change the style of Compose attributes.
 class ComposeColorSettingsPage : ColorSettingsPage {
-    override fun getHighlighter(): SyntaxHighlighter {
-        return KotlinColorSettingsPage().highlighter
-    }
+  override fun getHighlighter(): SyntaxHighlighter {
+    return KotlinColorSettingsPage().highlighter
+  }
 
-    override fun getAdditionalHighlightingTagToDescriptorMap(): MutableMap<String,
-            TextAttributesKey> {
-        val attributes = HashMap<String, TextAttributesKey>()
-        attributes[ComposableHighlighterExtension.COMPOSABLE_CALL_TEXT_ATTRIBUTES_NAME] =
-          ComposableHighlighterExtension.COMPOSABLE_CALL_TEXT_ATTRIBUTES_KEY
-        if (StudioFlags.COMPOSE_STATE_READ_HIGHLIGHTING_ENABLED.get()) {
-          attributes[ComposeStateReadAnnotator.COMPOSE_STATE_READ_TEXT_ATTRIBUTES_NAME] =
-            ComposeStateReadAnnotator.COMPOSE_STATE_READ_TEXT_ATTRIBUTES_KEY
-        }
-        attributes["ANNOTATION"] = KotlinHighlightingColors.ANNOTATION
-        attributes["KEYWORD"] = KotlinHighlightingColors.KEYWORD
-        attributes["FUNCTION_DECLARATION"] = KotlinHighlightingColors.FUNCTION_DECLARATION
-        attributes["FUNCTION_PARAMETER"] = KotlinHighlightingColors.PARAMETER
-        return attributes
+  override fun getAdditionalHighlightingTagToDescriptorMap():
+    MutableMap<String, TextAttributesKey> {
+    val attributes = HashMap<String, TextAttributesKey>()
+    attributes[ComposableHighlighterExtension.COMPOSABLE_CALL_TEXT_ATTRIBUTES_NAME] =
+      ComposableHighlighterExtension.COMPOSABLE_CALL_TEXT_ATTRIBUTES_KEY
+    if (StudioFlags.COMPOSE_STATE_READ_HIGHLIGHTING_ENABLED.get()) {
+      attributes[ComposeStateReadAnnotator.COMPOSE_STATE_READ_TEXT_ATTRIBUTES_NAME] =
+        ComposeStateReadAnnotator.COMPOSE_STATE_READ_TEXT_ATTRIBUTES_KEY
     }
+    attributes["ANNOTATION"] = KotlinHighlightingColors.ANNOTATION
+    attributes["KEYWORD"] = KotlinHighlightingColors.KEYWORD
+    attributes["FUNCTION_DECLARATION"] = KotlinHighlightingColors.FUNCTION_DECLARATION
+    attributes["FUNCTION_PARAMETER"] = KotlinHighlightingColors.PARAMETER
+    return attributes
+  }
 
-    override fun getIcon(): Icon? {
-        return null
-    }
+  override fun getIcon(): Icon? {
+    return null
+  }
 
-    override fun getAttributeDescriptors(): Array<AttributesDescriptor> {
-        // TODO: this needs to be localized.
-        return arrayOf(AttributesDescriptor("Calls to @Compose functions",
-                                            ComposableHighlighterExtension.COMPOSABLE_CALL_TEXT_ATTRIBUTES_KEY))
-    }
+  override fun getAttributeDescriptors(): Array<AttributesDescriptor> {
+    // TODO: this needs to be localized.
+    return arrayOf(
+      AttributesDescriptor(
+        "Calls to @Compose functions",
+        ComposableHighlighterExtension.COMPOSABLE_CALL_TEXT_ATTRIBUTES_KEY
+      )
+    )
+  }
 
-    override fun getColorDescriptors(): Array<ColorDescriptor> {
-        return emptyArray()
-    }
+  override fun getColorDescriptors(): Array<ColorDescriptor> {
+    return emptyArray()
+  }
 
-    override fun getDisplayName(): String {
-        // TODO: this needs to be localized.
-        return "Compose"
-    }
+  override fun getDisplayName(): String {
+    // TODO: this needs to be localized.
+    return "Compose"
+  }
 
-    override fun getDemoText(): String {
-        return "<ANNOTATION>@Composable</ANNOTATION>\n" +
-            "<KEYWORD>fun</KEYWORD> <FUNCTION_DECLARATION>Text</FUNCTION_DECLARATION>(" +
-            "<FUNCTION_PARAMETER>text</FUNCTION_PARAMETER>: <FUNCTION_PARAMETER>String" +
-            "</FUNCTION_PARAMETER>)\n" +
-            "}\n" +
-            "\n" +
-            "<ANNOTATION>@Composable</ANNOTATION>\n" +
-            "<KEYWORD>fun</KEYWORD> <FUNCTION_DECLARATION>Greeting</FUNCTION_DECLARATION>() {\n" +
-            "    <ComposableCallTextAttributes>Text</ComposableCallTextAttributes>(" +
-            "<FUNCTION_PARAMETER>\"Hello\"</FUNCTION_PARAMETER>)\n" +
-            "}"
-    }
-}
\ No newline at end of file
+  override fun getDemoText(): String {
+    return "<ANNOTATION>@Composable</ANNOTATION>\n" +
+      "<KEYWORD>fun</KEYWORD> <FUNCTION_DECLARATION>Text</FUNCTION_DECLARATION>(" +
+      "<FUNCTION_PARAMETER>text</FUNCTION_PARAMETER>: <FUNCTION_PARAMETER>String" +
+      "</FUNCTION_PARAMETER>)\n" +
+      "}\n" +
+      "\n" +
+      "<ANNOTATION>@Composable</ANNOTATION>\n" +
+      "<KEYWORD>fun</KEYWORD> <FUNCTION_DECLARATION>Greeting</FUNCTION_DECLARATION>() {\n" +
+      "    <ComposableCallTextAttributes>Text</ComposableCallTextAttributes>(" +
+      "<FUNCTION_PARAMETER>\"Hello\"</FUNCTION_PARAMETER>)\n" +
+      "}"
+  }
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposeFoldingBuilder.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposeFoldingBuilder.kt
index 9e30289..ebdbb32 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/ComposeFoldingBuilder.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/ComposeFoldingBuilder.kt
@@ -28,36 +28,37 @@
 import org.jetbrains.kotlin.psi.KtNamedFunction
 import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType
 
-/**
- * Adds a folding region for a Modifier chain longer than two.
- */
+/** Adds a folding region for a Modifier chain longer than two. */
 class ComposeFoldingBuilder : CustomFoldingBuilder() {
-  override fun buildLanguageFoldRegions(descriptors: MutableList<FoldingDescriptor>, root: PsiElement, document: Document, quick: Boolean) {
+  override fun buildLanguageFoldRegions(
+    descriptors: MutableList<FoldingDescriptor>,
+    root: PsiElement,
+    document: Document,
+    quick: Boolean
+  ) {
     if (root !is KtFile || DumbService.isDumb(root.project) || !isComposeEnabled(root)) {
       return
     }
 
-    val composableFunctions = root.getChildrenOfType<KtNamedFunction>().filter { it.isComposableFunction() }
+    val composableFunctions =
+      root.getChildrenOfType<KtNamedFunction>().filter { it.isComposableFunction() }
 
     for (function in composableFunctions) {
-      val modifiersChains = PsiTreeUtil.findChildrenOfType(function, KtDotQualifiedExpression::class.java).filter {
-        it.parent !is KtDotQualifiedExpression &&
-        isModifierChainLongerThanTwo(it)
-      }
+      val modifiersChains =
+        PsiTreeUtil.findChildrenOfType(function, KtDotQualifiedExpression::class.java).filter {
+          it.parent !is KtDotQualifiedExpression && isModifierChainLongerThanTwo(it)
+        }
 
       for (modifierChain in modifiersChains) {
         descriptors.add(FoldingDescriptor(modifierChain.node, modifierChain.node.textRange))
       }
     }
-
   }
 
-  /**
-   * For Modifier.adjust().adjust() -> Modifier.(...)
-   */
+  /** For Modifier.adjust().adjust() -> Modifier.(...) */
   override fun getLanguagePlaceholderText(node: ASTNode, range: TextRange): String {
     return node.text.substringBefore(".").trim() + ".(...)"
   }
 
   override fun isRegionCollapsedByDefault(node: ASTNode): Boolean = false
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposeKDocLinkResolutionService.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposeKDocLinkResolutionService.kt
index 2b5062f..8f1a1d7 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/ComposeKDocLinkResolutionService.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/ComposeKDocLinkResolutionService.kt
@@ -18,23 +18,25 @@
 import com.android.tools.idea.flags.StudioFlags
 import com.intellij.psi.search.GlobalSearchScope
 import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
+import org.jetbrains.kotlin.idea.base.projectStructure.scope.KotlinSourceFilterScope
 import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
 import org.jetbrains.kotlin.idea.kdoc.IdeKDocLinkResolutionService
 import org.jetbrains.kotlin.idea.kdoc.KDocLinkResolutionService
 import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
 import org.jetbrains.kotlin.idea.stubindex.KotlinClassShortNameIndex
 import org.jetbrains.kotlin.idea.stubindex.KotlinFunctionShortNameIndex
-import org.jetbrains.kotlin.idea.base.projectStructure.scope.KotlinSourceFilterScope
 import org.jetbrains.kotlin.name.FqName
 import org.jetbrains.kotlin.resolve.BindingContext
 import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
 
 /**
- * Resolves links to functions and classes inside KDoc that are not included to the project (as byte code).
+ * Resolves links to functions and classes inside KDoc that are not included to the project (as byte
+ * code).
  *
- * It's a copy of [org.jetbrains.kotlin.idea.kdoc.IdeKDocLinkResolutionService], but with a larger search scope:
- * GlobalSearchScope.everythingScope(project) instead of GlobalSearchScope.projectScope(project).
- * Source code is already in the index, it attached in [AndroidModuleDependenciesSetup#setUpLibraryDependency]
+ * It's a copy of [org.jetbrains.kotlin.idea.kdoc.IdeKDocLinkResolutionService], but with a larger
+ * search scope: GlobalSearchScope.everythingScope(project) instead of
+ * GlobalSearchScope.projectScope(project). Source code is already in the index, it attached in
+ * [AndroidModuleDependenciesSetup#setUpLibraryDependency]
  */
 class ComposeKDocLinkResolutionService : KDocLinkResolutionService {
   override fun resolveKDocLink(
@@ -44,11 +46,14 @@
     qualifiedName: List<String>
   ): Collection<DeclarationDescriptor> {
     val project = resolutionFacade.project
-    val descriptors = IdeKDocLinkResolutionService(project).resolveKDocLink(context, fromDescriptor, resolutionFacade, qualifiedName)
+    val descriptors =
+      IdeKDocLinkResolutionService(project)
+        .resolveKDocLink(context, fromDescriptor, resolutionFacade, qualifiedName)
 
     if (!StudioFlags.SAMPLES_SUPPORT_ENABLED.get()) return descriptors
 
-    val scope = KotlinSourceFilterScope.librarySources(GlobalSearchScope.everythingScope(project), project)
+    val scope =
+      KotlinSourceFilterScope.librarySources(GlobalSearchScope.everythingScope(project), project)
 
     val shortName = qualifiedName.lastOrNull() ?: return emptyList()
     val targetFqName = FqName.fromSegments(qualifiedName)
@@ -56,12 +61,14 @@
     val functions = KotlinFunctionShortNameIndex[shortName, project, scope].asSequence()
     val classes = KotlinClassShortNameIndex[shortName, project, scope].asSequence()
 
-    val additionalDescriptors = (functions + classes)
-      .filter { it.fqName == targetFqName }
-      .map { it.unsafeResolveToDescriptor(BodyResolveMode.PARTIAL) } // TODO Filter out not visible due dependencies config descriptors
-      .toList()
-    if (additionalDescriptors.isNotEmpty())
-      return additionalDescriptors + descriptors
+    val additionalDescriptors =
+      (functions + classes)
+        .filter { it.fqName == targetFqName }
+        .map {
+          it.unsafeResolveToDescriptor(BodyResolveMode.PARTIAL)
+        } // TODO Filter out not visible due dependencies config descriptors
+        .toList()
+    if (additionalDescriptors.isNotEmpty()) return additionalDescriptors + descriptors
 
     return descriptors
   }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposeOverrideImplementsAnnotationsFilter.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposeOverrideImplementsAnnotationsFilter.kt
index 0a386d0..8ed64d0 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/ComposeOverrideImplementsAnnotationsFilter.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/ComposeOverrideImplementsAnnotationsFilter.kt
@@ -19,10 +19,9 @@
 import com.intellij.psi.PsiFile
 import org.jetbrains.kotlin.psi.KtFile
 
-/**
- * Ensure that any @Composable annotations are retained when implementing an interface.
- */
+/** Ensure that any @Composable annotations are retained when implementing an interface. */
 class ComposeOverrideImplementsAnnotationsFilter : OverrideImplementsAnnotationsFilter {
   override fun getAnnotations(file: PsiFile): Array<String> =
-    if (file is KtFile && isComposeEnabled(file)) arrayOf(COMPOSABLE_ANNOTATION_FQ_NAME) else arrayOf()
+    if (file is KtFile && isComposeEnabled(file)) arrayOf(COMPOSABLE_ANNOTATION_FQ_NAME)
+    else arrayOf()
 }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposePluginIrGenerationExtension.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposePluginIrGenerationExtension.kt
index 9d65fe5..42660fc 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/ComposePluginIrGenerationExtension.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/ComposePluginIrGenerationExtension.kt
@@ -31,16 +31,19 @@
 class ComposePluginIrGenerationExtension : IrGenerationExtension {
   override fun generate(moduleFragment: IrModuleFragment, pluginContext: IrPluginContext) {
     try {
-        ComposeIrGenerationExtension(reportsDestination = null,
-                                     metricsDestination = null,
-                                     generateFunctionKeyMetaClasses = true,
-                                     intrinsicRememberEnabled = false)
-          .generate(moduleFragment, pluginContext)
-    } catch (e : ProcessCanceledException) {
-      // From ProcessCanceledException javadoc: "Usually, this exception should not be caught, swallowed, logged, or handled in any way.
+      ComposeIrGenerationExtension(
+          reportsDestination = null,
+          metricsDestination = null,
+          generateFunctionKeyMetaClasses = true,
+          intrinsicRememberEnabled = false
+        )
+        .generate(moduleFragment, pluginContext)
+    } catch (e: ProcessCanceledException) {
+      // From ProcessCanceledException javadoc: "Usually, this exception should not be caught,
+      // swallowed, logged, or handled in any way.
       // Instead, it should be rethrown so that the infrastructure can handle it correctly."
-      throw e;
-    } catch (versionError : IncompatibleComposeRuntimeVersionException) {
+      throw e
+    } catch (versionError: IncompatibleComposeRuntimeVersionException) {
       // We only rethrow version incompatibility when we are trying to CodeGen for Live Edit.
       for (s in versionError.stackTrace) {
         if (s.className.startsWith(liveEditPackageName)) {
@@ -48,8 +51,8 @@
         }
       }
       versionError.printStackTrace()
-    } catch (t : Throwable) {
+    } catch (t: Throwable) {
       t.printStackTrace()
     }
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposePluginUtils.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposePluginUtils.kt
index e035f0f..c35c802 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/ComposePluginUtils.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/ComposePluginUtils.kt
@@ -68,8 +68,9 @@
   return false
 }
 
-internal fun KotlinType.isClassOrExtendsClass(classFqName:String): Boolean {
-  return fqName?.asString() == classFqName || supertypes().any { it.fqName?.asString() == classFqName }
+internal fun KotlinType.isClassOrExtendsClass(classFqName: String): Boolean {
+  return fqName?.asString() == classFqName ||
+    supertypes().any { it.fqName?.asString() == classFqName }
 }
 
 internal fun KtValueArgument.matchingParamTypeFqName(callee: KtNamedFunction): FqName? {
@@ -77,43 +78,46 @@
     val argumentName = getArgumentName()!!.asName.asString()
     val matchingParam = callee.valueParameters.find { it.name == argumentName } ?: return null
     matchingParam.returnTypeFqName()
-  }
-  else {
+  } else {
     val argumentIndex = (parent as KtValueArgumentList).arguments.indexOf(this)
     val paramAtIndex = callee.valueParameters.getOrNull(argumentIndex) ?: return null
     paramAtIndex.returnTypeFqName()
   }
 }
 
-internal fun KtDeclaration.returnTypeFqName(): FqName? = if (isK2Plugin()) {
-  if (this !is KtCallableDeclaration) null
-  else analyze(this) { asFqName(this@returnTypeFqName.getReturnKtType()) }
-}
-else {
-  this.type()?.fqName
-}
+internal fun KtDeclaration.returnTypeFqName(): FqName? =
+  if (isK2Plugin()) {
+    if (this !is KtCallableDeclaration) null
+    else analyze(this) { asFqName(this@returnTypeFqName.getReturnKtType()) }
+  } else {
+    this.type()?.fqName
+  }
 
 @OptIn(KtAllowAnalysisOnEdt::class)
-internal fun KtElement.callReturnTypeFqName() = if (isK2Plugin()) {
-  allowAnalysisOnEdt {
-    analyze(this) {
-      val callReturnType = this@callReturnTypeFqName.resolveCall()?.singleFunctionCallOrNull()?.symbol?.returnType
-      callReturnType?.let { asFqName(it) }
+internal fun KtElement.callReturnTypeFqName() =
+  if (isK2Plugin()) {
+    allowAnalysisOnEdt {
+      analyze(this) {
+        val callReturnType =
+          this@callReturnTypeFqName.resolveCall()?.singleFunctionCallOrNull()?.symbol?.returnType
+        callReturnType?.let { asFqName(it) }
+      }
     }
+  } else {
+    resolveToCall(BodyResolveMode.PARTIAL)?.resultingDescriptor?.returnType?.fqName
   }
-}
-else {
-  resolveToCall(BodyResolveMode.PARTIAL)?.resultingDescriptor?.returnType?.fqName
-}
 
-// TODO(274630452): When the upstream APIs are available, implement it based on `fullyExpandedType` and `KtTypeRenderer`.
-internal fun KtAnalysisSession.asFqName(type: KtType) = type.expandedClassSymbol?.classIdIfNonLocal?.asSingleFqName()
+// TODO(274630452): When the upstream APIs are available, implement it based on `fullyExpandedType`
+// and `KtTypeRenderer`.
+internal fun KtAnalysisSession.asFqName(type: KtType) =
+  type.expandedClassSymbol?.classIdIfNonLocal?.asSingleFqName()
 
-internal fun KtFunction.hasComposableAnnotation() = if (isK2Plugin()) {
-  hasAnnotation(ComposeClassIds.Composable)
-} else {
-  descriptor?.hasComposableAnnotation() == true
-}
+internal fun KtFunction.hasComposableAnnotation() =
+  if (isK2Plugin()) {
+    hasAnnotation(ComposeClassIds.Composable)
+  } else {
+    descriptor?.hasComposableAnnotation() == true
+  }
 
 internal fun KtAnalysisSession.isComposableInvocation(callableSymbol: KtCallableSymbol): Boolean {
   fun hasComposableAnnotation(annotated: KtAnnotated?) =
@@ -122,10 +126,11 @@
   val type = callableSymbol.returnType
   if (hasComposableAnnotation(type)) return true
   val functionSymbol = callableSymbol as? KtFunctionSymbol
-  if (functionSymbol != null &&
+  if (
+    functionSymbol != null &&
       functionSymbol.isOperator &&
       functionSymbol.name == OperatorNameConventions.INVOKE
-    ) {
+  ) {
     functionSymbol.receiverType?.let { receiverType ->
       if (hasComposableAnnotation(receiverType)) return true
     }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposeSettings.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposeSettings.kt
index 539c95d..d818088 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/ComposeSettings.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/ComposeSettings.kt
@@ -24,7 +24,8 @@
 
 @Service
 @State(name = "ComposeSettings", storages = [Storage("composeSettings.xml")])
-class ComposeSettings : SimplePersistentStateComponent<ComposeSettingsState>(ComposeSettingsState()) {
+class ComposeSettings :
+  SimplePersistentStateComponent<ComposeSettingsState>(ComposeSettingsState()) {
   companion object {
     fun getInstance() = ApplicationManager.getApplication().getService(ComposeSettings::class.java)
   }
@@ -32,4 +33,4 @@
 
 class ComposeSettingsState : BaseState() {
   var isComposeInsertHandlerEnabled by property(true)
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposeSuppressor.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposeSuppressor.kt
index 97274ec..aedb571 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/ComposeSuppressor.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/ComposeSuppressor.kt
@@ -21,19 +21,16 @@
 import org.jetbrains.kotlin.idea.KotlinLanguage
 import org.jetbrains.kotlin.lexer.KtTokens
 
-/**
- * Suppress inspection that require composable function names to start with a lower case letter.
- */
+/** Suppress inspection that require composable function names to start with a lower case letter. */
 class ComposeSuppressor : InspectionSuppressor {
   override fun isSuppressedFor(element: PsiElement, toolId: String): Boolean {
     return toolId == "FunctionName" &&
-           element.language == KotlinLanguage.INSTANCE &&
-           element.node.elementType == KtTokens.IDENTIFIER &&
-           element.parent.isComposableFunction()
+      element.language == KotlinLanguage.INSTANCE &&
+      element.node.elementType == KtTokens.IDENTIFIER &&
+      element.parent.isComposableFunction()
   }
 
   override fun getSuppressActions(element: PsiElement?, toolId: String): Array<SuppressQuickFix> {
     return SuppressQuickFix.EMPTY_ARRAY
   }
 }
-
diff --git a/compose-ide-plugin/src/com/android/tools/compose/ComposeUsageGroupingRuleProvider.kt b/compose-ide-plugin/src/com/android/tools/compose/ComposeUsageGroupingRuleProvider.kt
index cb16f26..dab4e43 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/ComposeUsageGroupingRuleProvider.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/ComposeUsageGroupingRuleProvider.kt
@@ -31,10 +31,9 @@
 import com.intellij.usages.rules.UsageGroupingRule
 import com.intellij.usages.rules.UsageGroupingRuleEx
 import com.intellij.usages.rules.UsageGroupingRuleProviderEx
-import org.jetbrains.kotlin.name.ClassId
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.psi.KtFunction
 import javax.swing.Icon
+import org.jetbrains.kotlin.name.ClassId
+import org.jetbrains.kotlin.psi.KtFunction
 
 private val PREVIEW_CLASS_ID = ClassId.fromString("androidx/compose/ui/tooling/preview/Preview")
 
@@ -51,14 +50,17 @@
 private fun KtFunction.hasPreviewAnnotation() = hasAnnotation(PREVIEW_CLASS_ID)
 
 /** Returns whether any of the [UsageTarget]s represent @Composable functions. */
-private fun Array<out UsageTarget>.containsComposable(): Boolean = asSequence()
-  .filterIsInstance<PsiElementUsageTarget>()
-  .mapNotNull { it.element as? KtFunction }
-  .any { it.hasComposableAnnotation() }
+private fun Array<out UsageTarget>.containsComposable(): Boolean =
+  asSequence()
+    .filterIsInstance<PsiElementUsageTarget>()
+    .mapNotNull { it.element as? KtFunction }
+    .any { it.hasComposableAnnotation() }
 
 class ComposeUsageGroupingRuleProvider : UsageGroupingRuleProviderEx {
-  override fun getActiveRules(project: Project): Array<UsageGroupingRule> = arrayOf(PreviewUsageGroupingRule)
-  override fun getAllRules(project: Project, usageView: UsageView?): Array<UsageGroupingRule> = arrayOf(PreviewUsageGroupingRule)
+  override fun getActiveRules(project: Project): Array<UsageGroupingRule> =
+    arrayOf(PreviewUsageGroupingRule)
+  override fun getAllRules(project: Project, usageView: UsageView?): Array<UsageGroupingRule> =
+    arrayOf(PreviewUsageGroupingRule)
 }
 
 private object PreviewUsageGroupingRule : UsageGroupingRuleEx {
@@ -70,11 +72,14 @@
   override fun getTitle() = ComposeBundle.message("separate.preview.usages")
 
   override fun getParentGroupsFor(usage: Usage, targets: Array<out UsageTarget>): List<UsageGroup> {
-    // This block exists to facilitate end-to-end testing for ShowUsages. When ShowUsages is invoked, irrespective of whether anything
-    // related to compose is happening, this code will execute for each Usage seen, logging something to idea.log we can look for in our
+    // This block exists to facilitate end-to-end testing for ShowUsages. When ShowUsages is
+    // invoked, irrespective of whether anything
+    // related to compose is happening, this code will execute for each Usage seen, logging
+    // something to idea.log we can look for in our
     // end-to-end test, provided we turn on debugging for this class.
     if (java.lang.Boolean.getBoolean("studio.run.under.integration.test")) {
-      Logger.getInstance(ComposeUsageGroupingRuleProvider::class.java).debug("Saw usage: ${usage.presentation.plainText.trim()}")
+      Logger.getInstance(ComposeUsageGroupingRuleProvider::class.java)
+        .debug("Saw usage: ${usage.presentation.plainText.trim()}")
     }
 
     val element = (usage as? PsiElementUsage)?.element ?: return emptyList()
@@ -96,5 +101,6 @@
 internal object ProductionUsageGroup : UsageGroupBase(0) {
   override fun getIcon(): Icon? = null
 
-  override fun getPresentableGroupText() = ComposeBundle.message("usage.group.in.nonpreview.function")
+  override fun getPresentableGroupText() =
+    ComposeBundle.message("usage.group.in.nonpreview.function")
 }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/aa/code/ComposableFunctionRendering.kt b/compose-ide-plugin/src/com/android/tools/compose/aa/code/ComposableFunctionRendering.kt
index 26f7819..6f21244 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/aa/code/ComposableFunctionRendering.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/aa/code/ComposableFunctionRendering.kt
@@ -29,48 +29,70 @@
 /**
  * Generates [ComposableFunctionRenderParts] for a given Composable function.
  *
- * Since Composable functions tend to have numerous optional parameters, those are omitted from the rendered parameters and replaced with an
- * ellipsis ("..."). Additional modifications are made to ensure that a lambda can be added in cases where the Composable function requires
- * another Composable as its final argument.
+ * Since Composable functions tend to have numerous optional parameters, those are omitted from the
+ * rendered parameters and replaced with an ellipsis ("..."). Additional modifications are made to
+ * ensure that a lambda can be added in cases where the Composable function requires another
+ * Composable as its final argument.
  */
-fun KtAnalysisSession.getComposableFunctionRenderParts(functionSymbol: KtFunctionLikeSymbol): ComposableFunctionRenderParts {
+fun KtAnalysisSession.getComposableFunctionRenderParts(
+  functionSymbol: KtFunctionLikeSymbol
+): ComposableFunctionRenderParts {
   val allParameters = functionSymbol.valueParameters
   val requiredParameters = allParameters.filter { isRequired(it) }
-  val lastParamIsComposable = allParameters.lastOrNull()?.let { isComposableFunctionParameter(it) } == true
+  val lastParamIsComposable =
+    allParameters.lastOrNull()?.let { isComposableFunctionParameter(it) } == true
   val inParens = if (lastParamIsComposable) requiredParameters.dropLast(1) else requiredParameters
 
-  val tail = if (lastParamIsComposable) LambdaSignatureTemplates.DEFAULT_LAMBDA_PRESENTATION else null
+  val tail =
+    if (lastParamIsComposable) LambdaSignatureTemplates.DEFAULT_LAMBDA_PRESENTATION else null
 
-  val stringAfterValueParameters = when {
-    requiredParameters.size < allParameters.size -> if (inParens.isNotEmpty()) ", ...)" else "...)"
-    inParens.isEmpty() && lastParamIsComposable -> null // Don't render an empty pair of parentheses if we're rendering a lambda afterwards.
-    else -> ")"
-  } ?: return ComposableFunctionRenderParts(null, tail)
+  val stringAfterValueParameters =
+    when {
+      requiredParameters.size < allParameters.size ->
+        if (inParens.isNotEmpty()) ", ...)" else "...)"
+      inParens.isEmpty() && lastParamIsComposable ->
+        null // Don't render an empty pair of parentheses if we're rendering a lambda afterwards.
+      else -> ")"
+    }
+      ?: return ComposableFunctionRenderParts(null, tail)
 
   val parameters = renderValueParameters(inParens, stringAfterValueParameters)
   return ComposableFunctionRenderParts(parameters, tail)
 }
 
-fun KtAnalysisSession.renderValueParameters(valueParamsInParen: List<KtValueParameterSymbol>, closingString: String) = buildString {
+fun KtAnalysisSession.renderValueParameters(
+  valueParamsInParen: List<KtValueParameterSymbol>,
+  closingString: String
+) = buildString {
   append("(")
-  valueParamsInParen.joinTo(buffer = this) { it.render(KtDeclarationRendererForSource.WITH_SHORT_NAMES) }
+  valueParamsInParen.joinTo(buffer = this) {
+    it.render(KtDeclarationRendererForSource.WITH_SHORT_NAMES)
+  }
   append(closingString)
 }
 
 private fun KtAnalysisSession.isRequired(valueParamSymbol: KtValueParameterSymbol): Boolean {
   if (valueParamSymbol.hasDefaultValue) return false
 
-  // TODO(274145999): When we check it with a real AS instance, determine if we can drop this hacky solution or not.
-  // The KtValueParameterSymbol we get when running this from [ComposableItemPresentationProvider] for some reason says that optional
-  // Composable parameters don't declare a default value, which is incorrect. At the moment, the only way I've found to determine that
+  // TODO(274145999): When we check it with a real AS instance, determine if we can drop this hacky
+  // solution or not.
+  // The KtValueParameterSymbol we get when running this from [ComposableItemPresentationProvider]
+  // for some reason says that optional
+  // Composable parameters don't declare a default value, which is incorrect. At the moment, the
+  // only way I've found to determine that
   // they're truly optional is by looking at their text.
   return valueParamSymbol.psi?.text?.endsWith("/* = compiled code */") != true
 }
 
-fun KtAnalysisSession.isComposableFunctionParameter(valueParamSymbol: KtValueParameterSymbol): Boolean {
-  // Since vararg is not a function type parameter, we have to return false for a parameter with a vararg.
-  // In FE1.0, it was simple because vararg has an array type and checking that the parameter is a function type returns false.
-  // On the other hand, K2's value parameter symbol deliberately unwraps it and returns the element type as a symbol's returnType.
+fun KtAnalysisSession.isComposableFunctionParameter(
+  valueParamSymbol: KtValueParameterSymbol
+): Boolean {
+  // Since vararg is not a function type parameter, we have to return false for a parameter with a
+  // vararg.
+  // In FE1.0, it was simple because vararg has an array type and checking that the parameter is a
+  // function type returns false.
+  // On the other hand, K2's value parameter symbol deliberately unwraps it and returns the element
+  // type as a symbol's returnType.
   // We need a separate check for a vararg.
   if (valueParamSymbol.isVararg) return false
 
@@ -78,5 +100,7 @@
   // Mimic FE1.0 `KotlinType.isBuiltinFunctionalType`.
   val isBuiltinFunctionalType = parameterType.isFunctionType || parameterType.isSuspendFunctionType
   return isBuiltinFunctionalType &&
-         parameterType.annotationsByClassId(ClassId.topLevel(FqName(COMPOSABLE_ANNOTATION_FQ_NAME))).isNotEmpty()
-}
\ No newline at end of file
+    parameterType
+      .annotationsByClassId(ClassId.topLevel(FqName(COMPOSABLE_ANNOTATION_FQ_NAME)))
+      .isNotEmpty()
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/aa/intentions/ComposeCreateComposableFunctionQuickFix.kt b/compose-ide-plugin/src/com/android/tools/compose/aa/intentions/ComposeCreateComposableFunctionQuickFix.kt
index 898652d..57f2df2 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/aa/intentions/ComposeCreateComposableFunctionQuickFix.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/aa/intentions/ComposeCreateComposableFunctionQuickFix.kt
@@ -49,34 +49,28 @@
  *
  * Created action creates new function with @Composable annotation.
  *
- * Example:
- * For
+ * Example: For
  *
- * @Composable
- * fun myComposable() {
- *  <caret>newFunction()
- * }
+ * @Composable fun myComposable() { <caret>newFunction() }
  *
  * creates
  *
- * @Composable
- * fun newFunction() {
- *  TODO("Not yet implemented")
- * }
+ * @Composable fun newFunction() {
  *
- * b/267429486: This quickfix should make use of [CreateCallableFromUsageFix]
- * when that machinery is available on K2. For now, this implementation will
- * e.g. always extract the newFunction as a sibling to the calling compose
- * Function, and have fewer smarts in terms of parameter names and types.
+ * b/267429486: This quickfix should make use of [CreateCallableFromUsageFix] when that machinery is
+ * available on K2. For now, this implementation will e.g. always extract the newFunction as a
+ * sibling to the calling compose Function, and have fewer smarts in terms of parameter names and
+ * types.
+ *
+ * TODO("Not yet implemented") }
  */
 class ComposeCreateComposableFunctionQuickFix(
   element: KtCallExpression,
   private val newFunction: KtNamedFunction,
   private val sibling: KtNamedFunction,
-): QuickFixActionBase<KtCallExpression>(element) {
+) : QuickFixActionBase<KtCallExpression>(element) {
 
-  override fun getFamilyName(): String =
-    KotlinBundle.message("fix.create.from.usage.family")
+  override fun getFamilyName(): String = KotlinBundle.message("fix.create.from.usage.family")
 
   override fun getText(): String =
     ComposeBundle.message("create.composable.function") + " '${newFunction.name}'"
@@ -99,7 +93,9 @@
       val parentFunction = unresolvedCall.getStrictParentOfType<KtNamedFunction>() ?: return null
       if (!parentFunction.isComposableFunction()) return null
 
-      val unresolvedName = (unresolvedCall.calleeExpression as? KtSimpleNameExpression)?.getReferencedName() ?: return null
+      val unresolvedName =
+        (unresolvedCall.calleeExpression as? KtSimpleNameExpression)?.getReferencedName()
+          ?: return null
       if (unresolvedName.isBlank() || !unresolvedName[0].isUpperCase()) return null
 
       val fullCallExpression = unresolvedCall.getQualifiedExpressionForSelectorOrThis()
@@ -113,9 +109,8 @@
     }
 
     /**
-     * Budget-version of [CreateCallableFromUsageFix]: Constructs a plain
-     * function annotated with `@Composable`: infers (type) parameters from
-     * [unresolvedCall].
+     * Budget-version of [CreateCallableFromUsageFix]: Constructs a plain function annotated with
+     * `@Composable`: infers (type) parameters from [unresolvedCall].
      *
      * See b/267429486.
      */
@@ -124,23 +119,31 @@
       unresolvedName: String,
       container: KtElement,
     ): KtNamedFunction =
-      KtPsiFactory(container).createFunction(
-        KtPsiFactory.CallableBuilder(KtPsiFactory.CallableBuilder.Target.FUNCTION).apply {
-          modifier("@$COMPOSABLE_ANNOTATION_NAME")
-          typeParams(unresolvedCall.typeArguments.mapIndexed { index, _ -> "T$index" })
-          name(unresolvedName)
-          unresolvedCall.valueArguments.forEachIndexed { index, arg ->
-            val type = arg.getArgumentExpression()?.getKtType() ?: builtinTypes.ANY
-            val name = arg.getArgumentName()?.referenceExpression?.getReferencedName() ?: "x$index"
-            param(name, type.render(KtTypeRendererForSource.WITH_SHORT_NAMES, Variance.INVARIANT))
-          }
-          noReturnType()
-          blockBody("TODO(\"Not yet implemented\")")
-        }.asString())
+      KtPsiFactory(container)
+        .createFunction(
+          KtPsiFactory.CallableBuilder(KtPsiFactory.CallableBuilder.Target.FUNCTION)
+            .apply {
+              modifier("@$COMPOSABLE_ANNOTATION_NAME")
+              typeParams(unresolvedCall.typeArguments.mapIndexed { index, _ -> "T$index" })
+              name(unresolvedName)
+              unresolvedCall.valueArguments.forEachIndexed { index, arg ->
+                val type = arg.getArgumentExpression()?.getKtType() ?: builtinTypes.ANY
+                val name =
+                  arg.getArgumentName()?.referenceExpression?.getReferencedName() ?: "x$index"
+                param(
+                  name,
+                  type.render(KtTypeRendererForSource.WITH_SHORT_NAMES, Variance.INVARIANT)
+                )
+              }
+              noReturnType()
+              blockBody("TODO(\"Not yet implemented\")")
+            }
+            .asString()
+        )
 
     /**
-     * For the purpose of creating Composable functions, optimistically guesses
-     * that [expression] is of type `Unit`.
+     * For the purpose of creating Composable functions, optimistically guesses that [expression] is
+     * of type `Unit`.
      */
     private fun KtAnalysisSession.guessReturnType(expression: KtExpression): KtType {
       return (expression.getKtType() as? KtFunctionalType)?.returnType ?: builtinTypes.UNIT
diff --git a/compose-ide-plugin/src/com/android/tools/compose/aa/intentions/ComposeIdePluginQuickFixRegistrar.kt b/compose-ide-plugin/src/com/android/tools/compose/aa/intentions/ComposeIdePluginQuickFixRegistrar.kt
index 971461e..f930110 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/aa/intentions/ComposeIdePluginQuickFixRegistrar.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/aa/intentions/ComposeIdePluginQuickFixRegistrar.kt
@@ -15,11 +15,15 @@
  */
 package com.android.tools.compose.aa.intentions
 
+import com.android.tools.compose.intentions.AddComposableToFunctionQuickFix
+import org.jetbrains.kotlin.idea.codeinsight.api.applicators.fixes.KotlinQuickFixRegistrar
 import org.jetbrains.kotlin.idea.codeinsight.api.applicators.fixes.KotlinQuickFixesList
 import org.jetbrains.kotlin.idea.codeinsight.api.applicators.fixes.KtQuickFixesListBuilder
 
-class ComposeIdePluginQuickFixRegistrar : org.jetbrains.kotlin.idea.codeinsight.api.applicators.fixes.KotlinQuickFixRegistrar() {
-  override val list: KotlinQuickFixesList = KtQuickFixesListBuilder.registerPsiQuickFix {
-    registerApplicator(ComposeCreateComposableFunctionQuickFix.factory)
-  }
+class ComposeIdePluginQuickFixRegistrar : KotlinQuickFixRegistrar() {
+  override val list: KotlinQuickFixesList =
+    KtQuickFixesListBuilder.registerPsiQuickFix {
+      registerApplicator(ComposeCreateComposableFunctionQuickFix.factory)
+      registerApplicator(AddComposableToFunctionQuickFix.k2DiagnosticFixFactory)
+    }
 }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/ComposableFunctionRendering.kt b/compose-ide-plugin/src/com/android/tools/compose/code/ComposableFunctionRendering.kt
index 1c960f9..e80c4d0 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/ComposableFunctionRendering.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/ComposableFunctionRendering.kt
@@ -28,8 +28,8 @@
 import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
 import org.jetbrains.kotlin.name.FqName
 import org.jetbrains.kotlin.psi.KtDeclaration
-import org.jetbrains.kotlin.resolve.source.getPsi
 import org.jetbrains.kotlin.renderer.DescriptorRenderer.ValueParametersHandler
+import org.jetbrains.kotlin.resolve.source.getPsi
 
 /**
  * Represents parts of a Composable function to be used for rendering in various menus or dialogs.
@@ -39,11 +39,11 @@
 fun KtDeclaration.getComposableFunctionRenderParts(): ComposableFunctionRenderParts? {
   return if (isK2Plugin()) {
     analyze(this) {
-      val functionLikeSymbol = this@getComposableFunctionRenderParts.getSymbol() as? KtFunctionLikeSymbol ?: return null
+      val functionLikeSymbol =
+        this@getComposableFunctionRenderParts.getSymbol() as? KtFunctionLikeSymbol ?: return null
       getComposableFunctionRenderParts(functionLikeSymbol)
     }
-  }
-  else {
+  } else {
     val descriptor = this.descriptor as? FunctionDescriptor ?: return null
     descriptor.getComposableFunctionRenderParts()
   }
@@ -52,9 +52,10 @@
 /**
  * Generates [ComposableFunctionRenderParts] for a given Composable function.
  *
- * Since Composable functions tend to have numerous optional parameters, those are omitted from the rendered parameters and replaced with an
- * ellipsis ("..."). Additional modifications are made to ensure that a lambda can be added in cases where the Composable function requires
- * another Composable as its final argument.
+ * Since Composable functions tend to have numerous optional parameters, those are omitted from the
+ * rendered parameters and replaced with an ellipsis ("..."). Additional modifications are made to
+ * ensure that a lambda can be added in cases where the Composable function requires another
+ * Composable as its final argument.
  */
 fun FunctionDescriptor.getComposableFunctionRenderParts(): ComposableFunctionRenderParts {
   val allParameters = valueParameters
@@ -62,14 +63,17 @@
   val lastParamIsComposable = allParameters.lastOrNull()?.isComposableFunctionParameter() == true
   val inParens = if (lastParamIsComposable) requiredParameters.dropLast(1) else requiredParameters
 
-  val descriptorRenderer = when {
-    requiredParameters.size < allParameters.size -> SHORT_NAMES_RENDERER_WITH_DOTS
-    inParens.isEmpty() && lastParamIsComposable -> null // Don't render an empty pair of parentheses if we're rendering a lambda afterwards.
-    else -> SHORT_NAMES_RENDERER
-  }
+  val descriptorRenderer =
+    when {
+      requiredParameters.size < allParameters.size -> SHORT_NAMES_RENDERER_WITH_DOTS
+      inParens.isEmpty() && lastParamIsComposable ->
+        null // Don't render an empty pair of parentheses if we're rendering a lambda afterwards.
+      else -> SHORT_NAMES_RENDERER
+    }
   val parameters = descriptorRenderer?.renderValueParameters(inParens, false)
 
-  val tail = if (lastParamIsComposable) LambdaSignatureTemplates.DEFAULT_LAMBDA_PRESENTATION else null
+  val tail =
+    if (lastParamIsComposable) LambdaSignatureTemplates.DEFAULT_LAMBDA_PRESENTATION else null
 
   return ComposableFunctionRenderParts(parameters, tail)
 }
@@ -77,25 +81,28 @@
 private fun ValueParameterDescriptor.isRequired(): Boolean {
   if (declaresDefaultValue()) return false
 
-  // The ValueParameterDescriptor we get when running this from [ComposableItemPresentationProvider] for some reason says that optional
-  // Composable parameters don't declare a default value, which is incorrect. At the moment, the only way I've found to determine that
+  // The ValueParameterDescriptor we get when running this from [ComposableItemPresentationProvider]
+  // for some reason says that optional
+  // Composable parameters don't declare a default value, which is incorrect. At the moment, the
+  // only way I've found to determine that
   // they're truly optional is by looking at their text.
   return source.getPsi()?.text?.endsWith("/* = compiled code */") != true
 }
 
 fun ValueParameterDescriptor.isComposableFunctionParameter(): Boolean {
   val parameterType = type
-  return parameterType.isBuiltinFunctionalType && parameterType.annotations.hasAnnotation(FqName(COMPOSABLE_ANNOTATION_FQ_NAME))
+  return parameterType.isBuiltinFunctionalType &&
+    parameterType.annotations.hasAnnotation(FqName(COMPOSABLE_ANNOTATION_FQ_NAME))
 }
 
-/**
- * A version of [SHORT_NAMES_RENDERER] that adds `, ...)` at the end of the parameters list.
- */
-private val SHORT_NAMES_RENDERER_WITH_DOTS = SHORT_NAMES_RENDERER.withOptions {
-  valueParametersHandler = object : ValueParametersHandler by ValueParametersHandler.DEFAULT {
-    override fun appendAfterValueParameters(parameterCount: Int, builder: StringBuilder) {
-      if (parameterCount > 0) builder.append(", ")
-      builder.append("...)")
-    }
+/** A version of [SHORT_NAMES_RENDERER] that adds `, ...)` at the end of the parameters list. */
+private val SHORT_NAMES_RENDERER_WITH_DOTS =
+  SHORT_NAMES_RENDERER.withOptions {
+    valueParametersHandler =
+      object : ValueParametersHandler by ValueParametersHandler.DEFAULT {
+        override fun appendAfterValueParameters(parameterCount: Int, builder: StringBuilder) {
+          if (parameterCount > 0) builder.append(", ")
+          builder.append("...)")
+        }
+      }
   }
-}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/ComposeLineMarkerProviderDescriptor.kt b/compose-ide-plugin/src/com/android/tools/compose/code/ComposeLineMarkerProviderDescriptor.kt
index 352e76b..969971e 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/ComposeLineMarkerProviderDescriptor.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/ComposeLineMarkerProviderDescriptor.kt
@@ -52,22 +52,30 @@
   override fun getIcon() = StudioIcons.Compose.Editor.COMPOSABLE_FUNCTION
 
   override fun getLineMarkerInfo(element: PsiElement): LineMarkerInfo<*>? {
-    if (element !is LeafPsiElement || element.elementType != KtTokens.IDENTIFIER || !isComposeEnabled(element)) return null
+    if (
+      element !is LeafPsiElement ||
+        element.elementType != KtTokens.IDENTIFIER ||
+        !isComposeEnabled(element)
+    )
+      return null
 
     val parentFunction = element.parent.parent as? KtCallExpression ?: return null
     if (!isComposableInvocation(parentFunction)) return null
 
-    return LineMarkerInfo<PsiElement>(element,
-                                      element.range,
-                                      StudioIcons.Compose.Editor.COMPOSABLE_FUNCTION,
-                                      { ComposeBundle.message("composable.line.marker.tooltip") },
-                                      /* navHandler = */ null,
-                                      GutterIconRenderer.Alignment.RIGHT,
-                                      { ComposeBundle.message("composable.line.marker.tooltip") })
+    return LineMarkerInfo<PsiElement>(
+      element,
+      element.range,
+      StudioIcons.Compose.Editor.COMPOSABLE_FUNCTION,
+      { ComposeBundle.message("composable.line.marker.tooltip") },
+      /* navHandler = */ null,
+      GutterIconRenderer.Alignment.RIGHT,
+      { ComposeBundle.message("composable.line.marker.tooltip") }
+    )
   }
 
   companion object {
-    private val ANALYSIS_RESULT_KEY = Key<CachedValue<AnalysisResult>>("ComposeLineMarkerProviderDescriptor.AnalysisResult")
+    private val ANALYSIS_RESULT_KEY =
+      Key<CachedValue<AnalysisResult>>("ComposeLineMarkerProviderDescriptor.AnalysisResult")
 
     private fun isComposableInvocation(parentFunction: KtCallExpression): Boolean {
       if (isK2Plugin()) {
@@ -82,17 +90,25 @@
 
       val containingFile = parentFunction.containingFile as? KtFile ?: return false
 
-      val analysisResult = CachedValuesManager.getManager(parentFunction.project).getCachedValue(
-        containingFile,
-        ANALYSIS_RESULT_KEY,
-        getCachedValueProvider(containingFile),
-        /* trackValue = */ false)
+      val analysisResult =
+        CachedValuesManager.getManager(parentFunction.project)
+          .getCachedValue(
+            containingFile,
+            ANALYSIS_RESULT_KEY,
+            getCachedValueProvider(containingFile),
+            /* trackValue = */ false
+          )
 
-      return parentFunction.getResolvedCall(analysisResult.bindingContext)?.isComposableInvocation() ?: false
+      return parentFunction.getResolvedCall(analysisResult.bindingContext)?.isComposableInvocation()
+        ?: false
     }
 
     private fun getCachedValueProvider(ktFile: KtFile) = CachedValueProvider {
-      CachedValueProvider.Result.create(ktFile.analyzeWithAllCompilerChecks(), ktFile, PsiModificationTracker.MODIFICATION_COUNT)
+      CachedValueProvider.Result.create(
+        ktFile.analyzeWithAllCompilerChecks(),
+        ktFile,
+        PsiModificationTracker.MODIFICATION_COUNT
+      )
     }
   }
 }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/ComposeStateReadAnnotator.kt b/compose-ide-plugin/src/com/android/tools/compose/code/ComposeStateReadAnnotator.kt
index 3ce93fb..41618b9 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/ComposeStateReadAnnotator.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/ComposeStateReadAnnotator.kt
@@ -53,20 +53,25 @@
 private val CLASS_ID_OF_STATE = ClassId.topLevel(FqName(FQNAME))
 
 /**
- * Annotator that highlights reads of `androidx.compose.runtime.State` variables inside `@Composable` functions.
+ * Annotator that highlights reads of `androidx.compose.runtime.State` variables inside
+ * `@Composable` functions.
  *
- * TODO(b/225218822): Before productionizing this, depending on whether we want a gutter icon, highlighting, or both,
- *  we must change this to use `KotlinHighlightingVisitorExtension` (to avoid race conditions), or use a
- *  `RelatedItemLineMarkerProvider` for the gutter icon so it can be disabled with a setting. If we do both, we will
- *  need to share the logic and store result on the `PsiElement` to avoid computing it twice.
+ * TODO(b/225218822): Before productionizing this, depending on whether we want a gutter icon,
+ *   highlighting, or both, we must change this to use `KotlinHighlightingVisitorExtension` (to
+ *   avoid race conditions), or use a `RelatedItemLineMarkerProvider` for the gutter icon so it can
+ *   be disabled with a setting. If we do both, we will need to share the logic and store result on
+ *   the `PsiElement` to avoid computing it twice.
  */
 class ComposeStateReadAnnotator : Annotator {
   override fun annotate(element: PsiElement, holder: AnnotationHolder) {
     if (!StudioFlags.COMPOSE_STATE_READ_HIGHLIGHTING_ENABLED.get()) return
     if (element !is KtNameReferenceExpression) return
-    val scopeName = element.parentOfType<KtNamedFunction>()?.takeIf { it.hasComposableAnnotation() }?.name ?: return
+    val scopeName =
+      element.parentOfType<KtNamedFunction>()?.takeIf { it.hasComposableAnnotation() }?.name
+        ?: return
     element.getStateReadElement()?.let {
-      holder.newAnnotation(HighlightSeverity.INFORMATION, createMessage(it.text, scopeName))
+      holder
+        .newAnnotation(HighlightSeverity.INFORMATION, createMessage(it.text, scopeName))
         .textAttributes(COMPOSE_STATE_READ_TEXT_ATTRIBUTES_KEY)
         .gutterIconRenderer(ComposeStateReadGutterIconRenderer(it.text, scopeName))
         .create()
@@ -99,8 +104,8 @@
   }
 
   /**
-   * Returns whether the expression represents an implicit call to `State#getValue`, i.e. if the expression
-   * is for a delegated property where the delegate is of type `State`.
+   * Returns whether the expression represents an implicit call to `State#getValue`, i.e. if the
+   * expression is for a delegated property where the delegate is of type `State`.
    *
    * E.g. for a name reference expression `foo` if `foo` is defined as:
    *
@@ -113,33 +118,33 @@
   private fun KotlinType.isStateType() =
     (fqName?.asString() == FQNAME || supertypes().any { it.fqName?.asString() == FQNAME })
 
-  private fun KtAnalysisSession.isStateType(type: KtType): Boolean = if (type is KtNonErrorClassType) {
-    type.classId == CLASS_ID_OF_STATE || type.getAllSuperTypes().any { it is KtNonErrorClassType && it.classId == CLASS_ID_OF_STATE }
-  } else {
-    false
-  }
+  private fun KtAnalysisSession.isStateType(type: KtType): Boolean =
+    if (type is KtNonErrorClassType) {
+      type.classId == CLASS_ID_OF_STATE ||
+        type.getAllSuperTypes().any { it is KtNonErrorClassType && it.classId == CLASS_ID_OF_STATE }
+    } else {
+      false
+    }
 
   @OptIn(KtAllowAnalysisOnEdt::class)
   private fun KtExpression.isStateType(): Boolean =
     if (isK2Plugin()) {
-      allowAnalysisOnEdt {
-        analyze(this) {
-          getKtType()?.let { isStateType(it) } ?: false
-        }
-      }
+      allowAnalysisOnEdt { analyze(this) { getKtType()?.let { isStateType(it) } ?: false } }
     } else {
       resolveExprType()?.isStateType() ?: false
     }
 
   private fun KtNameReferenceExpression.isAssignee(): Boolean {
     return parentOfType<KtBinaryExpression>()
-             ?.takeIf { it.operationToken.toString() == "EQ" }
-             ?.let { it.left == this || it.left?.descendants()?.contains(this) == true }
-             ?: false
+      ?.takeIf { it.operationToken.toString() == "EQ" }
+      ?.let { it.left == this || it.left?.descendants()?.contains(this) == true }
+      ?: false
   }
 
-  private data class ComposeStateReadGutterIconRenderer(private val stateName: String,
-                                                        private val functionName: String) : GutterIconRenderer() {
+  private data class ComposeStateReadGutterIconRenderer(
+    private val stateName: String,
+    private val functionName: String
+  ) : GutterIconRenderer() {
     override fun getIcon() = StudioIcons.Common.INFO
     override fun getTooltipText() = createMessage(stateName, functionName)
   }
@@ -147,7 +152,10 @@
   companion object {
     const val COMPOSE_STATE_READ_TEXT_ATTRIBUTES_NAME = "ComposeStateReadTextAttributes"
     val COMPOSE_STATE_READ_TEXT_ATTRIBUTES_KEY: TextAttributesKey =
-      TextAttributesKey.createTextAttributesKey(COMPOSE_STATE_READ_TEXT_ATTRIBUTES_NAME, DefaultLanguageHighlighterColors.FUNCTION_CALL)
+      TextAttributesKey.createTextAttributesKey(
+        COMPOSE_STATE_READ_TEXT_ATTRIBUTES_NAME,
+        DefaultLanguageHighlighterColors.FUNCTION_CALL
+      )
 
     private fun createMessage(stateVariable: String, composable: String) =
       "State read: when the value of \"$stateVariable\" changes, \"$composable\" will recompose."
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/actions/ComposeProximityWeigher.kt b/compose-ide-plugin/src/com/android/tools/compose/code/actions/ComposeProximityWeigher.kt
index 11204e6..631ba51 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/actions/ComposeProximityWeigher.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/actions/ComposeProximityWeigher.kt
@@ -25,16 +25,19 @@
 import org.jetbrains.kotlin.psi.KtNamedDeclaration
 
 /** This weigher is used in determining the order of items in Kotlin's "Add Imports" list. */
-class ComposeProximityWeigher: ProximityWeigher() {
+class ComposeProximityWeigher : ProximityWeigher() {
   override fun weigh(element: PsiElement, location: ProximityLocation): Int? {
     if (location.position?.language != KotlinLanguage.INSTANCE) return null
     if (location.positionModule?.getModuleSystem()?.usesCompose != true) return null
 
-    // In the "Add Import" case, `location` unfortunately points only to the file we're in -- so we can't do anything smart that would take
+    // In the "Add Import" case, `location` unfortunately points only to the file we're in -- so we
+    // can't do anything smart that would take
     // into account the position of the code that needs the import.
 
     // If we've manually weighted this element, use that weight.
-    element.manualWeight()?.let { return it }
+    element.manualWeight()?.let {
+      return it
+    }
 
     if (element.isComposableFunction() && !element.isDeprecated()) return COMPOSABLE_METHOD_WEIGHT
 
@@ -55,7 +58,8 @@
   return MANUALLY_WEIGHTED_FQ_NAMES[fqName]
 }
 
-private val MANUALLY_WEIGHTED_FQ_NAMES = mapOf(
-  "androidx.compose.ui.Modifier" to PROMOTED_WEIGHT,
-  "androidx.compose.ui.graphics.Color" to PROMOTED_WEIGHT,
-)
+private val MANUALLY_WEIGHTED_FQ_NAMES =
+  mapOf(
+    "androidx.compose.ui.Modifier" to PROMOTED_WEIGHT,
+    "androidx.compose.ui.graphics.Color" to PROMOTED_WEIGHT,
+  )
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposeCompletionContributor.kt b/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposeCompletionContributor.kt
index 9b3b983..86f9ff4 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposeCompletionContributor.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposeCompletionContributor.kt
@@ -45,6 +45,9 @@
 import com.intellij.psi.util.parentOfType
 import com.intellij.util.asSafely
 import icons.StudioIcons
+import java.io.BufferedReader
+import javax.swing.Icon
+import javax.swing.ImageIcon
 import org.jetbrains.annotations.VisibleForTesting
 import org.jetbrains.kotlin.analysis.api.KtAllowAnalysisOnEdt
 import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
@@ -74,9 +77,6 @@
 import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
 import org.jetbrains.kotlin.resolve.calls.results.argumentValueType
 import org.jetbrains.kotlin.types.typeUtil.isUnit
-import java.io.BufferedReader
-import javax.swing.Icon
-import javax.swing.ImageIcon
 
 private val COMPOSABLE_FUNCTION_ICON = StudioIcons.Compose.Editor.COMPOSABLE_FUNCTION
 
@@ -91,50 +91,59 @@
   // The only type in the list is the return type (can be Unit).
   type.isFunctionType && argumentValueType.arguments.size == 1
 
-private fun KtAnalysisSession.isLambdaWithNoParameters(valueParameterSymbol: KtValueParameterSymbol): Boolean {
+private fun KtAnalysisSession.isLambdaWithNoParameters(
+  valueParameterSymbol: KtValueParameterSymbol
+): Boolean {
   // The only type in the list is the return type (can be Unit).
   val functionalReturnType = valueParameterSymbol.returnType as? KtFunctionalType ?: return false
   return functionalReturnType.ownTypeArguments.size == 1
 }
 
-/**
- * true iff the last parameter is required, and a lambda type with no parameters.
- */
+/** true iff the last parameter is required, and a lambda type with no parameters. */
 private fun ValueParameterDescriptor.isRequiredLambdaWithNoParameters() =
   !hasDefaultValue() && isLambdaWithNoParameters() && varargElementType == null
 
-/**
- * true iff the last parameter is required, and a lambda type with no parameters.
- */
-private fun KtAnalysisSession.isRequiredLambdaWithNoParameters(valueParameterSymbol: KtValueParameterSymbol) =
-  !valueParameterSymbol.hasDefaultValue && isLambdaWithNoParameters(valueParameterSymbol) && !valueParameterSymbol.isVararg
+/** true iff the last parameter is required, and a lambda type with no parameters. */
+private fun KtAnalysisSession.isRequiredLambdaWithNoParameters(
+  valueParameterSymbol: KtValueParameterSymbol
+) =
+  !valueParameterSymbol.hasDefaultValue &&
+    isLambdaWithNoParameters(valueParameterSymbol) &&
+    !valueParameterSymbol.isVararg
 
 private fun InsertionContext.getParent(): PsiElement? = file.findElementAt(startOffset)?.parent
 
 /**
- * Find the [CallType] from the [InsertionContext]. The [CallType] can be used to detect if the completion is being done in a regular
- * statement, an import or some other expression and decide if we want to apply the [ComposeInsertHandler].
+ * Find the [CallType] from the [InsertionContext]. The [CallType] can be used to detect if the
+ * completion is being done in a regular statement, an import or some other expression and decide if
+ * we want to apply the [ComposeInsertHandler].
  */
 private fun PsiElement?.inferCallType(): CallType<*> {
-  // Look for an existing KtSimpleNameExpression to pass to CallTypeAndReceiver.detect so we can infer the call type.
-  val namedExpression = (this as? KtSimpleNameExpression)?.mainReference?.expression ?: return CallType.DEFAULT
+  // Look for an existing KtSimpleNameExpression to pass to CallTypeAndReceiver.detect so we can
+  // infer the call type.
+  val namedExpression =
+    (this as? KtSimpleNameExpression)?.mainReference?.expression ?: return CallType.DEFAULT
   return CallTypeAndReceiver.detect(namedExpression).callType
 }
 
 /**
  * Return true if element is a KDoc.
  *
- * Ideally, we would use [inferCallType] but there doesn't seem to be a [CallType] for a KDoc element.
+ * Ideally, we would use [inferCallType] but there doesn't seem to be a [CallType] for a KDoc
+ * element.
  */
 private fun PsiElement?.isKdoc() = this is KDocName
 
-/**
- * Modifies [LookupElement]s for composable functions, to improve Compose editing UX.
- */
+/** Modifies [LookupElement]s for composable functions, to improve Compose editing UX. */
 class ComposeCompletionContributor : CompletionContributor() {
-  override fun fillCompletionVariants(parameters: CompletionParameters, resultSet: CompletionResultSet) {
-    if (parameters.position.getModuleSystem()?.usesCompose != true ||
-        parameters.position.language != KotlinLanguage.INSTANCE) {
+  override fun fillCompletionVariants(
+    parameters: CompletionParameters,
+    resultSet: CompletionResultSet
+  ) {
+    if (
+      parameters.position.getModuleSystem()?.usesCompose != true ||
+        parameters.position.language != KotlinLanguage.INSTANCE
+    ) {
       return
     }
 
@@ -153,8 +162,8 @@
       psi.isComposableFunction() ->
         if (lookupElement.isForSpecialLambdaLookupElement()) null
         else completionResult.withLookupElement(ComposableFunctionLookupElement(lookupElement))
-
-      ComposeMaterialIconLookupElement.appliesTo(psi) -> completionResult.withLookupElement(ComposeMaterialIconLookupElement(lookupElement))
+      ComposeMaterialIconLookupElement.appliesTo(psi) ->
+        completionResult.withLookupElement(ComposeMaterialIconLookupElement(lookupElement))
 
       // No transformation needed.
       else -> completionResult
@@ -162,9 +171,10 @@
   }
 
   /**
-   * Checks if the [LookupElement] is an additional, "special" lookup element created for functions that can be invoked using the lambda
-   * syntax. These are created by [LookupElementFactory.addSpecialFunctionCallElements] and can be confusing for Compose APIs that often
-   * use overloaded function names.
+   * Checks if the [LookupElement] is an additional, "special" lookup element created for functions
+   * that can be invoked using the lambda syntax. These are created by
+   * [LookupElementFactory.addSpecialFunctionCallElements] and can be confusing for Compose APIs
+   * that often use overloaded function names.
    */
   private fun LookupElement.isForSpecialLambdaLookupElement(): Boolean {
     val presentation = LookupElementPresentation()
@@ -173,13 +183,10 @@
   }
 }
 
-/**
- * Wraps original Kotlin [LookupElement]s for composable functions to make them stand out more.
- */
-private class ComposableFunctionLookupElement(original: LookupElement) : LookupElementDecorator<LookupElement>(original) {
-  /**
-   * Set of [CallType]s that should be handled by the [ComposeInsertHandler].
-   */
+/** Wraps original Kotlin [LookupElement]s for composable functions to make them stand out more. */
+private class ComposableFunctionLookupElement(original: LookupElement) :
+  LookupElementDecorator<LookupElement>(original) {
+  /** Set of [CallType]s that should be handled by the [ComposeInsertHandler]. */
   private val validCallTypes = setOf(CallType.DEFAULT, CallType.DOT)
 
   init {
@@ -196,14 +203,20 @@
       analyze(element) {
         val functionSymbol = element.getFunctionLikeSymbol()
         presentation.icon = COMPOSABLE_FUNCTION_ICON
-        presentation.setTypeText(if (functionSymbol.returnType.isUnit) null else presentation.typeText, null)
+        presentation.setTypeText(
+          if (functionSymbol.returnType.isUnit) null else presentation.typeText,
+          null
+        )
         val (parameters, tail) = getComposableFunctionRenderParts(functionSymbol)
         rewriteSignature(presentation, parameters, tail)
       }
     } else {
       val descriptor = getFunctionDescriptor() ?: return
       presentation.icon = COMPOSABLE_FUNCTION_ICON
-      presentation.setTypeText(if (descriptor.returnType?.isUnit() == true) null else presentation.typeText, null)
+      presentation.setTypeText(
+        if (descriptor.returnType?.isUnit() == true) null else presentation.typeText,
+        null
+      )
       val (parameters, tail) = descriptor.getComposableFunctionRenderParts()
       rewriteSignature(presentation, parameters, tail)
     }
@@ -231,17 +244,24 @@
     }
   }
 
-  private fun rewriteSignature(presentation: LookupElementPresentation, parameters: String?, tail: String?) {
+  private fun rewriteSignature(
+    presentation: LookupElementPresentation,
+    parameters: String?,
+    tail: String?
+  ) {
     presentation.clearTail()
     parameters?.let { presentation.appendTailTextItalic(it, /* grayed = */ false) }
     tail?.let { presentation.appendTailText(" $it", /* grayed = */ true) }
   }
 }
 
-/** Lookup element that decorates a Compose material icon property with the actual icon it represents. */
+/**
+ * Lookup element that decorates a Compose material icon property with the actual icon it
+ * represents.
+ */
 @VisibleForTesting
-internal class ComposeMaterialIconLookupElement(private val original: LookupElement)
-  : LookupElementDecorator<LookupElement>(original) {
+internal class ComposeMaterialIconLookupElement(private val original: LookupElement) :
+  LookupElementDecorator<LookupElement>(original) {
 
   init {
     // We know we'll want material icons, so start warming up the cache.
@@ -261,36 +281,42 @@
      *
      * The key is the package name, coming from a fully-qualified icon name.
      *
-     * The value is a pair that identifies how to construct names that represent these icons. The first string in each pair represents part
-     * of a directory name where the theme's icons are stored. The second string value represents the prefix of each image's file name.
+     * The value is a pair that identifies how to construct names that represent these icons. The
+     * first string in each pair represents part of a directory name where the theme's icons are
+     * stored. The second string value represents the prefix of each image's file name.
      */
-    private val themeNamingPatterns = mapOf(
-      "androidx.compose.material.icons.filled" to Pair("materialicons", "baseline"),
-      "androidx.compose.material.icons.rounded" to Pair("materialiconsround", "round"),
-      "androidx.compose.material.icons.sharp" to Pair("materialiconssharp", "sharp"),
-      "androidx.compose.material.icons.twotone" to Pair("materialiconstwotone", "twotone"),
-      "androidx.compose.material.icons.outlined" to Pair("materialiconsoutlined", "outline"),
-    )
+    private val themeNamingPatterns =
+      mapOf(
+        "androidx.compose.material.icons.filled" to Pair("materialicons", "baseline"),
+        "androidx.compose.material.icons.rounded" to Pair("materialiconsround", "round"),
+        "androidx.compose.material.icons.sharp" to Pair("materialiconssharp", "sharp"),
+        "androidx.compose.material.icons.twotone" to Pair("materialiconstwotone", "twotone"),
+        "androidx.compose.material.icons.outlined" to Pair("materialiconsoutlined", "outline"),
+      )
 
     /** Whether ComposeMaterialIconLookupElement can apply to the given [LookupElement]. */
     fun appliesTo(psiElement: PsiElement): Boolean {
       if (psiElement !is KtProperty) return false
       val fqName = psiElement.kotlinFqName?.asString() ?: return false
 
-      if (!fqName.startsWith("androidx.compose.material.icons") ||
-          psiElement.typeReference?.text?.endsWith("ImageVector") != true) return false
+      if (
+        !fqName.startsWith("androidx.compose.material.icons") ||
+          psiElement.typeReference?.text?.endsWith("ImageVector") != true
+      )
+        return false
 
       return themeNamingPatterns.containsKey(fqName.substringBeforeLast('.'))
     }
 
     /**
-     * Converts the property name of a Compose material icon to the snake-case equivalent used in file names, with additional underscores
-     * separating digits from non-digit characters.
+     * Converts the property name of a Compose material icon to the snake-case equivalent used in
+     * file names, with additional underscores separating digits from non-digit characters.
      *
      * eg: "AccountBox3" -> "account_box_3"
      *
-     * If a material icon's name starts with a number, the property name has an underscore prepended to make it a valid identifier, even
-     * though the underscore doesn't appear in the file path and name.
+     * If a material icon's name starts with a number, the property name has an underscore prepended
+     * to make it a valid identifier, even though the underscore doesn't appear in the file path and
+     * name.
      *
      * eg: "_1kPlus42" -> "1k_plus_42"
      */
@@ -322,20 +348,32 @@
 
     private fun getIconFromMaterialIconsProvider(fqName: String): Icon? {
       val iconFileName = fqName.iconFileNameFromFqName() ?: return null
-      return ComposeMaterialIconService.getInstance(ApplicationManager.getApplication()).getIcon(iconFileName)
+      return ComposeMaterialIconService.getInstance(ApplicationManager.getApplication())
+        .getIcon(iconFileName)
     }
 
     private fun getIconFromResources(fqName: String): Icon? {
       val resourcePath = fqName.resourcePathFromFqName() ?: return null
 
-      return ComposeMaterialIconLookupElement::class.java.classLoader.getResourceAsStream(resourcePath)?.use { inputStream ->
-        val content = inputStream.bufferedReader().use(BufferedReader::readText)
-        val errorLog = StringBuilder()
-        val bufferedImage = VdPreview.getPreviewFromVectorXml(VdPreview.TargetSize.createFromMaxDimension(16), content, errorLog)
-        if (errorLog.isNotEmpty()) Logger.getInstance(ComposeMaterialIconLookupElement::class.java).error(errorLog.toString())
+      return ComposeMaterialIconLookupElement::class
+        .java
+        .classLoader
+        .getResourceAsStream(resourcePath)
+        ?.use { inputStream ->
+          val content = inputStream.bufferedReader().use(BufferedReader::readText)
+          val errorLog = StringBuilder()
+          val bufferedImage =
+            VdPreview.getPreviewFromVectorXml(
+              VdPreview.TargetSize.createFromMaxDimension(16),
+              content,
+              errorLog
+            )
+          if (errorLog.isNotEmpty())
+            Logger.getInstance(ComposeMaterialIconLookupElement::class.java)
+              .error(errorLog.toString())
 
-        ImageIcon(bufferedImage)
-      }
+          ImageIcon(bufferedImage)
+        }
     }
   }
 }
@@ -345,93 +383,121 @@
   return elementAtCaret.getNextSiblingIgnoringWhitespace(true) ?: return null
 }
 
-private fun InsertionContext.isNextElementOpenCurlyBrace() = getNextElementIgnoringWhitespace()?.text?.startsWith("{") == true
+private fun InsertionContext.isNextElementOpenCurlyBrace() =
+  getNextElementIgnoringWhitespace()?.text?.startsWith("{") == true
 
-private fun InsertionContext.isNextElementOpenParenthesis() = getNextElementIgnoringWhitespace()?.text?.startsWith("(") == true
+private fun InsertionContext.isNextElementOpenParenthesis() =
+  getNextElementIgnoringWhitespace()?.text?.startsWith("(") == true
 
-private abstract class ComposeInsertHandler(callType: CallType<*>) : KotlinCallableInsertHandler(callType) {
-  override fun handleInsert(context: InsertionContext, item: LookupElement) = with(context) {
-    super.handleInsert(context, item)
+private abstract class ComposeInsertHandler(callType: CallType<*>) :
+  KotlinCallableInsertHandler(callType) {
+  override fun handleInsert(context: InsertionContext, item: LookupElement) =
+    with(context) {
+      super.handleInsert(context, item)
 
-    if (isNextElementOpenParenthesis()) return
+      if (isNextElementOpenParenthesis()) return
 
-    // All Kotlin insertion handlers do this, possibly to post-process adding a new import in the call to super above.
-    val psiDocumentManager = PsiDocumentManager.getInstance(project)
-    psiDocumentManager.commitAllDocuments()
-    psiDocumentManager.doPostponedOperationsAndUnblockDocument(document)
+      // All Kotlin insertion handlers do this, possibly to post-process adding a new import in the
+      // call to super above.
+      val psiDocumentManager = PsiDocumentManager.getInstance(project)
+      psiDocumentManager.commitAllDocuments()
+      psiDocumentManager.doPostponedOperationsAndUnblockDocument(document)
 
-    val templateManager = TemplateManager.getInstance(project)
-    val template = templateManager.createTemplate("", "").apply { configureFunctionTemplate(context, template = this) }
+      val templateManager = TemplateManager.getInstance(project)
+      val template =
+        templateManager.createTemplate("", "").apply {
+          configureFunctionTemplate(context, template = this)
+        }
 
-    templateManager.startTemplate(editor, template, object : TemplateEditingAdapter() {
-      override fun templateFinished(template: Template, brokenOff: Boolean) {
-        if (!brokenOff) {
-          val callExpression = file.findElementAt(editor.caretModel.offset)?.parentOfType<KtCallExpression>() ?: return
-          val valueArgumentList = callExpression.valueArgumentList ?: return
-          if (valueArgumentList.arguments.isEmpty() && callExpression.lambdaArguments.isNotEmpty()) {
-            runWriteAction { valueArgumentList.delete() }
+      templateManager.startTemplate(
+        editor,
+        template,
+        object : TemplateEditingAdapter() {
+          override fun templateFinished(template: Template, brokenOff: Boolean) {
+            if (!brokenOff) {
+              val callExpression =
+                file.findElementAt(editor.caretModel.offset)?.parentOfType<KtCallExpression>()
+                  ?: return
+              val valueArgumentList = callExpression.valueArgumentList ?: return
+              if (
+                valueArgumentList.arguments.isEmpty() && callExpression.lambdaArguments.isNotEmpty()
+              ) {
+                runWriteAction { valueArgumentList.delete() }
+              }
+            }
           }
         }
-      }
-    })
-  }
+      )
+    }
 
   abstract fun configureFunctionTemplate(context: InsertionContext, template: Template)
 
   class ParameterInfo(val name: String, val isLambdaWithNoParameters: Boolean)
 
-  fun configureFunctionTemplate(template: Template,
-                                parameterInfoList: List<ParameterInfo>,
-                                insertLambda: Boolean,
-                                isNextElementOpenCurlyBrace: Boolean) = template.apply {
-    isToReformat = true
-    setToIndent(true)
+  fun configureFunctionTemplate(
+    template: Template,
+    parameterInfoList: List<ParameterInfo>,
+    insertLambda: Boolean,
+    isNextElementOpenCurlyBrace: Boolean
+  ) =
+    template.apply {
+      isToReformat = true
+      setToIndent(true)
 
-    when {
-      parameterInfoList.isNotEmpty() -> {
-        addTextSegment("(")
-        parameterInfoList.forEachIndexed { index, paramInfo ->
-          if (index > 0) {
-            addTextSegment(", ")
+      when {
+        parameterInfoList.isNotEmpty() -> {
+          addTextSegment("(")
+          parameterInfoList.forEachIndexed { index, paramInfo ->
+            if (index > 0) {
+              addTextSegment(", ")
+            }
+            addTextSegment(paramInfo.name + " = ")
+            if (paramInfo.isLambdaWithNoParameters) {
+              addVariable(ConstantNode("{ /*TODO*/ }"), true)
+            } else {
+              addVariable(EmptyExpression(), true)
+            }
           }
-          addTextSegment(paramInfo.name + " = ")
-          if (paramInfo.isLambdaWithNoParameters) {
-            addVariable(ConstantNode("{ /*TODO*/ }"), true)
-          }
-          else {
-            addVariable(EmptyExpression(), true)
-          }
+          addTextSegment(")")
         }
-        addTextSegment(")")
+        !insertLambda -> addTextSegment("()")
       }
 
-      !insertLambda -> addTextSegment("()")
+      if (insertLambda && !isNextElementOpenCurlyBrace) {
+        addTextSegment(" {\n")
+        addEndVariable()
+        addTextSegment("\n}")
+      }
     }
-
-    if (insertLambda && !isNextElementOpenCurlyBrace) {
-      addTextSegment(" {\n")
-      addEndVariable()
-      addTextSegment("\n}")
-    }
-  }
 }
 
-private class ComposeInsertHandlerForK1(val functionDescriptor: FunctionDescriptor, callType: CallType<*>) : ComposeInsertHandler(
-  callType) {
+private class ComposeInsertHandlerForK1(
+  val functionDescriptor: FunctionDescriptor,
+  callType: CallType<*>
+) : ComposeInsertHandler(callType) {
   override fun configureFunctionTemplate(context: InsertionContext, template: Template) {
     val allParameters = functionDescriptor.valueParameters
-    val requiredParameters = allParameters.filter { !it.declaresDefaultValue() && it.varargElementType == null }
-    val insertLambda = allParameters.lastOrNull()?.let { valueParamDescriptor ->
-      valueParamDescriptor.isComposableFunctionParameter() || valueParamDescriptor.isRequiredLambdaWithNoParameters()
-    } == true
+    val requiredParameters =
+      allParameters.filter { !it.declaresDefaultValue() && it.varargElementType == null }
+    val insertLambda =
+      allParameters.lastOrNull()?.let { valueParamDescriptor ->
+        valueParamDescriptor.isComposableFunctionParameter() ||
+          valueParamDescriptor.isRequiredLambdaWithNoParameters()
+      } == true
     val inParens = if (insertLambda) requiredParameters.dropLast(1) else requiredParameters
-    configureFunctionTemplate(template, inParens.map { ParameterInfo(it.name.asString(), it.isLambdaWithNoParameters()) }, insertLambda,
-                              context.isNextElementOpenCurlyBrace())
+    configureFunctionTemplate(
+      template,
+      inParens.map { ParameterInfo(it.name.asString(), it.isLambdaWithNoParameters()) },
+      insertLambda,
+      context.isNextElementOpenCurlyBrace()
+    )
   }
 }
 
-private class ComposeInsertHandlerForK2(val functionElement: KtNamedFunction, callType: CallType<*>) : ComposeInsertHandler(
-  callType) {
+private class ComposeInsertHandlerForK2(
+  val functionElement: KtNamedFunction,
+  callType: CallType<*>
+) : ComposeInsertHandler(callType) {
   @OptIn(KtAllowAnalysisOnEdt::class)
   override fun configureFunctionTemplate(context: InsertionContext, template: Template) {
     allowAnalysisOnEdt {
@@ -439,12 +505,18 @@
         val functionSymbol = functionElement.getFunctionLikeSymbol()
         val allParameters = functionSymbol.valueParameters
         val requiredParameters = allParameters.filter { !it.hasDefaultValue && !it.isVararg }
-        val insertLambda = allParameters.lastOrNull()?.let { valueParamSymbol ->
-          isComposableFunctionParameter(valueParamSymbol) || isRequiredLambdaWithNoParameters(valueParamSymbol)
-        } == true
+        val insertLambda =
+          allParameters.lastOrNull()?.let { valueParamSymbol ->
+            isComposableFunctionParameter(valueParamSymbol) ||
+              isRequiredLambdaWithNoParameters(valueParamSymbol)
+          } == true
         val inParens = if (insertLambda) requiredParameters.dropLast(1) else requiredParameters
-        configureFunctionTemplate(template, inParens.map { ParameterInfo(it.name.asString(), isLambdaWithNoParameters(it)) }, insertLambda,
-                                  context.isNextElementOpenCurlyBrace())
+        configureFunctionTemplate(
+          template,
+          inParens.map { ParameterInfo(it.name.asString(), isLambdaWithNoParameters(it)) },
+          insertLambda,
+          context.isNextElementOpenCurlyBrace()
+        )
       }
     }
   }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposeCompletionWeigher.kt b/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposeCompletionWeigher.kt
index 59fbcd5..721a957 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposeCompletionWeigher.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposeCompletionWeigher.kt
@@ -32,18 +32,20 @@
 /**
  * Custom [CompletionWeigher] which moves Composable functions up the completion list.
  *
- * It doesn't give Composable functions "absolute" priority, some weighers are hardcoded to run first: specifically one that puts prefix
- * matches above [LookupElement]s where the match is in the middle of the name. Overriding this behavior would require an extension point in
+ * It doesn't give Composable functions "absolute" priority, some weighers are hardcoded to run
+ * first: specifically one that puts prefix matches above [LookupElement]s where the match is in the
+ * middle of the name. Overriding this behavior would require an extension point in
  * [org.jetbrains.kotlin.idea.completion.CompletionSession.createSorter].
  *
- * See [com.intellij.codeInsight.completion.PrioritizedLookupElement] for more information on how ordering of [LookupElement]s works and how
- * to debug it.
+ * See [com.intellij.codeInsight.completion.PrioritizedLookupElement] for more information on how
+ * ordering of [LookupElement]s works and how to debug it.
  */
 class ComposeCompletionWeigher : CompletionWeigher() {
   override fun weigh(element: LookupElement, location: CompletionLocation): Int {
     if (!location.completionParameters.isInComposeEnabledModuleAndFile()) return 0
 
-    // Since Compose uses so many named arguments, promote them to the top. This is for a case where the user has typed something like
+    // Since Compose uses so many named arguments, promote them to the top. This is for a case where
+    // the user has typed something like
     // "Button(en<caret>)", and we want to promote the completion "enabled = Boolean".
     if (element.isNamedArgumentCompletion()) return 3
 
@@ -71,22 +73,34 @@
   }
 }
 
-/** Set of fully-qualified names of non-Composable functions that should be promoted above standard Composables in a statement. */
-private val PROMOTED_NON_COMPOSABLES_IN_STATEMENTS = setOf(
-  "androidx.compose.material.MaterialTheme",
-  "androidx.compose.material3.MaterialTheme",
-)
+/**
+ * Set of fully-qualified names of non-Composable functions that should be promoted above standard
+ * Composables in a statement.
+ */
+private val PROMOTED_NON_COMPOSABLES_IN_STATEMENTS =
+  setOf(
+    "androidx.compose.material.MaterialTheme",
+    "androidx.compose.material3.MaterialTheme",
+  )
 
-/** Set of fully-qualified names of non-Composable functions that should be promoted in a value argument. */
-private val PROMOTED_NON_COMPOSABLES_IN_ARGUMENTS = setOf(
-  "androidx.compose.material.MaterialTheme",
-  "androidx.compose.material3.MaterialTheme",
-)
+/**
+ * Set of fully-qualified names of non-Composable functions that should be promoted in a value
+ * argument.
+ */
+private val PROMOTED_NON_COMPOSABLES_IN_ARGUMENTS =
+  setOf(
+    "androidx.compose.material.MaterialTheme",
+    "androidx.compose.material3.MaterialTheme",
+  )
 
-/** Set of fully-qualified name prefixes of non-Composable functions that should be promoted in a value argument. */
-private val PROMOTED_NON_COMPOSABLE_PREFIXES_IN_ARGUMENTS = setOf(
-  "androidx.compose.material.icons.",
-)
+/**
+ * Set of fully-qualified name prefixes of non-Composable functions that should be promoted in a
+ * value argument.
+ */
+private val PROMOTED_NON_COMPOSABLE_PREFIXES_IN_ARGUMENTS =
+  setOf(
+    "androidx.compose.material.icons.",
+  )
 
 private fun LookupElement.isPromotedInStatement(): Boolean {
   val fqName = (psiElement as? KtNamedDeclaration)?.fqName?.asString()
@@ -96,7 +110,7 @@
 private fun LookupElement.isPromotedInArgument(): Boolean {
   val fqName = (psiElement as? KtNamedDeclaration)?.fqName?.asString() ?: return false
   return PROMOTED_NON_COMPOSABLES_IN_ARGUMENTS.contains(fqName) ||
-         PROMOTED_NON_COMPOSABLE_PREFIXES_IN_ARGUMENTS.any { fqName.startsWith(it) }
+    PROMOTED_NON_COMPOSABLE_PREFIXES_IN_ARGUMENTS.any { fqName.startsWith(it) }
 }
 
 /** Checks if the proposed completion would insert a composable function. */
@@ -105,13 +119,22 @@
 /** Checks if the proposed completion would insert a named argument. */
 private fun LookupElement.isNamedArgumentCompletion() = lookupString.endsWith(" =")
 
-/** Checks if this completion is for a statement (where Compose views are usually called) and not part of another expression. */
+/**
+ * Checks if this completion is for a statement (where Compose views are usually called) and not
+ * part of another expression.
+ */
 private fun CompletionParameters.isForStatement() =
-  position is LeafPsiElement && position.node.elementType == KtTokens.IDENTIFIER && position.parent?.parent is KtBlockExpression
+  position is LeafPsiElement &&
+    position.node.elementType == KtTokens.IDENTIFIER &&
+    position.parent?.parent is KtBlockExpression
 
-/** Checks if this completion is for a value argument, where Compose views are usually not called. */
+/**
+ * Checks if this completion is for a value argument, where Compose views are usually not called.
+ */
 private fun CompletionParameters.isForValueArgument() =
-  position is LeafPsiElement && position.node.elementType == KtTokens.IDENTIFIER && position.parentOfType<KtValueArgument>() != null
+  position is LeafPsiElement &&
+    position.node.elementType == KtTokens.IDENTIFIER &&
+    position.parentOfType<KtValueArgument>() != null
 
 /** Checks if the given completions parameters are in a Kotlin file in a Compose-enabled module. */
 private fun CompletionParameters.isInComposeEnabledModuleAndFile() =
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposeMaterialIconService.kt b/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposeMaterialIconService.kt
index 248dca7..115015f 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposeMaterialIconService.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposeMaterialIconService.kt
@@ -25,22 +25,24 @@
 import com.intellij.openapi.components.Service
 import com.intellij.openapi.components.service
 import java.lang.ref.SoftReference
-import org.jetbrains.annotations.VisibleForTesting
 import java.util.concurrent.atomic.AtomicBoolean
 import javax.swing.Icon
 import javax.swing.ImageIcon
+import org.jetbrains.annotations.VisibleForTesting
 
-typealias IconLoader = ((MaterialVdIcons, MaterialVdIconsProvider.Status) -> Unit, Disposable) -> Unit
+typealias IconLoader =
+  ((MaterialVdIcons, MaterialVdIconsProvider.Status) -> Unit, Disposable) -> Unit
 
 /**
  * Light service providing cached Material icons for usage in the autocomplete dialog.
  *
- * Icons are loaded using [MaterialVdIconsProvider], sized to 16x16 to fit autocomplete UI, and are stored using soft references so that
- * they will be discarded if there is memory pressure.
+ * Icons are loaded using [MaterialVdIconsProvider], sized to 16x16 to fit autocomplete UI, and are
+ * stored using soft references so that they will be discarded if there is memory pressure.
  */
 @Service
 internal class ComposeMaterialIconService
-  @VisibleForTesting internal constructor(private val loadIcons: IconLoader) : Disposable {
+@VisibleForTesting
+internal constructor(private val loadIcons: IconLoader) : Disposable {
   constructor() : this(ComposeMaterialIconService::callLoadMaterialVdIcons)
 
   private var iconsWrapper: SoftReference<MaterialVdIconsWrapper> = SoftReference(null)
@@ -54,21 +56,26 @@
   /**
    * Gets an icon given its expected filename.
    *
-   * The filename should follow the idiomatic file format for Material icons of "<theme>_<iconname>_24.xml". For example, the Attachment
-   * icon in the Sharp theme would have the name "sharp_attachment_24.xml".
+   * The filename should follow the idiomatic file format for Material icons of
+   * "<theme>_<iconname>_24.xml". For example, the Attachment icon in the Sharp theme would have the
+   * name "sharp_attachment_24.xml".
    */
   fun getIcon(iconFileName: String): Icon? {
     // Return an icon if we currently have a reference to the icon wrapper.
-    iconsWrapper.get()?.let { return@getIcon it.getIcon(iconFileName) }
+    iconsWrapper.get()?.let {
+      return@getIcon it.getIcon(iconFileName)
+    }
 
-    // Since there's no reference, go ahead and start loading icons but don't wait for it to complete.
+    // Since there's no reference, go ahead and start loading icons but don't wait for it to
+    // complete.
     ensureIconsLoaded()
     return null
   }
 
   /**
-   * Icons are loaded using [MaterialVdIconsProvider], which will download icons if they aren't already available on disk. This method kicks
-   * off the loading process, and can be used in situations when we know we might be requesting icons shortly.
+   * Icons are loaded using [MaterialVdIconsProvider], which will download icons if they aren't
+   * already available on disk. This method kicks off the loading process, and can be used in
+   * situations when we know we might be requesting icons shortly.
    */
   fun ensureIconsLoaded() {
     // If we have the icon wrapper, there's no need to start a new loading process.
@@ -79,7 +86,8 @@
       return
     }
 
-    // Check once more for whether we have icons, on the small chance that loading completed between the above two checks.
+    // Check once more for whether we have icons, on the small chance that loading completed between
+    // the above two checks.
     if (iconsWrapper.get() != null) {
       iconLoadingInProgress.set(false)
       return
@@ -89,8 +97,12 @@
     loadIcons(this::materialVdIconsLoadedCallback, this)
   }
 
-  private fun materialVdIconsLoadedCallback(icons: MaterialVdIcons, status: MaterialVdIconsProvider.Status) {
-    // Store a wrapper using returned icons. When this callback is called multiple times, each call supersedes the last and contains a
+  private fun materialVdIconsLoadedCallback(
+    icons: MaterialVdIcons,
+    status: MaterialVdIconsProvider.Status
+  ) {
+    // Store a wrapper using returned icons. When this callback is called multiple times, each call
+    // supersedes the last and contains a
     // superset of its icons.
     iconsWrapper = SoftReference(MaterialVdIconsWrapper(icons))
 
@@ -99,7 +111,8 @@
   }
 
   /**
-   * Wrapper around [MaterialVdIcons] providing lookup access by icon name and resizing the icons for auto-complete.
+   * Wrapper around [MaterialVdIcons] providing lookup access by icon name and resizing the icons
+   * for auto-complete.
    */
   private class MaterialVdIconsWrapper(materialVdIcons: MaterialVdIcons) {
 
@@ -116,9 +129,14 @@
   companion object {
     fun getInstance(application: Application): ComposeMaterialIconService = application.service()
 
-    /** Call to [MaterialVdIconsProvider.loadMaterialVdIcons] wrapped in a function to allow overriding for tests. */
-    private fun callLoadMaterialVdIcons(refreshUiCallback: (MaterialVdIcons, MaterialVdIconsProvider.Status) -> Unit,
-                                        parentDisposable: Disposable) {
+    /**
+     * Call to [MaterialVdIconsProvider.loadMaterialVdIcons] wrapped in a function to allow
+     * overriding for tests.
+     */
+    private fun callLoadMaterialVdIcons(
+      refreshUiCallback: (MaterialVdIcons, MaterialVdIconsProvider.Status) -> Unit,
+      parentDisposable: Disposable
+    ) {
       MaterialVdIconsProvider.loadMaterialVdIcons(refreshUiCallback, parentDisposable)
     }
   }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposeModifierCompletionContributor.kt b/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposeModifierCompletionContributor.kt
index d9f522b..7a9f2c9 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposeModifierCompletionContributor.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposeModifierCompletionContributor.kt
@@ -98,10 +98,11 @@
 /**
  * Enhances code completion for Modifier (androidx.compose.ui.Modifier)
  *
- * Adds Modifier extension functions to code completion in places where modifier is expected
- * e.g. parameter of type Modifier, variable of type Modifier as it was called on Modifier.<caret>
+ * Adds Modifier extension functions to code completion in places where modifier is expected e.g.
+ * parameter of type Modifier, variable of type Modifier as it was called on Modifier.<caret>
  *
- * Moves extension functions for method called on modifier [isMethodCalledOnModifier] up in the completion list.
+ * Moves extension functions for method called on modifier [isMethodCalledOnModifier] up in the
+ * completion list.
  *
  * @see COMPOSE_MODIFIER_FQN
  */
@@ -114,43 +115,77 @@
     resultSet: CompletionResultSet,
   ) {
     val originalPosition = parameters.position
-    val extensionFunctionSymbols = getExtensionFunctionsForModifier(nameExpression, originalPosition, resultSet.prefixMatcher)
+    val extensionFunctionSymbols =
+      getExtensionFunctionsForModifier(nameExpression, originalPosition, resultSet.prefixMatcher)
 
     ProgressManager.checkCanceled()
-    val (returnsModifier, others) = extensionFunctionSymbols.partition { asFqName(it.returnType)?.asString() == COMPOSE_MODIFIER_FQN }
+    val (returnsModifier, others) =
+      extensionFunctionSymbols.partition {
+        asFqName(it.returnType)?.asString() == COMPOSE_MODIFIER_FQN
+      }
     val lookupElementFactory = KotlinFirLookupElementFactory()
-    val importStrategyDetector = ImportStrategyDetector(nameExpression.containingKtFile, nameExpression.project)
+    val importStrategyDetector =
+      ImportStrategyDetector(nameExpression.containingKtFile, nameExpression.project)
 
-    val isNewModifier = !isMethodCalledOnImportedModifier && originalPosition.parentOfType<KtDotQualifiedExpression>() == null
-    //Prioritise functions that return Modifier over other extension function.
+    val isNewModifier =
+      !isMethodCalledOnImportedModifier &&
+        originalPosition.parentOfType<KtDotQualifiedExpression>() == null
+    // Prioritise functions that return Modifier over other extension function.
     resultSet.addAllElements(
-      toLookupElements(returnsModifier, lookupElementFactory, importStrategyDetector, 2.0, insertModifier = isNewModifier))
-    //If user didn't type Modifier don't suggest extensions that doesn't return Modifier.
+      toLookupElements(
+        returnsModifier,
+        lookupElementFactory,
+        importStrategyDetector,
+        2.0,
+        insertModifier = isNewModifier
+      )
+    )
+    // If user didn't type Modifier don't suggest extensions that doesn't return Modifier.
     if (isMethodCalledOnImportedModifier) {
-      resultSet.addAllElements(toLookupElements(others, lookupElementFactory, importStrategyDetector, 0.0, insertModifier = isNewModifier))
+      resultSet.addAllElements(
+        toLookupElements(
+          others,
+          lookupElementFactory,
+          importStrategyDetector,
+          0.0,
+          insertModifier = isNewModifier
+        )
+      )
     }
 
     ProgressManager.checkCanceled()
 
-    //If method is called on modifier [KotlinCompletionContributor] will add extensions function one more time, we need to filter them out.
+    // If method is called on modifier [KotlinCompletionContributor] will add extensions function
+    // one more time, we need to filter them out.
     if (isMethodCalledOnImportedModifier) {
-      val extensionFunctionsNames = extensionFunctionSymbols.mapNotNull { (it as? KtNamedSymbol)?.name?.asString() }.toSet()
+      val extensionFunctionsNames =
+        extensionFunctionSymbols.mapNotNull { (it as? KtNamedSymbol)?.name?.asString() }.toSet()
       resultSet.runRemainingContributors(parameters) { completionResult ->
-        consumerCompletionResultFromRemainingContributor(completionResult, extensionFunctionsNames, originalPosition, resultSet)
+        consumerCompletionResultFromRemainingContributor(
+          completionResult,
+          extensionFunctionsNames,
+          originalPosition,
+          resultSet
+        )
       }
     }
   }
 
-  override fun fillCompletionVariants(parameters: CompletionParameters, resultSet: CompletionResultSet) {
+  override fun fillCompletionVariants(
+    parameters: CompletionParameters,
+    resultSet: CompletionResultSet
+  ) {
     val element = parameters.position
     if (!isComposeEnabled(element) || parameters.originalFile !is KtFile) {
       return
     }
 
-    // It says "on imported" because only in that case we are able to resolve that it called on Modifier.
+    // It says "on imported" because only in that case we are able to resolve that it called on
+    // Modifier.
     val isMethodCalledOnImportedModifier = element.isMethodCalledOnModifier()
     ProgressManager.checkCanceled()
-    val isModifierType = isMethodCalledOnImportedModifier || element.isModifierArgument || element.isModifierProperty
+    val isModifierType =
+      isMethodCalledOnImportedModifier || element.isModifierArgument || element.isModifierProperty
     if (!isModifierType) return
 
     ProgressManager.checkCanceled()
@@ -159,33 +194,52 @@
 
     if (isK2Plugin()) {
       analyze(nameExpression) {
-        fillCompletionVariants(parameters, nameExpression, isMethodCalledOnImportedModifier, resultSet)
+        fillCompletionVariants(
+          parameters,
+          nameExpression,
+          isMethodCalledOnImportedModifier,
+          resultSet
+        )
       }
       return
     }
 
     // For K1
-    val extensionFunctions = getExtensionFunctionsForModifier(nameExpression, element, resultSet.prefixMatcher)
+    val extensionFunctions =
+      getExtensionFunctionsForModifier(nameExpression, element, resultSet.prefixMatcher)
 
     ProgressManager.checkCanceled()
-    val (returnsModifier, others) = extensionFunctions.partition { it.returnType?.fqName?.asString() == COMPOSE_MODIFIER_FQN }
-    val lookupElementFactory = createLookupElementFactory(parameters.editor, nameExpression, parameters)
+    val (returnsModifier, others) =
+      extensionFunctions.partition { it.returnType?.fqName?.asString() == COMPOSE_MODIFIER_FQN }
+    val lookupElementFactory =
+      createLookupElementFactory(parameters.editor, nameExpression, parameters)
 
-    val isNewModifier = !isMethodCalledOnImportedModifier && element.parentOfType<KtDotQualifiedExpression>() == null
-    //Prioritise functions that return Modifier over other extension function.
-    resultSet.addAllElements(returnsModifier.toLookupElements(lookupElementFactory, 2.0, insertModifier = isNewModifier))
-    //If user didn't type Modifier don't suggest extensions that doesn't return Modifier.
+    val isNewModifier =
+      !isMethodCalledOnImportedModifier && element.parentOfType<KtDotQualifiedExpression>() == null
+    // Prioritise functions that return Modifier over other extension function.
+    resultSet.addAllElements(
+      returnsModifier.toLookupElements(lookupElementFactory, 2.0, insertModifier = isNewModifier)
+    )
+    // If user didn't type Modifier don't suggest extensions that doesn't return Modifier.
     if (isMethodCalledOnImportedModifier) {
-      resultSet.addAllElements(others.toLookupElements(lookupElementFactory, 0.0, insertModifier = isNewModifier))
+      resultSet.addAllElements(
+        others.toLookupElements(lookupElementFactory, 0.0, insertModifier = isNewModifier)
+      )
     }
 
     ProgressManager.checkCanceled()
 
-    //If method is called on modifier [KotlinCompletionContributor] will add extensions function one more time, we need to filter them out.
+    // If method is called on modifier [KotlinCompletionContributor] will add extensions function
+    // one more time, we need to filter them out.
     if (isMethodCalledOnImportedModifier) {
       val extensionFunctionsNames = extensionFunctions.map { it.name.asString() }.toSet()
       resultSet.runRemainingContributors(parameters) { completionResult ->
-        consumerCompletionResultFromRemainingContributor(completionResult, extensionFunctionsNames, element, resultSet)
+        consumerCompletionResultFromRemainingContributor(
+          completionResult,
+          extensionFunctionsNames,
+          element,
+          resultSet
+        )
       }
     }
   }
@@ -198,13 +252,16 @@
     resultSet: CompletionResultSet
   ) {
     val suggestedKtFunction = completionResult.lookupElement.psiElement as? KtFunction
-    val alreadyAddedResult = suggestedKtFunction?.name?.let { extensionFunctionsNames.contains(it) } == true
+    val alreadyAddedResult =
+      suggestedKtFunction?.name?.let { extensionFunctionsNames.contains(it) } == true
 
-    // Only call [isVisibleFromCompletionPosition] if the function is on an internal object, since that method is heavier.
-    // TODO (b/280093734): Remove this workaround once https://youtrack.jetbrains.com/issue/KTIJ-23360 is resolved.
+    // Only call [isVisibleFromCompletionPosition] if the function is on an internal object, since
+    // that method is heavier.
+    // TODO (b/280093734): Remove this workaround once
+    // https://youtrack.jetbrains.com/issue/KTIJ-23360 is resolved.
     val isOnInvisibleObject =
-      suggestedKtFunction?.containingClassOrObject?.hasModifier(KtTokens.INTERNAL_KEYWORD) == true &&
-      !suggestedKtFunction.isVisibleFromCompletionPosition(completionPositionElement)
+      suggestedKtFunction?.containingClassOrObject?.hasModifier(KtTokens.INTERNAL_KEYWORD) ==
+        true && !suggestedKtFunction.isVisibleFromCompletionPosition(completionPositionElement)
 
     if (!alreadyAddedResult && !isOnInvisibleObject) {
       resultSet.passResult(completionResult)
@@ -212,25 +269,33 @@
   }
 
   /**
-   * Checks if the given function is visible from the completion position. Workaround for b/279049842 and b/252977033.
+   * Checks if the given function is visible from the completion position. Workaround for
+   * b/279049842 and b/252977033.
    *
-   * Some suggestions for Modifier extensions are extension functions that live on internal objects in Compose libraries. These aren't legal
-   * to be directly referenced from users' code, but the Kotlin plugin suggests them anyway. This is tracked by
+   * Some suggestions for Modifier extensions are extension functions that live on internal objects
+   * in Compose libraries. These aren't legal to be directly referenced from users' code, but the
+   * Kotlin plugin suggests them anyway. This is tracked by
    * https://youtrack.jetbrains.com/issue/KTIJ-23360.
    *
-   * In the meantime, this method checks whether the containing class/object of the function is visible from the completion position. If
-   * not, then it will be filtered out from results.
+   * In the meantime, this method checks whether the containing class/object of the function is
+   * visible from the completion position. If not, then it will be filtered out from results.
    */
   private fun KtFunction.isVisibleFromCompletionPosition(completionPosition: PsiElement): Boolean {
-    // This is Compose, we should always be completing in a KtFile. If not, let's just assume things are visible so as not to muck with
+    // This is Compose, we should always be completing in a KtFile. If not, let's just assume things
+    // are visible so as not to muck with
     // whatever behavior is happening.
     val ktFile = completionPosition.containingFile as? KtFile ?: return true
 
     val elementToAnalyze = this.containingClassOrObject ?: this
     analyze(elementToAnalyze) {
-      val symbolWithVisibility = elementToAnalyze.getSymbol() as? KtSymbolWithVisibility ?: return true
+      val symbolWithVisibility =
+        elementToAnalyze.getSymbol() as? KtSymbolWithVisibility ?: return true
 
-      return isVisible(symbolWithVisibility, useSiteFile = ktFile.getFileSymbol(), position = completionPosition)
+      return isVisible(
+        symbolWithVisibility,
+        useSiteFile = ktFile.getFileSymbol(),
+        position = completionPosition
+      )
     }
   }
 
@@ -239,9 +304,11 @@
     weight: Double,
     insertModifier: Boolean
   ) = flatMap { descriptor ->
-    lookupElementFactory.createStandardLookupElementsForDescriptor(descriptor, useReceiverTypes = true).map {
-      PrioritizedLookupElement.withPriority(ModifierLookupElement(it, insertModifier), weight)
-    }
+    lookupElementFactory
+      .createStandardLookupElementsForDescriptor(descriptor, useReceiverTypes = true)
+      .map {
+        PrioritizedLookupElement.withPriority(ModifierLookupElement(it, insertModifier), weight)
+      }
   }
 
   @Suppress("UnstableApiUsage")
@@ -251,16 +318,20 @@
     importStrategyDetector: ImportStrategyDetector,
     weight: Double,
     insertModifier: Boolean
-  ) = functionSymbols.map { symbol ->
-    with(lookupElementFactory) {
-      val lookupElement = createLookupElement(symbol as KtNamedSymbol, importStrategyDetector)
-      PrioritizedLookupElement.withPriority(ModifierLookupElement(lookupElement, insertModifier), weight)
+  ) =
+    functionSymbols.map { symbol ->
+      with(lookupElementFactory) {
+        val lookupElement = createLookupElement(symbol as KtNamedSymbol, importStrategyDetector)
+        PrioritizedLookupElement.withPriority(
+          ModifierLookupElement(lookupElement, insertModifier),
+          weight
+        )
+      }
     }
-  }
 
   /**
-   * Creates LookupElementFactory that is similar to the one kotlin-plugin uses during completion session.
-   * Code partially copied from [CompletionSession].
+   * Creates LookupElementFactory that is similar to the one kotlin-plugin uses during completion
+   * session. Code partially copied from [CompletionSession].
    */
   private fun createLookupElementFactory(
     editor: Editor,
@@ -274,20 +345,30 @@
     val moduleDescriptor = resolutionFacade.moduleDescriptor
 
     val callTypeAndReceiver = CallTypeAndReceiver.detect(nameExpression)
-    val receiverTypes = callTypeAndReceiver.receiverTypesWithIndex(
-      bindingContext, nameExpression, moduleDescriptor, resolutionFacade,
-      stableSmartCastsOnly = true, /* we don't include smart cast receiver types for "unstable" receiver value to mark members grayed */
-      withImplicitReceiversWhenExplicitPresent = true
-    )
+    val receiverTypes =
+      callTypeAndReceiver.receiverTypesWithIndex(
+        bindingContext,
+        nameExpression,
+        moduleDescriptor,
+        resolutionFacade,
+        stableSmartCastsOnly =
+          true, /* we don't include smart cast receiver types for "unstable" receiver value to mark members grayed */
+        withImplicitReceiversWhenExplicitPresent = true
+      )
 
-    val inDescriptor = nameExpression.getResolutionScope(bindingContext, resolutionFacade).ownerDescriptor
+    val inDescriptor =
+      nameExpression.getResolutionScope(bindingContext, resolutionFacade).ownerDescriptor
 
     val insertHandler = InsertHandlerProvider(CallType.DOT, parameters.editor, ::emptyList)
     val basicLookupElementFactory = BasicLookupElementFactory(nameExpression.project, insertHandler)
 
     return LookupElementFactory(
-      basicLookupElementFactory, editor, receiverTypes,
-      callTypeAndReceiver.callType, inDescriptor, CollectRequiredTypesContextVariablesProvider()
+      basicLookupElementFactory,
+      editor,
+      receiverTypes,
+      callTypeAndReceiver.callType,
+      inDescriptor,
+      CollectRequiredTypesContextVariablesProvider()
     )
   }
 
@@ -297,8 +378,13 @@
   private fun createNameExpression(originalElement: PsiElement): KtSimpleNameExpression {
     val originalFile = originalElement.containingFile as KtFile
 
-    val file = KtPsiFactory.contextual(originalFile).createFile("temp.kt", "val x = $COMPOSE_MODIFIER_FQN.call")
-    return file.getChildOfType<KtProperty>()!!.getChildOfType<KtDotQualifiedExpression>()!!.lastChild as KtSimpleNameExpression
+    val file =
+      KtPsiFactory.contextual(originalFile)
+        .createFile("temp.kt", "val x = $COMPOSE_MODIFIER_FQN.call")
+    return file
+      .getChildOfType<KtProperty>()!!
+      .getChildOfType<KtDotQualifiedExpression>()!!
+      .lastChild as KtSimpleNameExpression
   }
 
   private fun KtAnalysisSession.findReceiverSymbol(element: KtElement): KtClassOrObjectSymbol? {
@@ -306,7 +392,8 @@
       when (element) {
         is KtNameReferenceExpression -> element
         else -> element.childrenOfType<KtNameReferenceExpression>().singleOrNull()
-      } ?: return null
+      }
+        ?: return null
     val reference = namedReferenceExpression.mainReference as? KtSimpleNameReference ?: return null
     return reference.resolveToSymbol() as? KtClassOrObjectSymbol
   }
@@ -321,11 +408,20 @@
     val searchScope = getResolveScope(file)
     val callTypeAndReceiver = CallTypeAndReceiver.detect(nameExpression)
     val receiverSymbol = callTypeAndReceiver.receiver?.let { findReceiverSymbol(it) }
-    return HLIndexHelper(nameExpression.project, searchScope).getTopLevelExtensions(
-      { name -> prefixMatcher.prefixMatches(name.asString()) }, setOfNotNull(
-      receiverSymbol?.classIdIfNonLocal?.shortClassName?.identifier)).mapNotNull { it.getSymbol() as? KtCallableSymbol }.filter {
-      isVisible(it as KtSymbolWithVisibility, fileSymbol, callTypeAndReceiver.receiver as? KtExpression, originalPosition)
-    }
+    return HLIndexHelper(nameExpression.project, searchScope)
+      .getTopLevelExtensions(
+        { name -> prefixMatcher.prefixMatches(name.asString()) },
+        setOfNotNull(receiverSymbol?.classIdIfNonLocal?.shortClassName?.identifier)
+      )
+      .mapNotNull { it.getSymbol() as? KtCallableSymbol }
+      .filter {
+        isVisible(
+          it as KtSymbolWithVisibility,
+          fileSymbol,
+          callTypeAndReceiver.receiver as? KtExpression,
+          originalPosition
+        )
+      }
   }
 
   private fun getExtensionFunctionsForModifier(
@@ -341,7 +437,12 @@
     val callTypeAndReceiver = CallTypeAndReceiver.detect(nameExpression)
     fun isVisible(descriptor: DeclarationDescriptor): Boolean {
       if (descriptor is DeclarationDescriptorWithVisibility) {
-        return descriptor.isVisible(originalPosition, callTypeAndReceiver.receiver as? KtExpression, bindingContext, resolutionFacade)
+        return descriptor.isVisible(
+          originalPosition,
+          callTypeAndReceiver.receiver as? KtExpression,
+          bindingContext,
+          resolutionFacade
+        )
       }
 
       return true
@@ -350,7 +451,13 @@
     val indicesHelper = KotlinIndicesHelper(resolutionFacade, searchScope, ::isVisible, file = file)
 
     val nameFilter = { name: String -> prefixMatcher.prefixMatches(name) }
-    return indicesHelper.getCallableTopLevelExtensions(callTypeAndReceiver, nameExpression, bindingContext, null, nameFilter)
+    return indicesHelper.getCallableTopLevelExtensions(
+      callTypeAndReceiver,
+      nameExpression,
+      bindingContext,
+      null,
+      nameFilter
+    )
   }
 
   private val PsiElement.isModifierProperty: Boolean
@@ -362,10 +469,13 @@
 
   private val PsiElement.isModifierArgument: Boolean
     get() {
-      val argument = contextOfType<KtValueArgument>().takeIf { it !is KtLambdaArgument } ?: return false
+      val argument =
+        contextOfType<KtValueArgument>().takeIf { it !is KtLambdaArgument } ?: return false
 
       val callExpression = argument.parentOfType<KtCallElement>() ?: return false
-      val callee = callExpression.calleeExpression?.mainReference?.resolve() as? KtNamedFunction ?: return false
+      val callee =
+        callExpression.calleeExpression?.mainReference?.resolve() as? KtNamedFunction
+          ?: return false
 
       val argumentTypeFqName = argument.matchingParamTypeFqName(callee)
 
@@ -378,21 +488,23 @@
    * Returns true for Modifier.align().%this%, myModifier.%this%, Modifier.%this%.
    */
   private fun PsiElement.isMethodCalledOnModifier(): Boolean {
-    val elementOnWhichMethodCalled: KtExpression = (parent as? KtNameReferenceExpression)?.getReceiverExpression() ?: return false
+    val elementOnWhichMethodCalled: KtExpression =
+      (parent as? KtNameReferenceExpression)?.getReceiverExpression() ?: return false
     // Case Modifier.align().%this%, modifier.%this%
-    val fqName = elementOnWhichMethodCalled.callReturnTypeFqName() ?:
-                 // Case Modifier.%this%
-                 ((elementOnWhichMethodCalled as? KtNameReferenceExpression)?.resolve() as? KtClass)?.fqName
+    val fqName =
+      elementOnWhichMethodCalled.callReturnTypeFqName()
+        ?:
+        // Case Modifier.%this%
+        ((elementOnWhichMethodCalled as? KtNameReferenceExpression)?.resolve() as? KtClass)?.fqName
     return fqName?.asString() == COMPOSE_MODIFIER_FQN
   }
 
   /**
-   * Inserts "Modifier." before [delegate] and imports [ComposeModifierCompletionContributor.modifierFqName] if it's not imported.
+   * Inserts "Modifier." before [delegate] and imports
+   * [ComposeModifierCompletionContributor.modifierFqName] if it's not imported.
    */
-  private class ModifierLookupElement(
-    delegate: LookupElement,
-    val insertModifier: Boolean
-  ) : LookupElementDecorator<LookupElement>(delegate) {
+  private class ModifierLookupElement(delegate: LookupElement, val insertModifier: Boolean) :
+    LookupElementDecorator<LookupElement>(delegate) {
     companion object {
       private const val callOnModifierObject = "Modifier."
     }
@@ -420,10 +532,14 @@
 
     override fun handleInsert(context: InsertionContext) {
       val psiDocumentManager = PsiDocumentManager.getInstance(context.project)
-      // Compose plugin inserts Modifier if completion character is '\n', doesn't happened with '\t'. Looks like a bug.
+      // Compose plugin inserts Modifier if completion character is '\n', doesn't happened with
+      // '\t'. Looks like a bug.
       if (insertModifier && context.completionChar != '\n') {
         context.document.insertString(context.startOffset, callOnModifierObject)
-        context.offsetMap.addOffset(CompletionInitializationContext.START_OFFSET, context.startOffset + callOnModifierObject.length)
+        context.offsetMap.addOffset(
+          CompletionInitializationContext.START_OFFSET,
+          context.startOffset + callOnModifierObject.length
+        )
         psiDocumentManager.commitAllDocuments()
         psiDocumentManager.doPostponedOperationsAndUnblockDocument(context.document)
       }
@@ -431,8 +547,11 @@
       if (isK2Plugin()) {
         ktFile.addImport(FqName(COMPOSE_MODIFIER_FQN))
       } else {
-        val modifierDescriptor = ktFile.resolveImportReference(FqName(COMPOSE_MODIFIER_FQN)).singleOrNull()
-        modifierDescriptor?.let { ImportInsertHelper.getInstance(context.project).importDescriptor(ktFile, it) }
+        val modifierDescriptor =
+          ktFile.resolveImportReference(FqName(COMPOSE_MODIFIER_FQN)).singleOrNull()
+        modifierDescriptor?.let {
+          ImportInsertHelper.getInstance(context.project).importDescriptor(ktFile, it)
+        }
       }
       psiDocumentManager.commitAllDocuments()
       psiDocumentManager.doPostponedOperationsAndUnblockDocument(context.document)
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposePositioningCompletionContributor.kt b/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposePositioningCompletionContributor.kt
index 785c970..1bbd81b 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposePositioningCompletionContributor.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/completion/ComposePositioningCompletionContributor.kt
@@ -58,20 +58,26 @@
 import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
 
 /**
- * Represents a class in the Compose library containing Alignment or Arrangement properties which might be suggested as completions.
+ * Represents a class in the Compose library containing Alignment or Arrangement properties which
+ * might be suggested as completions.
  */
 private data class ClassWithDeclarationsToSuggest(
   /** Package on which this class resides. */
   private val packageName: String,
-  /** Short(er) name of the class containing properties that can be suggested. This may contain multiple dot-separated pieces, and is
-   * intended to be concatenated with [packageName] to get the interface's fully-qualified name.
+  /**
+   * Short(er) name of the class containing properties that can be suggested. This may contain
+   * multiple dot-separated pieces, and is intended to be concatenated with [packageName] to get the
+   * interface's fully-qualified name.
    */
   private val classShortName: String,
-  /** Short name of the class to be imported when a suggestion is made. This differs from [classShortName] in the case of Companions. */
+  /**
+   * Short name of the class to be imported when a suggestion is made. This differs from
+   * [classShortName] in the case of Companions.
+   */
   private val classShortNameToImport: String = classShortName,
   /**
-   * Prefix applied to the property when completing. This is most often the same as [classShortName], but may contain nested classes (e.g.
-   * "Arrangement.Absolute").
+   * Prefix applied to the property when completing. This is most often the same as
+   * [classShortName], but may contain nested classes (e.g. "Arrangement.Absolute").
    */
   private val propertyCompletionPrefix: String = classShortName,
 ) {
@@ -82,13 +88,18 @@
   /**
    * Returns [LookupElement]s for the given [PsiElement].
    *
-   * @param typeToSuggest Fully-qualified name of the type required for suggested properties.
-   * @typeText Display text of the type to be used when rendering the [LookupElement]/
+   * @param typeToSuggest Fully-qualified name of the type required for suggested
+   *   properties. @typeText Display text of the type to be used when rendering the [LookupElement]/
    */
-  fun getLookupElements(elementToComplete: PsiElement, typeToSuggest: String, typeText: String): List<LookupElement> {
+  fun getLookupElements(
+    elementToComplete: PsiElement,
+    typeToSuggest: String,
+    typeText: String
+  ): List<LookupElement> {
     val project = elementToComplete.project
 
-    // It's necessary to ensure these are distinct, because in some circumstances there may be multiple versions of the class returned when
+    // It's necessary to ensure these are distinct, because in some circumstances there may be
+    // multiple versions of the class returned when
     // searching with 'allScope'.
     return KotlinFullClassNameIndex.get(classFqName, project, project.allScope())
       .flatMap { it.getPropertiesByType(project)[typeToSuggest] ?: emptyList() }
@@ -96,44 +107,59 @@
       .mapNotNull { createLookupElement(it, elementToComplete, typeText) }
   }
 
-  private fun createLookupElement(elementToSuggest: KtDeclaration, elementToComplete: PsiElement, typeText: String): LookupElement? {
+  private fun createLookupElement(
+    elementToSuggest: KtDeclaration,
+    elementToComplete: PsiElement,
+    typeText: String
+  ): LookupElement? {
     val lookupStringWithClass = "${propertyCompletionPrefix}.${elementToSuggest.name}"
     val presentableTailText = " ($packageName)"
 
-    // If the user's already typed part of a dot expression, then not all the given suggestions from this class will be applicable.
-    // For example, if the user has typed "Arrangement.Absolute.L", we want to exclude "Arrangement.Left".
+    // If the user's already typed part of a dot expression, then not all the given suggestions from
+    // this class will be applicable.
+    // For example, if the user has typed "Arrangement.Absolute.L", we want to exclude
+    // "Arrangement.Left".
     val alreadyCompletedPrefix =
-      elementToComplete.parentOfType<KtDotQualifiedExpression>()?.receiverExpression?.normalizedExpressionText()?.let { "$it." } ?: ""
+      elementToComplete
+        .parentOfType<KtDotQualifiedExpression>()
+        ?.receiverExpression
+        ?.normalizedExpressionText()
+        ?.let { "$it." }
+        ?: ""
 
     if (!lookupStringWithClass.startsWith(alreadyCompletedPrefix)) return null
 
-    // When completing one of these properties with a dot expression, we want the lookup string to exclude any full piece that's already
-    // been typed. For example, if the suggestion is "Arrangement.Absolute.Left" and the user has types "Arrangement.Ab", we want the
+    // When completing one of these properties with a dot expression, we want the lookup string to
+    // exclude any full piece that's already
+    // been typed. For example, if the suggestion is "Arrangement.Absolute.Left" and the user has
+    // types "Arrangement.Ab", we want the
     // resulting lookup string to be "Absolute.Left".
     val mainLookupString = lookupStringWithClass.removePrefix(alreadyCompletedPrefix)
 
-    val builder = LookupElementBuilder
-      .create(elementToSuggest, mainLookupString)
-      .bold()
-      .withTailText(presentableTailText, true)
-      .withTypeText(typeText)
-      .withInsertHandler lambda@{ context, _ ->
-        // Add import in addition to filling in the completion.
-        val psiDocumentManager = PsiDocumentManager.getInstance(context.project)
-        val ktFile = context.file as KtFile
-        if (isK2Plugin()) {
-          ktFile.addImport(FqName(classToImport))
-          psiDocumentManager.commitAllDocuments()
-          psiDocumentManager.doPostponedOperationsAndUnblockDocument(context.document)
-        } else {
-          val modifierDescriptor = ktFile.resolveImportReference(FqName(classToImport)).singleOrNull()
-          if (modifierDescriptor != null) {
-            ImportInsertHelper.getInstance(context.project).importDescriptor(ktFile, modifierDescriptor)
+    val builder =
+      LookupElementBuilder.create(elementToSuggest, mainLookupString)
+        .bold()
+        .withTailText(presentableTailText, true)
+        .withTypeText(typeText)
+        .withInsertHandler lambda@{ context, _ ->
+          // Add import in addition to filling in the completion.
+          val psiDocumentManager = PsiDocumentManager.getInstance(context.project)
+          val ktFile = context.file as KtFile
+          if (isK2Plugin()) {
+            ktFile.addImport(FqName(classToImport))
             psiDocumentManager.commitAllDocuments()
             psiDocumentManager.doPostponedOperationsAndUnblockDocument(context.document)
+          } else {
+            val modifierDescriptor =
+              ktFile.resolveImportReference(FqName(classToImport)).singleOrNull()
+            if (modifierDescriptor != null) {
+              ImportInsertHelper.getInstance(context.project)
+                .importDescriptor(ktFile, modifierDescriptor)
+              psiDocumentManager.commitAllDocuments()
+              psiDocumentManager.doPostponedOperationsAndUnblockDocument(context.document)
+            }
           }
         }
-      }
 
     return object : LookupElementDecorator<LookupElement>(builder) {
       override fun renderElement(presentation: LookupElementPresentation) {
@@ -144,25 +170,32 @@
   }
 
   companion object {
-    /** Gets a list of this class's properties grouped by their fully-qualified type name. This result is cached for fast retrieval. */
-    private fun KtClassOrObject.getPropertiesByType(project: Project): Map<String, List<KtProperty>> {
+    /**
+     * Gets a list of this class's properties grouped by their fully-qualified type name. This
+     * result is cached for fast retrieval.
+     */
+    private fun KtClassOrObject.getPropertiesByType(
+      project: Project
+    ): Map<String, List<KtProperty>> {
       return CachedValuesManager.getManager(project).getCachedValue(this) {
-        val result = declarations
-          .filterIsInstance<KtProperty>()
-          .mapNotNull { property ->
-            property.returnTypeFqName()?.asString()?.let { Pair(it, property) }
-          }
-          .groupBy({ it.first }, { it.second })
+        val result =
+          declarations
+            .filterIsInstance<KtProperty>()
+            .mapNotNull { property ->
+              property.returnTypeFqName()?.asString()?.let { Pair(it, property) }
+            }
+            .groupBy({ it.first }, { it.second })
         CachedValueProvider.Result.create(result, this)
       }
     }
 
     /**
-     * Given a dot-qualified expression, returns a normalized form of the name. This removes inconsistencies that may be introduced by
-     * whitespace within the name; so the expression "com . foo   .bar" will be reduced to "com.foo.bar".
+     * Given a dot-qualified expression, returns a normalized form of the name. This removes
+     * inconsistencies that may be introduced by whitespace within the name; so the expression "com
+     * . foo .bar" will be reduced to "com.foo.bar".
      */
     private fun KtExpression.normalizedExpressionText(): String? {
-      return when(this) {
+      return when (this) {
         is KtDotQualifiedExpression -> {
           val leftSide = receiverExpression.normalizedExpressionText() ?: return null
           val rightSide = selectorExpression?.normalizedExpressionText() ?: return null
@@ -180,38 +213,49 @@
   /** Package on which this interface resides. */
   private val packageName: String,
   /**
-   * Short(er) name of the interface. This may contain multiple dot-separated pieces, and is intended to be concatenated with [packageName]
-   * to get the interface's fully-qualified name.
+   * Short(er) name of the interface. This may contain multiple dot-separated pieces, and is
+   * intended to be concatenated with [packageName] to get the interface's fully-qualified name.
    */
   private val interfaceName: String,
-  /** A list of classes on which to search for properties implementing this interface, which can be used for suggestions. */
+  /**
+   * A list of classes on which to search for properties implementing this interface, which can be
+   * used for suggestions.
+   */
   private val suggestedCompletionPropertyClasses: List<ClassWithDeclarationsToSuggest>,
-  /** An additional type that is allowed for suggestions in addition to [interfaceName]. The type must reside on the same [packageName]. */
+  /**
+   * An additional type that is allowed for suggestions in addition to [interfaceName]. The type
+   * must reside on the same [packageName].
+   */
   private val additionalTypeToSuggest: String? = null,
   /**
-   * Collection of weights to be used when ranking suggestions. The key is a short type name residing on [packageName], corresponding to one
-   * of the positioning interfaces being handled. The value is a simple priority: larger values result in a higher position in the
-   * completion list. This value is added to any weight in [weightsByParentClass].
+   * Collection of weights to be used when ranking suggestions. The key is a short type name
+   * residing on [packageName], corresponding to one of the positioning interfaces being handled.
+   * The value is a simple priority: larger values result in a higher position in the completion
+   * list. This value is added to any weight in [weightsByParentClass].
    */
   private val weightsByType: Map<String, Int>,
   /**
-   * Collection of weights to be used when ranking suggestions. The key is a short type name residing on [packageName], corresponding to the
-   * class on which a suggested property is defined. The value is a simple priority: larger values result in a higher position in the
-   * completion list. This value is added to any weight in [weightsByType].
+   * Collection of weights to be used when ranking suggestions. The key is a short type name
+   * residing on [packageName], corresponding to the class on which a suggested property is defined.
+   * The value is a simple priority: larger values result in a higher position in the completion
+   * list. This value is added to any weight in [weightsByType].
    */
   private val weightsByParentClass: Map<String, Int>,
 ) {
 
   val interfaceFqName = "$packageName.$interfaceName"
 
-  private val weightsByFullyQualifiedType = weightsByType.mapKeys { (key, _) -> "$packageName.$key" }
-  private val weightsByFullyQualifiedParentClass = weightsByParentClass.mapKeys { (key, _) -> "$packageName.$key" }
+  private val weightsByFullyQualifiedType =
+    weightsByType.mapKeys { (key, _) -> "$packageName.$key" }
+  private val weightsByFullyQualifiedParentClass =
+    weightsByParentClass.mapKeys { (key, _) -> "$packageName.$key" }
 
   /**
    * A list of types that are allowed for suggestions.
    *
-   * The first [String] in this [Pair] represents the fully-qualified name of the type. The second [String] in this [Pair] represents a
-   * shorter version of the type that can be displayed on the right side of the auto-completion dialog.
+   * The first [String] in this [Pair] represents the fully-qualified name of the type. The second
+   * [String] in this [Pair] represents a shorter version of the type that can be displayed on the
+   * right side of the auto-completion dialog.
    */
   private val typesToSuggest: List<Pair<String, String>> = buildList {
     add("$packageName.$interfaceName" to interfaceName)
@@ -234,8 +278,10 @@
     val lookupElementTypeName = (psiElement as? KtDeclaration)?.returnTypeFqName()?.asString()
     val typeWeight = lookupElementTypeName?.let { weightsByFullyQualifiedType[it] } ?: 0
 
-    val lookupElementParentClassName = (psiElement as? KtDeclaration)?.containingClassOrObject?.fqName?.asString()
-    val containingClassWeight = lookupElementParentClassName?.let { weightsByFullyQualifiedParentClass[it] } ?: 0
+    val lookupElementParentClassName =
+      (psiElement as? KtDeclaration)?.containingClassOrObject?.fqName?.asString()
+    val containingClassWeight =
+      lookupElementParentClassName?.let { weightsByFullyQualifiedParentClass[it] } ?: 0
     return typeWeight + containingClassWeight
   }
 
@@ -243,8 +289,10 @@
 
     /** Returns an applicable [PositioningInterface] for the given [PsiElement] if one exists. */
     fun forCompletionElement(psiElement: PsiElement): PositioningInterface? {
-      // Arrangement and Alignment completions are handled when completing arguments and properties only.
-      val elementToCompleteTypeFqName = psiElement.argumentTypeFqName ?: psiElement.propertyTypeFqName ?: return null
+      // Arrangement and Alignment completions are handled when completing arguments and properties
+      // only.
+      val elementToCompleteTypeFqName =
+        psiElement.argumentTypeFqName ?: psiElement.propertyTypeFqName ?: return null
       return VALUES[elementToCompleteTypeFqName]
     }
 
@@ -256,10 +304,13 @@
 
     private val PsiElement.argumentTypeFqName: String?
       get() {
-        val argument = contextOfType<KtValueArgument>().takeIf { it !is KtLambdaArgument } ?: return null
+        val argument =
+          contextOfType<KtValueArgument>().takeIf { it !is KtLambdaArgument } ?: return null
 
         val callExpression = argument.parentOfType<KtCallElement>() ?: return null
-        val callee = callExpression.calleeExpression?.mainReference?.resolve() as? KtNamedFunction ?: return null
+        val callee =
+          callExpression.calleeExpression?.mainReference?.resolve() as? KtNamedFunction
+            ?: return null
 
         val argumentTypeFqName = argument.matchingParamTypeFqName(callee)
 
@@ -269,144 +320,169 @@
     private const val ALIGNMENT_PACKAGE = "androidx.compose.ui"
     private const val ARRANGEMENT_PACKAGE = "androidx.compose.foundation.layout"
 
-    private val ALIGNMENT_CLASSES_FOR_SUGGESTIONS = listOf(
-      ClassWithDeclarationsToSuggest(
-        packageName = ALIGNMENT_PACKAGE,
-        classShortName = "Alignment.Companion",
-        classShortNameToImport = "Alignment",
-        propertyCompletionPrefix = "Alignment",
-      ),
-      ClassWithDeclarationsToSuggest(
-        packageName = ALIGNMENT_PACKAGE,
-        classShortName = "AbsoluteAlignment",
-      ),
-    )
+    private val ALIGNMENT_CLASSES_FOR_SUGGESTIONS =
+      listOf(
+        ClassWithDeclarationsToSuggest(
+          packageName = ALIGNMENT_PACKAGE,
+          classShortName = "Alignment.Companion",
+          classShortNameToImport = "Alignment",
+          propertyCompletionPrefix = "Alignment",
+        ),
+        ClassWithDeclarationsToSuggest(
+          packageName = ALIGNMENT_PACKAGE,
+          classShortName = "AbsoluteAlignment",
+        ),
+      )
 
-    private val ARRANGEMENT_CLASSES_FOR_SUGGESTIONS = listOf(
-      ClassWithDeclarationsToSuggest(
-        packageName = ARRANGEMENT_PACKAGE,
-        classShortName = "Arrangement",
-      ),
-      ClassWithDeclarationsToSuggest(
-        packageName = ARRANGEMENT_PACKAGE,
-        classShortName = "Arrangement.Absolute",
-        classShortNameToImport = "Arrangement",
-      ),
-    )
+    private val ARRANGEMENT_CLASSES_FOR_SUGGESTIONS =
+      listOf(
+        ClassWithDeclarationsToSuggest(
+          packageName = ARRANGEMENT_PACKAGE,
+          classShortName = "Arrangement",
+        ),
+        ClassWithDeclarationsToSuggest(
+          packageName = ARRANGEMENT_PACKAGE,
+          classShortName = "Arrangement.Absolute",
+          classShortNameToImport = "Arrangement",
+        ),
+      )
 
-    private val VALUES = listOf(
-      PositioningInterface(
-        packageName = ALIGNMENT_PACKAGE,
-        interfaceName = "Alignment",
-        ALIGNMENT_CLASSES_FOR_SUGGESTIONS,
-        weightsByType = mapOf(
-          "Alignment" to 10,
-          "Alignment.Horizontal" to -10,
-          "Alignment.Vertical" to -10,
-        ),
-        weightsByParentClass = mapOf(
-          "Alignment.Companion" to 2,
-          "Alignment" to 2,
-          "AbsoluteAlignment" to 1,
-        ),
-      ),
-      PositioningInterface(
-        packageName = ALIGNMENT_PACKAGE,
-        interfaceName = "Alignment.Horizontal",
-        ALIGNMENT_CLASSES_FOR_SUGGESTIONS,
-        weightsByType = mapOf(
-          "Alignment.Horizontal" to 10,
-          "Alignment" to -10,
-          "Alignment.Vertical" to -10,
-        ),
-        weightsByParentClass = mapOf(
-          "Alignment.Companion" to 2,
-          "Alignment" to 2,
-          "AbsoluteAlignment" to 1,
-        ),
-      ),
-      PositioningInterface(
-        packageName = ALIGNMENT_PACKAGE,
-        interfaceName = "Alignment.Vertical",
-        ALIGNMENT_CLASSES_FOR_SUGGESTIONS,
-        weightsByType = mapOf(
-          "Alignment.Vertical" to 10,
-          "Alignment" to -10,
-          "Alignment.Horizontal" to -10,
-        ),
-        weightsByParentClass = mapOf(
-          "Alignment.Companion" to 2,
-          "Alignment" to 2,
-          "AbsoluteAlignment" to 1,
-        ),
-      ),
-
-      PositioningInterface(
-        packageName = ARRANGEMENT_PACKAGE,
-        interfaceName = "Arrangement.Horizontal",
-        ARRANGEMENT_CLASSES_FOR_SUGGESTIONS,
-        additionalTypeToSuggest = "Arrangement.HorizontalOrVertical",
-        weightsByType = mapOf(
-          "Arrangement.Horizontal" to 10,
-          "Arrangement.HorizontalOrVertical" to 10,
-          "Arrangement.Vertical" to -10,
-        ),
-        weightsByParentClass = mapOf(
-          "Arrangement" to 2,
-          "Arrangement.Absolute" to 1,
-        ),
-      ),
-      PositioningInterface(
-        packageName = ARRANGEMENT_PACKAGE,
-        interfaceName = "Arrangement.Vertical",
-        ARRANGEMENT_CLASSES_FOR_SUGGESTIONS,
-        additionalTypeToSuggest = "Arrangement.HorizontalOrVertical",
-        weightsByType = mapOf(
-          "Arrangement.Vertical" to 10,
-          "Arrangement.HorizontalOrVertical" to 10,
-          "Arrangement.Horizontal" to -10,
-        ),
-        weightsByParentClass = mapOf(
-          "Arrangement" to 2,
-          "Arrangement.Absolute" to 1,
-        ),
-      ),
-      PositioningInterface(
-        packageName = ARRANGEMENT_PACKAGE,
-        interfaceName = "Arrangement.HorizontalOrVertical",
-        ARRANGEMENT_CLASSES_FOR_SUGGESTIONS,
-        weightsByType = mapOf(
-          "Arrangement.HorizontalOrVertical" to 10,
-          "Arrangement.Vertical" to -10,
-          "Arrangement.Horizontal" to -10,
-        ),
-        weightsByParentClass = mapOf(
-          "Arrangement" to 2,
-          "Arrangement.Absolute" to 1,
-        ),
-      ),
-    ).associateBy { it.interfaceFqName }
+    private val VALUES =
+      listOf(
+          PositioningInterface(
+            packageName = ALIGNMENT_PACKAGE,
+            interfaceName = "Alignment",
+            ALIGNMENT_CLASSES_FOR_SUGGESTIONS,
+            weightsByType =
+              mapOf(
+                "Alignment" to 10,
+                "Alignment.Horizontal" to -10,
+                "Alignment.Vertical" to -10,
+              ),
+            weightsByParentClass =
+              mapOf(
+                "Alignment.Companion" to 2,
+                "Alignment" to 2,
+                "AbsoluteAlignment" to 1,
+              ),
+          ),
+          PositioningInterface(
+            packageName = ALIGNMENT_PACKAGE,
+            interfaceName = "Alignment.Horizontal",
+            ALIGNMENT_CLASSES_FOR_SUGGESTIONS,
+            weightsByType =
+              mapOf(
+                "Alignment.Horizontal" to 10,
+                "Alignment" to -10,
+                "Alignment.Vertical" to -10,
+              ),
+            weightsByParentClass =
+              mapOf(
+                "Alignment.Companion" to 2,
+                "Alignment" to 2,
+                "AbsoluteAlignment" to 1,
+              ),
+          ),
+          PositioningInterface(
+            packageName = ALIGNMENT_PACKAGE,
+            interfaceName = "Alignment.Vertical",
+            ALIGNMENT_CLASSES_FOR_SUGGESTIONS,
+            weightsByType =
+              mapOf(
+                "Alignment.Vertical" to 10,
+                "Alignment" to -10,
+                "Alignment.Horizontal" to -10,
+              ),
+            weightsByParentClass =
+              mapOf(
+                "Alignment.Companion" to 2,
+                "Alignment" to 2,
+                "AbsoluteAlignment" to 1,
+              ),
+          ),
+          PositioningInterface(
+            packageName = ARRANGEMENT_PACKAGE,
+            interfaceName = "Arrangement.Horizontal",
+            ARRANGEMENT_CLASSES_FOR_SUGGESTIONS,
+            additionalTypeToSuggest = "Arrangement.HorizontalOrVertical",
+            weightsByType =
+              mapOf(
+                "Arrangement.Horizontal" to 10,
+                "Arrangement.HorizontalOrVertical" to 10,
+                "Arrangement.Vertical" to -10,
+              ),
+            weightsByParentClass =
+              mapOf(
+                "Arrangement" to 2,
+                "Arrangement.Absolute" to 1,
+              ),
+          ),
+          PositioningInterface(
+            packageName = ARRANGEMENT_PACKAGE,
+            interfaceName = "Arrangement.Vertical",
+            ARRANGEMENT_CLASSES_FOR_SUGGESTIONS,
+            additionalTypeToSuggest = "Arrangement.HorizontalOrVertical",
+            weightsByType =
+              mapOf(
+                "Arrangement.Vertical" to 10,
+                "Arrangement.HorizontalOrVertical" to 10,
+                "Arrangement.Horizontal" to -10,
+              ),
+            weightsByParentClass =
+              mapOf(
+                "Arrangement" to 2,
+                "Arrangement.Absolute" to 1,
+              ),
+          ),
+          PositioningInterface(
+            packageName = ARRANGEMENT_PACKAGE,
+            interfaceName = "Arrangement.HorizontalOrVertical",
+            ARRANGEMENT_CLASSES_FOR_SUGGESTIONS,
+            weightsByType =
+              mapOf(
+                "Arrangement.HorizontalOrVertical" to 10,
+                "Arrangement.Vertical" to -10,
+                "Arrangement.Horizontal" to -10,
+              ),
+            weightsByParentClass =
+              mapOf(
+                "Arrangement" to 2,
+                "Arrangement.Absolute" to 1,
+              ),
+          ),
+        )
+        .associateBy { it.interfaceFqName }
   }
 }
 
 /**
- * Suggests completion for the Alignment and Arrangement interfaces. Both interfaces have Horizontal and Vertical variants which the default
- * auto-completion intermixes, even though only one subset is generally applicable in any given completion.
+ * Suggests completion for the Alignment and Arrangement interfaces. Both interfaces have Horizontal
+ * and Vertical variants which the default auto-completion intermixes, even though only one subset
+ * is generally applicable in any given completion.
  */
 class ComposePositioningCompletionContributor : CompletionContributor() {
-  override fun fillCompletionVariants(parameters: CompletionParameters, result: CompletionResultSet) {
+  override fun fillCompletionVariants(
+    parameters: CompletionParameters,
+    result: CompletionResultSet
+  ) {
     val elementToComplete = parameters.position
 
     if (!isComposeEnabled(elementToComplete) || parameters.originalFile !is KtFile) return
 
     // Add any suggested elements needed for this element.
-    val lookupElements = PositioningInterface.forCompletionElement(elementToComplete)?.getSuggestedCompletions(elementToComplete) ?: return
+    val lookupElements =
+      PositioningInterface.forCompletionElement(elementToComplete)
+        ?.getSuggestedCompletions(elementToComplete)
+        ?: return
     result.addAllElements(lookupElements)
 
-    // Run the remaining contributors, removing any duplicates of the items that have already been suggested.
+    // Run the remaining contributors, removing any duplicates of the items that have already been
+    // suggested.
     val addedElements = lookupElements.mapNotNull { it.psiElement?.kotlinFqName }.toSet()
     result.runRemainingContributors(parameters) { completionResult ->
-      val alreadyAddedElement = completionResult.lookupElement.psiElement?.kotlinFqName?.let { addedElements.contains(it) } ?: false
+      val alreadyAddedElement =
+        completionResult.lookupElement.psiElement?.kotlinFqName?.let { addedElements.contains(it) }
+          ?: false
       if (!alreadyAddedElement) {
         result.passResult(completionResult)
       }
@@ -420,12 +496,15 @@
     val parameters = location.completionParameters
     val elementToComplete = parameters.position
     if (!isComposeEnabled(elementToComplete) || parameters.originalFile !is KtFile) {
-      // Return null when this isn't a completion we care about to avoid any further comparisons or object allocations.
+      // Return null when this isn't a completion we care about to avoid any further comparisons or
+      // object allocations.
       return null
     }
 
-    // Since this is a completion involving one of the types handled here, we want to rank everything. If it's not an element being
+    // Since this is a completion involving one of the types handled here, we want to rank
+    // everything. If it's not an element being
     // adjusted, then the weight of '0' will effectively let the item pass through unmodified.
-    return PositioningInterface.forCompletionElement(elementToComplete)?.getWeight(lookupElement) ?: 0
+    return PositioningInterface.forCompletionElement(elementToComplete)?.getWeight(lookupElement)
+      ?: 0
   }
 }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/Constants.kt b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/Constants.kt
index c44a15f..dfa03f9 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/Constants.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/Constants.kt
@@ -16,30 +16,22 @@
 package com.android.tools.compose.code.completion.constraintlayout
 
 internal object KeyWords {
-  /**
-   * Name of the property within a MotionScene that contains several ConstraintSet declarations.
-   */
+  /** Name of the property within a MotionScene that contains several ConstraintSet declarations. */
   const val ConstraintSets = "ConstraintSets"
 
-  /**
-   * Name of the property within a MotionScene that contains several Transition declarations.
-   */
+  /** Name of the property within a MotionScene that contains several Transition declarations. */
   const val Transitions = "Transitions"
 
   /**
-   * Name of the property used to indicate that the containing ConstraintSet inherits its constraints from the ConstraintSet given by the
-   * `Extends` property value.
+   * Name of the property used to indicate that the containing ConstraintSet inherits its
+   * constraints from the ConstraintSet given by the `Extends` property value.
    */
   const val Extends = "Extends"
 
-  /**
-   * Reserved ID for the containing layout. Typically referenced in constraint blocks.
-   */
+  /** Reserved ID for the containing layout. Typically referenced in constraint blocks. */
   const val ParentId = "parent"
 
-  /**
-   * Name of the Visibility property in a constraint block.
-   */
+  /** Name of the Visibility property in a constraint block. */
   const val Visibility = "visibility"
 
   /**
@@ -61,10 +53,8 @@
   val keyWord: String
 }
 
-//region Constrain KeyWords
-/**
- * The classic anchors used to constrain a widget.
- */
+// region Constrain KeyWords
+/** The classic anchors used to constrain a widget. */
 internal enum class StandardAnchor(override val keyWord: String) : ConstraintLayoutKeyWord {
   Start("start"),
   Left("left"),
@@ -96,17 +86,13 @@
   CenterV("centerVertically")
 }
 
-/**
- * Supported keywords to define the dimension of a widget.
- */
+/** Supported keywords to define the dimension of a widget. */
 internal enum class Dimension(override val keyWord: String) : ConstraintLayoutKeyWord {
   Width("width"),
   Height("height")
 }
 
-/**
- * Keywords to apply rendering time transformations to a widget.
- */
+/** Keywords to apply rendering time transformations to a widget. */
 internal enum class RenderTransform(override val keyWord: String) : ConstraintLayoutKeyWord {
   Alpha("alpha"),
   ScaleX("scaleX"),
@@ -118,7 +104,7 @@
   TranslationY("translationY"),
   TranslationZ("translationZ"),
 }
-//endregion
+// endregion
 
 internal enum class DimBehavior(override val keyWord: String) : ConstraintLayoutKeyWord {
   Spread("spread"),
@@ -127,19 +113,19 @@
   MatchParent("parent")
 }
 
-internal enum class VisibilityMode(override val keyWord: String): ConstraintLayoutKeyWord {
+internal enum class VisibilityMode(override val keyWord: String) : ConstraintLayoutKeyWord {
   Visible("visible"),
   Invisible("invisible"),
   Gone("gone")
 }
 
-internal enum class ClearOption(override val keyWord: String): ConstraintLayoutKeyWord {
+internal enum class ClearOption(override val keyWord: String) : ConstraintLayoutKeyWord {
   Constraints("constraints"),
   Dimensions("dimensions"),
   Transforms("transforms")
 }
 
-internal enum class TransitionField(override val keyWord: String): ConstraintLayoutKeyWord {
+internal enum class TransitionField(override val keyWord: String) : ConstraintLayoutKeyWord {
   From("from"),
   To("to"),
   PathArc("pathMotionArc"),
@@ -147,14 +133,14 @@
   OnSwipe("onSwipe")
 }
 
-internal enum class OnSwipeField(override val keyWord: String): ConstraintLayoutKeyWord {
+internal enum class OnSwipeField(override val keyWord: String) : ConstraintLayoutKeyWord {
   AnchorId("anchor"),
   Direction("direction"),
   Side("side"),
   Mode("mode")
 }
 
-internal enum class OnSwipeSide(override val keyWord: String): ConstraintLayoutKeyWord {
+internal enum class OnSwipeSide(override val keyWord: String) : ConstraintLayoutKeyWord {
   Top("top"),
   Left("left"),
   Right("right"),
@@ -164,7 +150,7 @@
   End("end")
 }
 
-internal enum class OnSwipeDirection(override val keyWord: String): ConstraintLayoutKeyWord {
+internal enum class OnSwipeDirection(override val keyWord: String) : ConstraintLayoutKeyWord {
   Up("up"),
   Down("down"),
   Left("left"),
@@ -175,28 +161,27 @@
   AntiClockwise("anticlockwise")
 }
 
-internal enum class OnSwipeMode(override val keyWord: String): ConstraintLayoutKeyWord {
+internal enum class OnSwipeMode(override val keyWord: String) : ConstraintLayoutKeyWord {
   Velocity("velocity"),
   Spring("spring")
 }
 
-internal enum class KeyFrameField(override val keyWord: String): ConstraintLayoutKeyWord {
+internal enum class KeyFrameField(override val keyWord: String) : ConstraintLayoutKeyWord {
   Positions("KeyPositions"),
   Attributes("KeyAttributes"),
   Cycles("KeyCycles")
 }
 
-/**
- * Common fields used by any of [KeyFrameField].
- */
-internal enum class KeyFrameChildCommonField(override val keyWord: String): ConstraintLayoutKeyWord {
+/** Common fields used by any of [KeyFrameField]. */
+internal enum class KeyFrameChildCommonField(override val keyWord: String) :
+  ConstraintLayoutKeyWord {
   TargetId("target"),
   Frames("frames"),
   Easing("transitionEasing"),
   Fit("curveFit"),
 }
 
-internal enum class KeyPositionField(override val keyWord: String): ConstraintLayoutKeyWord {
+internal enum class KeyPositionField(override val keyWord: String) : ConstraintLayoutKeyWord {
   PercentX("percentX"),
   PercentY("percentY"),
   PercentWidth("percentWidth"),
@@ -205,8 +190,8 @@
   Type("type")
 }
 
-internal enum class KeyCycleField(override val keyWord: String): ConstraintLayoutKeyWord {
+internal enum class KeyCycleField(override val keyWord: String) : ConstraintLayoutKeyWord {
   Period("period"),
   Offset("offset"),
   Phase("phase")
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/ConstraintLayoutJsonCompletionContributor.kt b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/ConstraintLayoutJsonCompletionContributor.kt
index 0348aa8..c7bf2d6 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/ConstraintLayoutJsonCompletionContributor.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/ConstraintLayoutJsonCompletionContributor.kt
@@ -36,31 +36,55 @@
 
 internal const val BASE_DEPTH_FOR_LITERAL_IN_PROPERTY = 2
 
-internal const val BASE_DEPTH_FOR_NAME_IN_PROPERTY_OBJECT = BASE_DEPTH_FOR_LITERAL_IN_PROPERTY + BASE_DEPTH_FOR_LITERAL_IN_PROPERTY
+internal const val BASE_DEPTH_FOR_NAME_IN_PROPERTY_OBJECT =
+  BASE_DEPTH_FOR_LITERAL_IN_PROPERTY + BASE_DEPTH_FOR_LITERAL_IN_PROPERTY
 
-/** Depth for a literal of a property of the list of ConstraintSets. With respect to the ConstraintSets root element. */
-private const val CONSTRAINT_SET_LIST_PROPERTY_DEPTH = BASE_DEPTH_FOR_LITERAL_IN_PROPERTY + BASE_DEPTH_FOR_LITERAL_IN_PROPERTY
+/**
+ * Depth for a literal of a property of the list of ConstraintSets. With respect to the
+ * ConstraintSets root element.
+ */
+private const val CONSTRAINT_SET_LIST_PROPERTY_DEPTH =
+  BASE_DEPTH_FOR_LITERAL_IN_PROPERTY + BASE_DEPTH_FOR_LITERAL_IN_PROPERTY
 
-/** Depth for a literal of a property of a ConstraintSet. With respect to the ConstraintSets root element. */
-private const val CONSTRAINT_SET_PROPERTY_DEPTH = CONSTRAINT_SET_LIST_PROPERTY_DEPTH + BASE_DEPTH_FOR_LITERAL_IN_PROPERTY
+/**
+ * Depth for a literal of a property of a ConstraintSet. With respect to the ConstraintSets root
+ * element.
+ */
+private const val CONSTRAINT_SET_PROPERTY_DEPTH =
+  CONSTRAINT_SET_LIST_PROPERTY_DEPTH + BASE_DEPTH_FOR_LITERAL_IN_PROPERTY
 
-/** Depth for a literal of a property of a Transition. With respect to the Transitions root element. */
+/**
+ * Depth for a literal of a property of a Transition. With respect to the Transitions root element.
+ */
 private const val TRANSITION_PROPERTY_DEPTH = CONSTRAINT_SET_PROPERTY_DEPTH
 
-/** Depth for a literal of a property of a Constraints block. With respect to the ConstraintSets root element. */
-internal const val CONSTRAINT_BLOCK_PROPERTY_DEPTH = CONSTRAINT_SET_PROPERTY_DEPTH + BASE_DEPTH_FOR_LITERAL_IN_PROPERTY
+/**
+ * Depth for a literal of a property of a Constraints block. With respect to the ConstraintSets root
+ * element.
+ */
+internal const val CONSTRAINT_BLOCK_PROPERTY_DEPTH =
+  CONSTRAINT_SET_PROPERTY_DEPTH + BASE_DEPTH_FOR_LITERAL_IN_PROPERTY
 
-/** Depth for a literal of a property of an OnSwipe block. With respect to the Transitions root element. */
-internal const val ONSWIPE_PROPERTY_DEPTH = TRANSITION_PROPERTY_DEPTH + BASE_DEPTH_FOR_LITERAL_IN_PROPERTY
+/**
+ * Depth for a literal of a property of an OnSwipe block. With respect to the Transitions root
+ * element.
+ */
+internal const val ONSWIPE_PROPERTY_DEPTH =
+  TRANSITION_PROPERTY_DEPTH + BASE_DEPTH_FOR_LITERAL_IN_PROPERTY
 
-/** Depth for a literal of a property of a KeyFrames block. With respect to the Transitions root element. */
+/**
+ * Depth for a literal of a property of a KeyFrames block. With respect to the Transitions root
+ * element.
+ */
 internal const val KEYFRAMES_PROPERTY_DEPTH = ONSWIPE_PROPERTY_DEPTH
 
 /**
- * [CompletionContributor] for the JSON5 format supported in ConstraintLayout-Compose (and MotionLayout).
+ * [CompletionContributor] for the JSON5 format supported in ConstraintLayout-Compose (and
+ * MotionLayout).
  *
- * See the official wiki in [GitHub](https://github.com/androidx/constraintlayout/wiki/ConstraintSet-JSON5-syntax) to learn more about the
- * supported JSON5 syntax.
+ * See the official wiki in
+ * [GitHub](https://github.com/androidx/constraintlayout/wiki/ConstraintSet-JSON5-syntax) to learn
+ * more about the supported JSON5 syntax.
  */
 class ConstraintLayoutJsonCompletionContributor : CompletionContributor() {
   init {
@@ -88,14 +112,18 @@
       CompletionType.BASIC,
       // Complete IDs on special anchors, they take a single string value
       jsonStringValue()
-        .withPropertyParentAtLevel(BASE_DEPTH_FOR_LITERAL_IN_PROPERTY, SpecialAnchor.values().map { it.keyWord }),
+        .withPropertyParentAtLevel(
+          BASE_DEPTH_FOR_LITERAL_IN_PROPERTY,
+          SpecialAnchor.values().map { it.keyWord }
+        ),
       ConstraintIdsProvider
     )
     extend(
       CompletionType.BASIC,
       // Complete IDs in the constraint array (first position)
       jsonStringValue()
-        // First element in the array, ie: there is no PsiElement preceding the desired one at this level
+        // First element in the array, ie: there is no PsiElement preceding the desired one at this
+        // level
         .withParent(psiElement<JsonStringLiteral>().atIndexOfJsonArray(0))
         .insideConstraintArray(),
       ConstraintIdsProvider
@@ -104,7 +132,8 @@
       CompletionType.BASIC,
       // Complete anchors in the constraint array (second position)
       jsonStringValue()
-        // Second element in the array, ie: there is one PsiElement preceding the desired one at this level
+        // Second element in the array, ie: there is one PsiElement preceding the desired one at
+        // this level
         .withParent(psiElement<JsonStringLiteral>().atIndexOfJsonArray(1))
         .insideConstraintArray(),
       AnchorablesProvider
@@ -112,15 +141,17 @@
     extend(
       CompletionType.BASIC,
       // Complete a clear option within the 'clear' array
-      jsonStringValue()
-        .insideClearArray(),
+      jsonStringValue().insideClearArray(),
       ClearOptionsProvider
     )
     extend(
       CompletionType.BASIC,
       // Complete non-numeric dimension values for width & height
       jsonStringValue()
-        .withPropertyParentAtLevel(BASE_DEPTH_FOR_LITERAL_IN_PROPERTY, Dimension.values().map { it.keyWord }),
+        .withPropertyParentAtLevel(
+          BASE_DEPTH_FOR_LITERAL_IN_PROPERTY,
+          Dimension.values().map { it.keyWord }
+        ),
       EnumValuesCompletionProvider(DimBehavior::class)
     )
     extend(
@@ -130,23 +161,26 @@
         .withPropertyParentAtLevel(BASE_DEPTH_FOR_LITERAL_IN_PROPERTY, KeyWords.Visibility),
       EnumValuesCompletionProvider(VisibilityMode::class)
     )
-    //endregion
+    // endregion
 
-    //region Transitions
+    // region Transitions
     extend(
       CompletionType.BASIC,
       // Complete fields of a Transition block
-      jsonPropertyName()
-        .withTransitionsParentAtLevel(TRANSITION_PROPERTY_DEPTH),
+      jsonPropertyName().withTransitionsParentAtLevel(TRANSITION_PROPERTY_DEPTH),
       TransitionFieldsProvider
     )
     extend(
       CompletionType.BASIC,
       // Complete existing ConstraintSet names for `from` and `to` Transition properties
       jsonStringValue()
-        .withPropertyParentAtLevel(BASE_DEPTH_FOR_LITERAL_IN_PROPERTY, listOf(TransitionField.From.keyWord, TransitionField.To.keyWord))
+        .withPropertyParentAtLevel(
+          BASE_DEPTH_FOR_LITERAL_IN_PROPERTY,
+          listOf(TransitionField.From.keyWord, TransitionField.To.keyWord)
+        )
         .withTransitionsParentAtLevel(TRANSITION_PROPERTY_DEPTH),
-      // TODO(b/207030860): Guarantee that provided names for 'from' or 'to' are distinct from each other,
+      // TODO(b/207030860): Guarantee that provided names for 'from' or 'to' are distinct from each
+      // other,
       //  ie: both shouldn't reference the same ConstraintSet
       ConstraintSetNamesProvider
     )
@@ -154,7 +188,10 @@
       CompletionType.BASIC,
       // Complete fields of a KeyFrames block
       jsonPropertyName()
-        .withPropertyParentAtLevel(BASE_DEPTH_FOR_NAME_IN_PROPERTY_OBJECT, TransitionField.KeyFrames.keyWord)
+        .withPropertyParentAtLevel(
+          BASE_DEPTH_FOR_NAME_IN_PROPERTY_OBJECT,
+          TransitionField.KeyFrames.keyWord
+        )
         .withTransitionsParentAtLevel(KEYFRAMES_PROPERTY_DEPTH),
       KeyFramesFieldsProvider
     )
@@ -162,7 +199,10 @@
       CompletionType.BASIC,
       // Complete fields of an OnSwipe block
       jsonPropertyName()
-        .withPropertyParentAtLevel(BASE_DEPTH_FOR_NAME_IN_PROPERTY_OBJECT, TransitionField.OnSwipe.keyWord)
+        .withPropertyParentAtLevel(
+          BASE_DEPTH_FOR_NAME_IN_PROPERTY_OBJECT,
+          TransitionField.OnSwipe.keyWord
+        )
         .withTransitionsParentAtLevel(ONSWIPE_PROPERTY_DEPTH),
       OnSwipeFieldsProvider
     )
@@ -170,7 +210,10 @@
       CompletionType.BASIC,
       // Complete the possible IDs for the OnSwipe `anchor` property
       jsonStringValue()
-        .withPropertyParentAtLevel(BASE_DEPTH_FOR_LITERAL_IN_PROPERTY, OnSwipeField.AnchorId.keyWord),
+        .withPropertyParentAtLevel(
+          BASE_DEPTH_FOR_LITERAL_IN_PROPERTY,
+          OnSwipeField.AnchorId.keyWord
+        ),
       ConstraintIdsProvider
     )
     extend(
@@ -184,7 +227,10 @@
       CompletionType.BASIC,
       // Complete the known values for the OnSwipe `direction` property
       jsonStringValue()
-        .withPropertyParentAtLevel(BASE_DEPTH_FOR_LITERAL_IN_PROPERTY, OnSwipeField.Direction.keyWord),
+        .withPropertyParentAtLevel(
+          BASE_DEPTH_FOR_LITERAL_IN_PROPERTY,
+          OnSwipeField.Direction.keyWord
+        ),
       EnumValuesCompletionProvider(OnSwipeDirection::class)
     )
     extend(
@@ -199,17 +245,26 @@
       // Complete the fields for any of the possible KeyFrames children
       jsonPropertyName()
         // A level deeper considering the array surrounding the object
-        .withPropertyParentAtLevel(BASE_DEPTH_FOR_NAME_IN_PROPERTY_OBJECT + 1, KeyFrameField.values().map { it.keyWord }),
+        .withPropertyParentAtLevel(
+          BASE_DEPTH_FOR_NAME_IN_PROPERTY_OBJECT + 1,
+          KeyFrameField.values().map { it.keyWord }
+        ),
       KeyFrameChildFieldsCompletionProvider
     )
-    //endregion
+    // endregion
   }
 
-  override fun fillCompletionVariants(parameters: CompletionParameters, result: CompletionResultSet) {
-    if (parameters.position.getModuleSystem()?.usesCompose != true || parameters.position.language != JsonLanguage.INSTANCE) {
+  override fun fillCompletionVariants(
+    parameters: CompletionParameters,
+    result: CompletionResultSet
+  ) {
+    if (
+      parameters.position.getModuleSystem()?.usesCompose != true ||
+        parameters.position.language != JsonLanguage.INSTANCE
+    ) {
       // TODO(b/207030860): Allow in other contexts once the syntax is supported outside Compose
       return
     }
     super.fillCompletionVariants(parameters, result)
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/InsertionFormat.kt b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/InsertionFormat.kt
index 0ba83a9..cf5462a 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/InsertionFormat.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/InsertionFormat.kt
@@ -31,17 +31,21 @@
 
 internal val ConstrainAnchorTemplate = LiveTemplateFormat(": ['<>', '<>', <0>],")
 
-internal val ClearAllTemplate = LiteralWithCaretFormat(
-  literalFormat = ": ['${ClearOption.Constraints}', '${ClearOption.Dimensions}', '${ClearOption.Transforms}'],"
-)
+internal val ClearAllTemplate =
+  LiteralWithCaretFormat(
+    literalFormat =
+      ": ['${ClearOption.Constraints}', '${ClearOption.Dimensions}', '${ClearOption.Transforms}'],"
+  )
 
 /**
- * Returns a [LiveTemplateFormat] that contains a template for a Json array with numeric type, where the size of the array is given by
- * [count] and the user may edit each of the values in the array using Live Templates.
+ * Returns a [LiveTemplateFormat] that contains a template for a Json array with numeric type, where
+ * the size of the array is given by [count] and the user may edit each of the values in the array
+ * using Live Templates.
  *
- * E.g.: For [count] = 3, returns the template: `": [0, 0, 0],"`, where every value may be changed by the user.
+ * E.g.: For [count] = 3, returns the template: `": [0, 0, 0],"`, where every value may be changed
+ * by the user.
  */
 internal fun buildJsonNumberArrayTemplate(count: Int): LiveTemplateFormat {
   val times = count.coerceAtLeast(1)
   return LiveTemplateFormat(": [" + "<0>, ".repeat(times).removeSuffix(", ") + "],")
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/JsonPsiUtil.kt b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/JsonPsiUtil.kt
index 29a5b45..50c1418 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/JsonPsiUtil.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/JsonPsiUtil.kt
@@ -20,8 +20,10 @@
 import com.intellij.psi.util.parentOfType
 
 /**
- * From the element being invoked, returns the [JsonProperty] parent that also includes the [JsonProperty] from which completion is
- * triggered.
+ * From the element being invoked, returns the [JsonProperty] parent that also includes the
+ * [JsonProperty] from which completion is triggered.
  */
 internal fun getJsonPropertyParent(parameters: CompletionParameters): JsonProperty? =
-  parameters.position.parentOfType<JsonProperty>(withSelf = true)?.parentOfType<JsonProperty>(withSelf = false)
\ No newline at end of file
+  parameters.position
+    .parentOfType<JsonProperty>(withSelf = true)
+    ?.parentOfType<JsonProperty>(withSelf = false)
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/PatternUtils.kt b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/PatternUtils.kt
index 2937e7a..e2c9f53 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/PatternUtils.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/PatternUtils.kt
@@ -35,67 +35,90 @@
 internal fun jsonStringValue() =
   PlatformPatterns.psiElement(JsonElementTypes.SINGLE_QUOTED_STRING).withParent<JsonStringLiteral>()
 
-internal fun PsiElementPattern<*, *>.withConstraintSetsParentAtLevel(level: Int) = withPropertyParentAtLevel(level, KeyWords.ConstraintSets)
-internal fun PsiElementPattern<*, *>.withTransitionsParentAtLevel(level: Int) = withPropertyParentAtLevel(level, KeyWords.Transitions)
+internal fun PsiElementPattern<*, *>.withConstraintSetsParentAtLevel(level: Int) =
+  withPropertyParentAtLevel(level, KeyWords.ConstraintSets)
+
+internal fun PsiElementPattern<*, *>.withTransitionsParentAtLevel(level: Int) =
+  withPropertyParentAtLevel(level, KeyWords.Transitions)
 
 internal fun PsiElementPattern<*, *>.insideClearArray() = inArrayWithinConstraintBlockProperty {
   // For the 'clear' constraint block property
   matches(KeyWords.Clear)
 }
 
-internal fun PsiElementPattern<*, *>.insideConstraintArray() = inArrayWithinConstraintBlockProperty {
-  // The parent property name may only be a StandardAnchor
-  oneOf(StandardAnchor.values().map { it.keyWord })
-}
+internal fun PsiElementPattern<*, *>.insideConstraintArray() =
+  inArrayWithinConstraintBlockProperty {
+    // The parent property name may only be a StandardAnchor
+    oneOf(StandardAnchor.values().map { it.keyWord })
+  }
 
 /**
- * [PsiElementPattern] that matches an element in a [JsonArray] within a Constraint block. Where the property the array is assigned to, has
- * a name that is matched by [matchPropertyName].
+ * [PsiElementPattern] that matches an element in a [JsonArray] within a Constraint block. Where the
+ * property the array is assigned to, has a name that is matched by [matchPropertyName].
  */
-internal fun PsiElementPattern<*, *>.inArrayWithinConstraintBlockProperty(matchPropertyName: StringPattern.() -> StringPattern) =
+internal fun PsiElementPattern<*, *>.inArrayWithinConstraintBlockProperty(
+  matchPropertyName: StringPattern.() -> StringPattern
+) =
   withSuperParent(2, psiElement<JsonArray>())
     .withSuperParent(
       BASE_DEPTH_FOR_LITERAL_IN_PROPERTY + 1, // JsonArray adds one level
-      psiElement<JsonProperty>().withChild(
-        // The first expression in a JsonProperty corresponds to the name of the property
-        psiElement<JsonReferenceExpression>().withText(StandardPatterns.string().matchPropertyName())
-      )
+      psiElement<JsonProperty>()
+        .withChild(
+          // The first expression in a JsonProperty corresponds to the name of the property
+          psiElement<JsonReferenceExpression>()
+            .withText(StandardPatterns.string().matchPropertyName())
+        )
     )
-    .withConstraintSetsParentAtLevel(CONSTRAINT_BLOCK_PROPERTY_DEPTH + 1) // JsonArray adds one level
+    .withConstraintSetsParentAtLevel(
+      CONSTRAINT_BLOCK_PROPERTY_DEPTH + 1
+    ) // JsonArray adds one level
 // endregion
 
 // region Kotlin Syntax Helpers
-internal inline fun <reified T : PsiElement> psiElement(): PsiElementPattern<T, PsiElementPattern.Capture<T>> =
-  PlatformPatterns.psiElement(T::class.java)
+internal inline fun <reified T : PsiElement> psiElement():
+  PsiElementPattern<T, PsiElementPattern.Capture<T>> = PlatformPatterns.psiElement(T::class.java)
 
-internal inline fun <reified T : PsiElement> PsiElementPattern<*, *>.withParent() = this.withParent(T::class.java)
+internal inline fun <reified T : PsiElement> PsiElementPattern<*, *>.withParent() =
+  this.withParent(T::class.java)
 
 /**
- * Pattern such that when traversing up the tree from the current element, the element at [level] is a [JsonProperty]. And its name matches
- * the given [name].
+ * Pattern such that when traversing up the tree from the current element, the element at [level] is
+ * a [JsonProperty]. And its name matches the given [name].
  */
 internal fun PsiElementPattern<*, *>.withPropertyParentAtLevel(level: Int, name: String) =
   withPropertyParentAtLevel(level, listOf(name))
 
 /**
- * Pattern such that when traversing up the tree from the current element, the element at [level] is a [JsonProperty]. Which name matches
- * one of the given [names].
+ * Pattern such that when traversing up the tree from the current element, the element at [level] is
+ * a [JsonProperty]. Which name matches one of the given [names].
  */
-internal fun PsiElementPattern<*, *>.withPropertyParentAtLevel(level: Int, names: Collection<String>) =
-  this.withSuperParent(level, psiElement<JsonProperty>().withChild(
-    psiElement<JsonReferenceExpression>().withText(StandardPatterns.string().oneOf(names)))
+internal fun PsiElementPattern<*, *>.withPropertyParentAtLevel(
+  level: Int,
+  names: Collection<String>
+) =
+  this.withSuperParent(
+    level,
+    psiElement<JsonProperty>()
+      .withChild(
+        psiElement<JsonReferenceExpression>().withText(StandardPatterns.string().oneOf(names))
+      )
   )
 
 /**
- * Verifies that the current element is at the given [index] of the elements contained by its [JsonArray] parent.
+ * Verifies that the current element is at the given [index] of the elements contained by its
+ * [JsonArray] parent.
  */
-internal fun <T : JsonValue> PsiElementPattern<T, PsiElementPattern.Capture<T>>.atIndexOfJsonArray(index: Int) =
-  with(object : PatternCondition<T>("atIndexOfJsonArray") {
-    override fun accepts(element: T, context: ProcessingContext?): Boolean {
-      val parent = element.context as? JsonArray ?: return false
-      val children = parent.valueList
-      val indexOfSelf = children.indexOf(element)
-      return index == indexOfSelf
+internal fun <T : JsonValue> PsiElementPattern<T, PsiElementPattern.Capture<T>>.atIndexOfJsonArray(
+  index: Int
+) =
+  with(
+    object : PatternCondition<T>("atIndexOfJsonArray") {
+      override fun accepts(element: T, context: ProcessingContext?): Boolean {
+        val parent = element.context as? JsonArray ?: return false
+        val children = parent.valueList
+        val indexOfSelf = children.indexOf(element)
+        return index == indexOfSelf
+      }
     }
-  })
-// endregion
\ No newline at end of file
+  )
+// endregion
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/CompletionProviders.kt b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/CompletionProviders.kt
index 8f6ac28..e8dff54 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/CompletionProviders.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/CompletionProviders.kt
@@ -57,11 +57,17 @@
 import kotlin.reflect.KClass
 
 /**
- * Completion provider that looks for the 'ConstraintSets' declaration and passes a model that provides useful functions for inheritors that
- * want to provide completions based on the contents of the 'ConstraintSets' [JsonProperty].
+ * Completion provider that looks for the 'ConstraintSets' declaration and passes a model that
+ * provides useful functions for inheritors that want to provide completions based on the contents
+ * of the 'ConstraintSets' [JsonProperty].
  */
-internal abstract class BaseConstraintSetsCompletionProvider : CompletionProvider<CompletionParameters>() {
-  final override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) {
+internal abstract class BaseConstraintSetsCompletionProvider :
+  CompletionProvider<CompletionParameters>() {
+  final override fun addCompletions(
+    parameters: CompletionParameters,
+    context: ProcessingContext,
+    result: CompletionResultSet
+  ) {
     val constraintSetsModel = createConstraintSetsModel(initialElement = parameters.position)
     if (constraintSetsModel != null) {
       ProgressManager.checkCanceled()
@@ -70,7 +76,8 @@
   }
 
   /**
-   * Inheritors should implement this function that may pass a reference to the ConstraintSets property.
+   * Inheritors should implement this function that may pass a reference to the ConstraintSets
+   * property.
    */
   abstract fun addCompletions(
     constraintSetsPropertyModel: ConstraintSetsPropertyModel,
@@ -85,7 +92,8 @@
    */
   private fun createConstraintSetsModel(initialElement: PsiElement): ConstraintSetsPropertyModel? {
     // Start with the closest JsonObject towards the root
-    var currentJsonObject: JsonObject? = initialElement.parentOfType<JsonObject>(withSelf = true) ?: return null
+    var currentJsonObject: JsonObject? =
+      initialElement.parentOfType<JsonObject>(withSelf = true) ?: return null
     lateinit var topLevelJsonObject: JsonObject
 
     // Then find the top most JsonObject while checking for cancellation
@@ -96,18 +104,22 @@
       ProgressManager.checkCanceled()
     }
 
-    // The last non-null JsonObject is the topmost, the ConstraintSets property is expected within this element
-    val constraintSetsProperty = topLevelJsonObject.findProperty(KeyWords.ConstraintSets) ?: return null
-    // TODO(b/207030860): Consider creating the model even if there's no property that is explicitly called 'ConstraintSets'
-    //    ie: imply that the root JsonObject is the ConstraintSets object, with the downside that figuring out the correct context would
+    // The last non-null JsonObject is the topmost, the ConstraintSets property is expected within
+    // this element
+    val constraintSetsProperty =
+      topLevelJsonObject.findProperty(KeyWords.ConstraintSets) ?: return null
+    // TODO(b/207030860): Consider creating the model even if there's no property that is explicitly
+    // called 'ConstraintSets'
+    //    ie: imply that the root JsonObject is the ConstraintSets object, with the downside that
+    // figuring out the correct context would
     //    be much more difficult
     return ConstraintSetsPropertyModel(constraintSetsProperty)
   }
 }
 
 /**
- * Provides options to autocomplete constraint IDs for constraint set declarations, based on the IDs already defined by the user in other
- * constraint sets.
+ * Provides options to autocomplete constraint IDs for constraint set declarations, based on the IDs
+ * already defined by the user in other constraint sets.
  */
 internal object ConstraintSetFieldsProvider : BaseConstraintSetsCompletionProvider() {
   override fun addCompletions(
@@ -115,17 +127,21 @@
     parameters: CompletionParameters,
     result: CompletionResultSet
   ) {
-    val currentConstraintSet = ConstraintSetModel.getModelForCompletionOnConstraintSetProperty(parameters) ?: return
+    val currentConstraintSet =
+      ConstraintSetModel.getModelForCompletionOnConstraintSetProperty(parameters) ?: return
     val currentSetName = currentConstraintSet.name ?: return
-    constraintSetsPropertyModel.getRemainingFieldsForConstraintSet(currentSetName).forEach { fieldName ->
-      val template = if (fieldName == KeyWords.Extends) JsonStringValueTemplate else JsonNewObjectTemplate
+    constraintSetsPropertyModel.getRemainingFieldsForConstraintSet(currentSetName).forEach {
+      fieldName ->
+      val template =
+        if (fieldName == KeyWords.Extends) JsonStringValueTemplate else JsonNewObjectTemplate
       result.addLookupElement(lookupString = fieldName, tailText = null, template)
     }
   }
 }
 
 /**
- * Autocomplete options with the names of all available ConstraintSets, except from the one the autocomplete was invoked from.
+ * Autocomplete options with the names of all available ConstraintSets, except from the one the
+ * autocomplete was invoked from.
  */
 internal object ConstraintSetNamesProvider : BaseConstraintSetsCompletionProvider() {
   override fun addCompletions(
@@ -133,7 +149,8 @@
     parameters: CompletionParameters,
     result: CompletionResultSet
   ) {
-    val currentConstraintSet = ConstraintSetModel.getModelForCompletionOnConstraintSetProperty(parameters)
+    val currentConstraintSet =
+      ConstraintSetModel.getModelForCompletionOnConstraintSetProperty(parameters)
     val currentSetName = currentConstraintSet?.name
     val names = constraintSetsPropertyModel.getConstraintSetNames().toMutableSet()
     if (currentSetName != null) {
@@ -144,7 +161,8 @@
 }
 
 /**
- * Autocomplete options used to define the constraints of a widget (defined by the ID) within a ConstraintSet
+ * Autocomplete options used to define the constraints of a widget (defined by the ID) within a
+ * ConstraintSet
  */
 internal object ConstraintsProvider : BaseConstraintSetsCompletionProvider() {
   override fun addCompletions(
@@ -152,11 +170,16 @@
     parameters: CompletionParameters,
     result: CompletionResultSet
   ) {
-    val parentPropertyModel = JsonPropertyModel.getModelForCompletionOnInnerJsonProperty(parameters) ?: return
+    val parentPropertyModel =
+      JsonPropertyModel.getModelForCompletionOnInnerJsonProperty(parameters) ?: return
     val existingFieldsSet = parentPropertyModel.declaredFieldNamesSet
     StandardAnchor.values().forEach {
       if (!existingFieldsSet.contains(it.keyWord)) {
-        result.addLookupElement(lookupString = it.keyWord, tailText = " [...]", format = ConstrainAnchorTemplate)
+        result.addLookupElement(
+          lookupString = it.keyWord,
+          tailText = " [...]",
+          format = ConstrainAnchorTemplate
+        )
       }
     }
     if (!existingFieldsSet.contains(KeyWords.Visibility)) {
@@ -167,13 +190,16 @@
     result.addEnumKeyWordsWithNumericValueTemplate<RenderTransform>(existingFieldsSet)
 
     // Complete 'clear' if the containing ConstraintSet has `extendsFrom`
-    val containingConstraintSetModel = parentPropertyModel.getParentProperty()?.let {
-      ConstraintSetModel(it)
-    }
+    val containingConstraintSetModel =
+      parentPropertyModel.getParentProperty()?.let { ConstraintSetModel(it) }
     if (containingConstraintSetModel?.extendsFrom != null) {
       // Add an option with an empty string array and another one with all clear options
       result.addLookupElement(lookupString = KeyWords.Clear, format = JsonStringArrayTemplate)
-      result.addLookupElement(lookupString = KeyWords.Clear, format = ClearAllTemplate, tailText = " [<all>]")
+      result.addLookupElement(
+        lookupString = KeyWords.Clear,
+        format = ClearAllTemplate,
+        tailText = " [<all>]"
+      )
     }
   }
 }
@@ -181,8 +207,8 @@
 /**
  * Provides IDs when autocompleting a constraint array.
  *
- * The ID may be either 'parent' or any of the declared IDs in all ConstraintSets, except the ID of the constraints block from which this
- * provider was invoked.
+ * The ID may be either 'parent' or any of the declared IDs in all ConstraintSets, except the ID of
+ * the constraints block from which this provider was invoked.
  */
 internal object ConstraintIdsProvider : BaseConstraintSetsCompletionProvider() {
   override fun addCompletions(
@@ -190,22 +216,22 @@
     parameters: CompletionParameters,
     result: CompletionResultSet
   ) {
-    val possibleIds = constraintSetsPropertyModel.constraintSets.flatMap { it.declaredIds }.toCollection(HashSet())
+    val possibleIds =
+      constraintSetsPropertyModel.constraintSets.flatMap { it.declaredIds }.toCollection(HashSet())
     // Parent ID should always be present
     possibleIds.add(KeyWords.ParentId)
     // Remove the current ID
     getJsonPropertyParent(parameters)?.name?.let(possibleIds::remove)
 
-    possibleIds.forEach { id ->
-      result.addLookupElement(lookupString = id)
-    }
+    possibleIds.forEach { id -> result.addLookupElement(lookupString = id) }
   }
 }
 
 /**
  * Provides the appropriate anchors when completing a constraint array.
  *
- * [StandardAnchor.verticalAnchors] can only be constrained to other vertical anchors. Same logic for [StandardAnchor.horizontalAnchors].
+ * [StandardAnchor.verticalAnchors] can only be constrained to other vertical anchors. Same logic
+ * for [StandardAnchor.horizontalAnchors].
  */
 internal object AnchorablesProvider : BaseConstraintSetsCompletionProvider() {
   override fun addCompletions(
@@ -213,13 +239,15 @@
     parameters: CompletionParameters,
     result: CompletionResultSet
   ) {
-    val currentAnchorKeyWord = parameters.position.parentOfType<JsonProperty>(withSelf = true)?.name ?: return
+    val currentAnchorKeyWord =
+      parameters.position.parentOfType<JsonProperty>(withSelf = true)?.name ?: return
 
-    val possibleAnchors = when {
-      StandardAnchor.isVertical(currentAnchorKeyWord) -> StandardAnchor.verticalAnchors
-      StandardAnchor.isHorizontal(currentAnchorKeyWord) -> StandardAnchor.horizontalAnchors
-      else -> emptyList()
-    }
+    val possibleAnchors =
+      when {
+        StandardAnchor.isVertical(currentAnchorKeyWord) -> StandardAnchor.verticalAnchors
+        StandardAnchor.isHorizontal(currentAnchorKeyWord) -> StandardAnchor.horizontalAnchors
+        else -> emptyList()
+      }
     possibleAnchors.forEach { result.addLookupElement(lookupString = it.keyWord) }
   }
 }
@@ -235,10 +263,14 @@
     parameters: CompletionParameters,
     result: CompletionResultSet
   ) {
-    val existing = parameters.position.parentOfType<JsonArray>(withSelf = false)?.valueList
-                     ?.filterIsInstance<JsonStringLiteral>()
-                     ?.map { it.value }
-                     ?.toSet() ?: emptySet()
+    val existing =
+      parameters.position
+        .parentOfType<JsonArray>(withSelf = false)
+        ?.valueList
+        ?.filterIsInstance<JsonStringLiteral>()
+        ?.map { it.value }
+        ?.toSet()
+        ?: emptySet()
     addEnumKeywords<ClearOption>(result, existing)
   }
 }
@@ -249,8 +281,13 @@
  * @see TransitionField
  */
 internal object TransitionFieldsProvider : CompletionProvider<CompletionParameters>() {
-  override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) {
-    val parentPropertyModel = JsonPropertyModel.getModelForCompletionOnInnerJsonProperty(parameters) ?: return
+  override fun addCompletions(
+    parameters: CompletionParameters,
+    context: ProcessingContext,
+    result: CompletionResultSet
+  ) {
+    val parentPropertyModel =
+      JsonPropertyModel.getModelForCompletionOnInnerJsonProperty(parameters) ?: return
     TransitionField.values().forEach {
       if (parentPropertyModel.containsPropertyOfName(it.keyWord)) {
         // skip
@@ -275,9 +312,16 @@
  * @see OnSwipeField
  */
 internal object OnSwipeFieldsProvider : CompletionProvider<CompletionParameters>() {
-  override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) {
-    val parentPropertyModel = JsonPropertyModel.getModelForCompletionOnInnerJsonProperty(parameters) ?: return
-    result.addEnumKeyWordsWithStringValueTemplate<OnSwipeField>(parentPropertyModel.declaredFieldNamesSet)
+  override fun addCompletions(
+    parameters: CompletionParameters,
+    context: ProcessingContext,
+    result: CompletionResultSet
+  ) {
+    val parentPropertyModel =
+      JsonPropertyModel.getModelForCompletionOnInnerJsonProperty(parameters) ?: return
+    result.addEnumKeyWordsWithStringValueTemplate<OnSwipeField>(
+      parentPropertyModel.declaredFieldNamesSet
+    )
   }
 }
 
@@ -287,8 +331,13 @@
  * @see KeyFrameField
  */
 internal object KeyFramesFieldsProvider : CompletionProvider<CompletionParameters>() {
-  override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) {
-    val parentPropertyModel = JsonPropertyModel.getModelForCompletionOnInnerJsonProperty(parameters) ?: return
+  override fun addCompletions(
+    parameters: CompletionParameters,
+    context: ProcessingContext,
+    result: CompletionResultSet
+  ) {
+    val parentPropertyModel =
+      JsonPropertyModel.getModelForCompletionOnInnerJsonProperty(parameters) ?: return
     addEnumKeywords<KeyFrameField>(
       result = result,
       format = JsonObjectArrayTemplate,
@@ -298,21 +347,29 @@
 }
 
 /**
- * Provides completion for the fields of KeyFrame children. A KeyFrame child can be any of [KeyFrameField].
+ * Provides completion for the fields of KeyFrame children. A KeyFrame child can be any of
+ * [KeyFrameField].
  */
 internal object KeyFrameChildFieldsCompletionProvider : CompletionProvider<CompletionParameters>() {
-  override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) {
-    // TODO(b/207030860): For consistency, make it so that JsonPropertyModel may be used here. It currently won't work because the model
+  override fun addCompletions(
+    parameters: CompletionParameters,
+    context: ProcessingContext,
+    result: CompletionResultSet
+  ) {
+    // TODO(b/207030860): For consistency, make it so that JsonPropertyModel may be used here. It
+    // currently won't work because the model
     //  doesn't consider a property defined by an array of objects.
 
     // Obtain existing list of existing properties
     val parentObject = parameters.position.parentOfType<JsonObject>(withSelf = false) ?: return
     val existingFieldsSet = parentObject.propertyList.map { it.name }.toSet()
 
-    // We have to know the type of KeyFrame we are autocompleting for (KeyPositions, KeyAttributes, etc)
+    // We have to know the type of KeyFrame we are autocompleting for (KeyPositions, KeyAttributes,
+    // etc)
     val keyFrameTypeName = parentObject.parentOfType<JsonProperty>(withSelf = false)?.name ?: return
 
-    // Look for the `frames` property, we want to know the size of its array (if present), since all other numeric properties should have an
+    // Look for the `frames` property, we want to know the size of its array (if present), since all
+    // other numeric properties should have an
     // array of the same size
     val framesProperty = parentObject.findProperty(KeyFrameChildCommonField.Frames.keyWord)
     val arrayCountInFramesProperty = (framesProperty?.value as? JsonArray)?.valueList?.size ?: 1
@@ -329,12 +386,14 @@
         return@forEach
       }
       when (it) {
-        KeyFrameChildCommonField.Frames -> result.addLookupElement(lookupString = it.keyWord, format = jsonNumberArrayTemplate)
+        KeyFrameChildCommonField.Frames ->
+          result.addLookupElement(lookupString = it.keyWord, format = jsonNumberArrayTemplate)
         else -> result.addLookupElement(lookupString = it.keyWord, format = JsonStringValueTemplate)
       }
     }
 
-    // Figure out which type of KeyFrame the completion is being called on, and offer completion for their respective fields
+    // Figure out which type of KeyFrame the completion is being called on, and offer completion for
+    // their respective fields
     when (keyFrameTypeName) {
       KeyFrameField.Positions.keyWord -> {
         addKeyPositionFields(result, existingFieldsSet) {
@@ -344,12 +403,24 @@
       }
       KeyFrameField.Attributes.keyWord -> {
         // KeyAttributes properties are the same as the RenderTransform fields
-        addEnumKeywords<RenderTransform>(result = result, format = jsonNumberArrayTemplate, existing = existingFieldsSet)
+        addEnumKeywords<RenderTransform>(
+          result = result,
+          format = jsonNumberArrayTemplate,
+          existing = existingFieldsSet
+        )
       }
       KeyFrameField.Cycles.keyWord -> {
         // KeyCycles properties are a mix of RenderTransform fields and KeyCycles specific fields
-        addEnumKeywords<RenderTransform>(result = result, format = jsonNumberArrayTemplate, existing = existingFieldsSet)
-        addEnumKeywords<KeyCycleField>(result = result, format = jsonNumberArrayTemplate, existing = existingFieldsSet)
+        addEnumKeywords<RenderTransform>(
+          result = result,
+          format = jsonNumberArrayTemplate,
+          existing = existingFieldsSet
+        )
+        addEnumKeywords<KeyCycleField>(
+          result = result,
+          format = jsonNumberArrayTemplate,
+          existing = existingFieldsSet
+        )
       }
       else -> {
         thisLogger().warn("Completion on unknown KeyFrame type: $keyFrameTypeName")
@@ -358,7 +429,8 @@
   }
 
   /**
-   * Add LookupElements to the [result] for each non-repeated [KeyPositionField] using the [InsertionFormat] returned by [templateProvider].
+   * Add LookupElements to the [result] for each non-repeated [KeyPositionField] using the
+   * [InsertionFormat] returned by [templateProvider].
    */
   private fun addKeyPositionFields(
     result: CompletionResultSet,
@@ -370,7 +442,10 @@
         // Skip repeated fields
         return@forEach
       }
-      result.addLookupElement(lookupString = keyPositionField.keyWord, format = templateProvider(keyPositionField))
+      result.addLookupElement(
+        lookupString = keyPositionField.keyWord,
+        format = templateProvider(keyPositionField)
+      )
     }
   }
 
@@ -390,17 +465,20 @@
  *
  * The provided values come from [ConstraintLayoutKeyWord.keyWord].
  */
-internal class EnumValuesCompletionProvider<E>(private val enumClass: KClass<E>)
-  : CompletionProvider<CompletionParameters>() where E : Enum<E>, E : ConstraintLayoutKeyWord {
-  override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) {
-    enumClass.java.enumConstants.forEach {
-      result.addLookupElement(lookupString = it.keyWord)
-    }
+internal class EnumValuesCompletionProvider<E>(private val enumClass: KClass<E>) :
+  CompletionProvider<CompletionParameters>() where E : Enum<E>, E : ConstraintLayoutKeyWord {
+  override fun addCompletions(
+    parameters: CompletionParameters,
+    context: ProcessingContext,
+    result: CompletionResultSet
+  ) {
+    enumClass.java.enumConstants.forEach { result.addLookupElement(lookupString = it.keyWord) }
   }
 }
 
 /**
- * Add the [ConstraintLayoutKeyWord.keyWord] of the enum constants as a completion result that takes a string for its value.
+ * Add the [ConstraintLayoutKeyWord.keyWord] of the enum constants as a completion result that takes
+ * a string for its value.
  */
 private inline fun <reified E> CompletionResultSet.addEnumKeyWordsWithStringValueTemplate(
   existing: Set<String>
@@ -409,7 +487,8 @@
 }
 
 /**
- * Add the [ConstraintLayoutKeyWord.keyWord] of the enum constants as a completion result that takes a number for its value.
+ * Add the [ConstraintLayoutKeyWord.keyWord] of the enum constants as a completion result that takes
+ * a number for its value.
  */
 private inline fun <reified E> CompletionResultSet.addEnumKeyWordsWithNumericValueTemplate(
   existing: Set<String>
@@ -417,9 +496,7 @@
   addEnumKeywords<E>(result = this, existing = existing, format = JsonNumericValueTemplate)
 }
 
-/**
- * Helper function to simplify adding enum constant members to the completion result.
- */
+/** Helper function to simplify adding enum constant members to the completion result. */
 private inline fun <reified E> addEnumKeywords(
   result: CompletionResultSet,
   existing: Set<String> = emptySet(),
@@ -430,4 +507,4 @@
       result.addLookupElement(lookupString = constant.keyWord, format = format)
     }
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/model/BaseJsonElementModel.kt b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/model/BaseJsonElementModel.kt
index 16e74dd..a17aa03 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/model/BaseJsonElementModel.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/model/BaseJsonElementModel.kt
@@ -25,53 +25,45 @@
 import com.intellij.psi.util.parentOfType
 import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
 
-/**
- * Base model for [JsonElement], sets a pointer to avoid holding to the element itself.
- */
-internal abstract class BaseJsonElementModel<E: JsonElement>(element: E) {
+/** Base model for [JsonElement], sets a pointer to avoid holding to the element itself. */
+internal abstract class BaseJsonElementModel<E : JsonElement>(element: E) {
   protected val elementPointer = SmartPointerManager.createPointer(element)
 }
 
 /**
  * Base model for a [JsonProperty].
  *
- * Populates some common fields and provides useful function while avoiding holding to PsiElement instances.
+ * Populates some common fields and provides useful function while avoiding holding to PsiElement
+ * instances.
  */
-internal open class JsonPropertyModel(element: JsonProperty): BaseJsonElementModel<JsonProperty>(element) {
-  /**
-   * The [JsonObject] that describes this [JsonProperty].
-   */
+internal open class JsonPropertyModel(element: JsonProperty) :
+  BaseJsonElementModel<JsonProperty>(element) {
+  /** The [JsonObject] that describes this [JsonProperty]. */
   private val innerJsonObject: JsonObject? = elementPointer.element?.getChildOfType<JsonObject>()
 
-  /**
-   * A mapping of the containing [JsonProperty]s by their declare name.
-   */
+  /** A mapping of the containing [JsonProperty]s by their declare name. */
   private val propertiesByName: Map<String, JsonProperty> =
     innerJsonObject?.propertyList?.associateBy { it.name } ?: emptyMap()
 
-  /**
-   * [List] of all the children of this element that are [JsonProperty].
-   */
+  /** [List] of all the children of this element that are [JsonProperty]. */
   protected val innerProperties: Collection<JsonProperty> = propertiesByName.values
 
-  /**
-   * Name of the [JsonProperty].
-   */
+  /** Name of the [JsonProperty]. */
   val name: String?
     get() = elementPointer.element?.name
 
-  /**
-   * A set of names for all declared properties in this [JsonProperty].
-   */
+  /** A set of names for all declared properties in this [JsonProperty]. */
   val declaredFieldNamesSet: Set<String> = propertiesByName.keys
 
   /**
-   * For the children of the current element, returns the [JsonProperty] which name matches the given [name]. Null if none of them does.
+   * For the children of the current element, returns the [JsonProperty] which name matches the
+   * given [name]. Null if none of them does.
    */
   protected fun findProperty(name: String): JsonProperty? = propertiesByName[name]
 
   /**
-   * Returns true if this [JsonProperty] contains another [JsonProperty] declared by the given [name].
+   * Returns true if this [JsonProperty] contains another [JsonProperty] declared by the given
+   * [name].
    */
   fun containsPropertyOfName(name: String): Boolean = propertiesByName.containsKey(name)
 
@@ -80,22 +72,26 @@
    *
    * May return null if this model is for a top level [JsonProperty].
    */
-  fun getParentProperty(): JsonProperty? = elementPointer.element?.parentOfType<JsonProperty>(withSelf = false)
+  fun getParentProperty(): JsonProperty? =
+    elementPointer.element?.parentOfType<JsonProperty>(withSelf = false)
 
   companion object {
     /**
-     * Returns the [JsonPropertyModel] where the completion is performed on an inner [JsonProperty], including if the completion is on the
-     * value side of the inner [JsonProperty].
+     * Returns the [JsonPropertyModel] where the completion is performed on an inner [JsonProperty],
+     * including if the completion is on the value side of the inner [JsonProperty].
      *
-     * In other words, the model of the second [JsonProperty] parent if the element on [CompletionParameters.getPosition] is NOT a
-     * [JsonProperty].
+     * In other words, the model of the second [JsonProperty] parent if the element on
+     * [CompletionParameters.getPosition] is NOT a [JsonProperty].
      *
-     * Or the model of the first [JsonProperty] parent if the element on [CompletionParameters.getPosition] is a [JsonProperty].
+     * Or the model of the first [JsonProperty] parent if the element on
+     * [CompletionParameters.getPosition] is a [JsonProperty].
      */
-    fun getModelForCompletionOnInnerJsonProperty(parameters: CompletionParameters): JsonPropertyModel? {
+    fun getModelForCompletionOnInnerJsonProperty(
+      parameters: CompletionParameters
+    ): JsonPropertyModel? {
       val parentJsonProperty = getJsonPropertyParent(parameters) ?: return null
       ProgressManager.checkCanceled()
       return JsonPropertyModel(parentJsonProperty)
     }
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/model/ConstraintSetModel.kt b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/model/ConstraintSetModel.kt
index 95fd5db..fc22454 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/model/ConstraintSetModel.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/model/ConstraintSetModel.kt
@@ -28,19 +28,13 @@
  * A ConstraintSet is a state that defines a specific layout of the contents in a ConstraintLayout.
  */
 internal class ConstraintSetModel(jsonProperty: JsonProperty) : JsonPropertyModel(jsonProperty) {
-  /**
-   * List of properties that have a constraint block assigned to it.
-   */
+  /** List of properties that have a constraint block assigned to it. */
   private val propertiesWithConstraints = innerProperties.filter { it.name != KeyWords.Extends }
 
-  /**
-   * Name of the ConstraintSet this is extending constraints from.
-   */
+  /** Name of the ConstraintSet this is extending constraints from. */
   val extendsFrom: String? = (findProperty(KeyWords.Extends)?.value as? JsonStringLiteral)?.value
 
-  /**
-   * List of IDs declared in this ConstraintSet.
-   */
+  /** List of IDs declared in this ConstraintSet. */
   val declaredIds = propertiesWithConstraints.map { it.name }
 
   /**
@@ -49,22 +43,23 @@
    * Note that it does not resolve constraints inherited from [extendsFrom].
    */
   val constraintsById: Map<String, ConstraintsModel> =
-    propertiesWithConstraints.associate { property ->
-      property.name to ConstraintsModel(property)
-    }
+    propertiesWithConstraints.associate { property -> property.name to ConstraintsModel(property) }
 
-  // TODO(b/207030860): Add a method that can pull all resolved constraints for each widget ID, it could be useful to make sure we are not
+  // TODO(b/207030860): Add a method that can pull all resolved constraints for each widget ID, it
+  // could be useful to make sure we are not
   //  offering options that are implicitly present from the 'Extends' ConstraintSet
 
   companion object {
     /**
-     * Returns a [ConstraintSetModel], for when the completion is performed on a property or the value of a property within a ConstraintSet
-     * declaration.
+     * Returns a [ConstraintSetModel], for when the completion is performed on a property or the
+     * value of a property within a ConstraintSet declaration.
      */
-    fun getModelForCompletionOnConstraintSetProperty(parameters: CompletionParameters): ConstraintSetModel? {
+    fun getModelForCompletionOnConstraintSetProperty(
+      parameters: CompletionParameters
+    ): ConstraintSetModel? {
       val parentJsonProperty = getJsonPropertyParent(parameters) ?: return null
       ProgressManager.checkCanceled()
       return ConstraintSetModel(parentJsonProperty)
     }
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/model/ConstraintSetsPropertyModel.kt b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/model/ConstraintSetsPropertyModel.kt
index 0d16fa7..40ca127 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/model/ConstraintSetsPropertyModel.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/model/ConstraintSetsPropertyModel.kt
@@ -21,31 +21,29 @@
 /**
  * Model for the `ConstraintSets` Json block.
  *
- * The `ConstraintSets` Json block, is a collection of different ConstraintSets, each of which describes a state of the layout by defining
- * properties of each of its widgets such as width, height or their layout constraints.
+ * The `ConstraintSets` Json block, is a collection of different ConstraintSets, each of which
+ * describes a state of the layout by defining properties of each of its widgets such as width,
+ * height or their layout constraints.
  *
  * @param constraintSetsElement The PSI element of the `ConstraintSets` Json property
  */
-internal class ConstraintSetsPropertyModel(
-  constraintSetsElement: JsonProperty
-) : JsonPropertyModel(constraintSetsElement) {
-  // TODO(b/209839226): Explore how we could use these models to validate the syntax or structure of the JSON as well as to check logic
+internal class ConstraintSetsPropertyModel(constraintSetsElement: JsonProperty) :
+  JsonPropertyModel(constraintSetsElement) {
+  // TODO(b/209839226): Explore how we could use these models to validate the syntax or structure of
+  // the JSON as well as to check logic
   //  correctness through Inspections/Lint
-  /**
-   * List of all ConstraintSet elements in the Json block.
-   */
+  /** List of all ConstraintSet elements in the Json block. */
   val constraintSets: List<ConstraintSetModel> = innerProperties.map { ConstraintSetModel(it) }
 
-  /**
-   * The names of all ConstraintSets in this block.
-   */
+  /** The names of all ConstraintSets in this block. */
   fun getConstraintSetNames(): Collection<String> {
     return declaredFieldNamesSet
   }
 
   /**
-   * Returns the remaining possible fields for the given [constraintSetName], this is done by reading all fields in all ConstraintSets and
-   * subtracting the fields already present in [constraintSetName]. Most of these should be the IDs that represent constrained widgets.
+   * Returns the remaining possible fields for the given [constraintSetName], this is done by
+   * reading all fields in all ConstraintSets and subtracting the fields already present in
+   * [constraintSetName]. Most of these should be the IDs that represent constrained widgets.
    */
   fun getRemainingFieldsForConstraintSet(constraintSetName: String): List<String> {
     val availableNames = mutableSetOf(KeyWords.Extends)
@@ -54,8 +52,7 @@
       constraintSet.declaredFieldNamesSet.forEach { propertyName ->
         if (constraintSet.name == constraintSetName) {
           usedNames.add(propertyName)
-        }
-        else {
+        } else {
           availableNames.add(propertyName)
         }
       }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/model/ConstraintsModel.kt b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/model/ConstraintsModel.kt
index 4370246..b8ea00e 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/model/ConstraintsModel.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/code/completion/constraintlayout/provider/model/ConstraintsModel.kt
@@ -18,12 +18,14 @@
 import com.intellij.json.psi.JsonProperty
 
 /**
- * Model for the JSON block that corresponds to the constraints applied on a widget (defined by an ID).
+ * Model for the JSON block that corresponds to the constraints applied on a widget (defined by an
+ * ID).
  *
- * Constraints are a set of instructions that define the widget's dimensions, position with respect to other widgets and render-time
- * transforms.
+ * Constraints are a set of instructions that define the widget's dimensions, position with respect
+ * to other widgets and render-time transforms.
  */
-internal class ConstraintsModel(jsonProperty: JsonProperty): JsonPropertyModel(jsonProperty) {
-  // TODO(b/207030860): Fill the contents of this model as is necessary, keeping in mind that it would be useful to have fields like
+internal class ConstraintsModel(jsonProperty: JsonProperty) : JsonPropertyModel(jsonProperty) {
+  // TODO(b/207030860): Fill the contents of this model as is necessary, keeping in mind that it
+  // would be useful to have fields like
   //   'verticalConstraints', 'hasBaseline', 'dimensionBehavior', etc...
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeDebuggerClassesFilterProvider.kt b/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeDebuggerClassesFilterProvider.kt
index d1a1e7f..2ca5c53 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeDebuggerClassesFilterProvider.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeDebuggerClassesFilterProvider.kt
@@ -24,6 +24,7 @@
   }
 
   override fun getFilters(): List<ClassFilter> {
-    return if (ComposeDebuggerSettings.getInstance().filterComposeRuntimeClasses) FILTERS else listOf()
+    return if (ComposeDebuggerSettings.getInstance().filterComposeRuntimeClasses) FILTERS
+    else listOf()
   }
 }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeDebuggerSettings.kt b/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeDebuggerSettings.kt
index 5780f64..1109a69 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeDebuggerSettings.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeDebuggerSettings.kt
@@ -26,11 +26,9 @@
 import com.intellij.xdebugger.settings.DebuggerSettingsCategory
 import com.intellij.xdebugger.settings.XDebuggerSettings
 
-@State(
-  name = "ComposeDebuggerSettings",
-  storages = [Storage("compose.debug.xml")]
-)
-class ComposeDebuggerSettings : XDebuggerSettings<ComposeDebuggerSettings>("compose_debugger"), Getter<ComposeDebuggerSettings> {
+@State(name = "ComposeDebuggerSettings", storages = [Storage("compose.debug.xml")])
+class ComposeDebuggerSettings :
+  XDebuggerSettings<ComposeDebuggerSettings>("compose_debugger"), Getter<ComposeDebuggerSettings> {
   var filterComposeRuntimeClasses: Boolean = true
 
   companion object {
diff --git a/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeFunctionBreakpoint.kt b/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeFunctionBreakpoint.kt
index 30509b6..ba94610 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeFunctionBreakpoint.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeFunctionBreakpoint.kt
@@ -23,14 +23,14 @@
 import org.jetbrains.kotlin.idea.debugger.core.breakpoints.SourcePositionRefiner
 
 /**
- * A [com.intellij.debugger.ui.breakpoints.MethodBreakpoint] that supports `@Composable` function breakpoints
+ * A [com.intellij.debugger.ui.breakpoints.MethodBreakpoint] that supports `@Composable` function
+ * breakpoints
  */
-internal class ComposeFunctionBreakpoint(
-  project: Project,
-  breakpoint: XBreakpoint<*>
-) : KotlinFunctionBreakpoint(project, breakpoint), SourcePositionRefiner {
+internal class ComposeFunctionBreakpoint(project: Project, breakpoint: XBreakpoint<*>) :
+  KotlinFunctionBreakpoint(project, breakpoint), SourcePositionRefiner {
   override fun isMethodMatch(method: Method, debugProcess: DebugProcessImpl) =
-    method.name() == methodName && method.signature().withoutComposeArgs() == mySignature?.getName(debugProcess)
+    method.name() == methodName &&
+      method.signature().withoutComposeArgs() == mySignature?.getName(debugProcess)
 }
 
 private fun String.withoutComposeArgs(): String {
@@ -40,4 +40,4 @@
     return this
   }
   return substring(0, start) + substring(end)
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeFunctionBreakpointHandlerFactory.kt b/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeFunctionBreakpointHandlerFactory.kt
index dd5d38b..bd28add 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeFunctionBreakpointHandlerFactory.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeFunctionBreakpointHandlerFactory.kt
@@ -19,11 +19,10 @@
 import com.intellij.debugger.engine.JavaBreakpointHandler
 import com.intellij.debugger.engine.JavaBreakpointHandlerFactory
 
-/**
- * A [JavaBreakpointHandlerFactory] for [ComposeFunctionBreakpoint]
- */
+/** A [JavaBreakpointHandlerFactory] for [ComposeFunctionBreakpoint] */
 internal class ComposeFunctionBreakpointHandlerFactory : JavaBreakpointHandlerFactory {
-  override fun createHandler(process: DebugProcessImpl): JavaBreakpointHandler = ComposeFunctionBreakpointHandler(process)
+  override fun createHandler(process: DebugProcessImpl): JavaBreakpointHandler =
+    ComposeFunctionBreakpointHandler(process)
 
   private class ComposeFunctionBreakpointHandler(process: DebugProcessImpl) :
     JavaBreakpointHandler(ComposeFunctionBreakpointType::class.java, process)
diff --git a/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeFunctionBreakpointType.kt b/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeFunctionBreakpointType.kt
index c0b0e80..a593f89 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeFunctionBreakpointType.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/debug/ComposeFunctionBreakpointType.kt
@@ -29,23 +29,29 @@
 import org.jetbrains.kotlin.psi.KtFunction
 import org.jetbrains.kotlin.psi.KtPsiUtil
 
-/**
- * A [com.intellij.debugger.ui.breakpoints.JavaMethodBreakpointType] for `@Composable` functions
- */
+/** A [com.intellij.debugger.ui.breakpoints.JavaMethodBreakpointType] for `@Composable` functions */
 internal class ComposeFunctionBreakpointType :
-  KotlinFunctionBreakpointType("compose-function", ComposeBundle.message("compose.breakpoint.description")) {
+  KotlinFunctionBreakpointType(
+    "compose-function",
+    ComposeBundle.message("compose.breakpoint.description")
+  ) {
 
-  override fun createJavaBreakpoint(project: Project, breakpoint: XBreakpoint<JavaMethodBreakpointProperties>): KotlinFunctionBreakpoint =
-    ComposeFunctionBreakpoint(project, breakpoint)
+  override fun createJavaBreakpoint(
+    project: Project,
+    breakpoint: XBreakpoint<JavaMethodBreakpointProperties>
+  ): KotlinFunctionBreakpoint = ComposeFunctionBreakpoint(project, breakpoint)
 
-  override fun isFunctionBreakpointApplicable(file: VirtualFile, line: Int, project: Project): Boolean =
+  override fun isFunctionBreakpointApplicable(
+    file: VirtualFile,
+    line: Int,
+    project: Project
+  ): Boolean =
     isBreakpointApplicable(file, line, project) { element ->
       when (element) {
         is KtFunction ->
           ApplicabilityResult.maybe(
-            !KtPsiUtil.isLocal(element) &&
-            !element.isInlineOnly() &&
-            element.isComposable())
+            !KtPsiUtil.isLocal(element) && !element.isInlineOnly() && element.isComposable()
+          )
         else -> ApplicabilityResult.UNKNOWN
       }
     }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/debug/ComposePositionManager.kt b/compose-ide-plugin/src/com/android/tools/compose/debug/ComposePositionManager.kt
index f0f23a0..5c5969f 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/debug/ComposePositionManager.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/debug/ComposePositionManager.kt
@@ -41,33 +41,33 @@
  * A PositionManager capable of setting breakpoints inside of ComposableSingleton lambdas.
  *
  * This class essentially resolves breakpoints for lambdas generated by the compose compiler
- * optimization that was introduced in I8c967b14c5d9bf67e5646e60f630f2e29e006366
- * The default [KotlinPositionManager] only locates source positions in enclosing and nested
- * classes, while composable singleton lambdas are cached in a separate top-level class.
+ * optimization that was introduced in I8c967b14c5d9bf67e5646e60f630f2e29e006366 The default
+ * [KotlinPositionManager] only locates source positions in enclosing and nested classes, while
+ * composable singleton lambdas are cached in a separate top-level class.
  *
  * See https://issuetracker.google.com/190373291 for more information.
  */
 class ComposePositionManager(
   private val debugProcess: DebugProcess,
   private val kotlinPositionManager: KotlinPositionManager
-) : MultiRequestPositionManager by kotlinPositionManager, PositionManagerWithMultipleStackFrames  {
+) : MultiRequestPositionManager by kotlinPositionManager, PositionManagerWithMultipleStackFrames {
   override fun getAcceptedFileTypes(): Set<FileType> = KOTLIN_FILE_TYPES
 
   override fun createStackFrames(descriptor: StackFrameDescriptorImpl): List<XStackFrame> =
     kotlinPositionManager.createStackFrames(descriptor)
 
-  override fun evaluateCondition(context: EvaluationContext,
-                                 frame: StackFrameProxyImpl,
-                                 location: Location,
-                                 expression: String): ThreeState =
-    kotlinPositionManager.evaluateCondition(context, frame, location, expression)
+  override fun evaluateCondition(
+    context: EvaluationContext,
+    frame: StackFrameProxyImpl,
+    location: Location,
+    expression: String
+  ): ThreeState = kotlinPositionManager.evaluateCondition(context, frame, location, expression)
 
   /**
    * Returns all prepared classes which could contain the given classPosition.
    *
-   * This handles the case where a user sets a breakpoint in a ComposableSingleton
-   * lambda after the debug process has already initialized the corresponding
-   * `lambda-n` class.
+   * This handles the case where a user sets a breakpoint in a ComposableSingleton lambda after the
+   * debug process has already initialized the corresponding `lambda-n` class.
    */
   override fun getAllClasses(classPosition: SourcePosition): List<ReferenceType> {
     val file = classPosition.file
@@ -79,9 +79,10 @@
     }
 
     val vm = debugProcess.virtualMachineProxy
-    val singletonClasses = vm.classesByName(computeComposableSingletonsClassName(file)).flatMap { referenceType ->
-      if (referenceType.isPrepared) allRecursivelyNestedTypesOf(referenceType) else listOf()
-    }
+    val singletonClasses =
+      vm.classesByName(computeComposableSingletonsClassName(file)).flatMap { referenceType ->
+        if (referenceType.isPrepared) allRecursivelyNestedTypesOf(referenceType) else listOf()
+      }
 
     if (singletonClasses.isEmpty()) {
       throw NoDataException.INSTANCE
@@ -112,7 +113,10 @@
    * the given `position`, but may not be loaded yet. The `requestor` will be called for any newly
    * prepared class which matches any of the created search patterns.
    */
-  override fun createPrepareRequests(requestor: ClassPrepareRequestor, position: SourcePosition): List<ClassPrepareRequest> {
+  override fun createPrepareRequests(
+    requestor: ClassPrepareRequestor,
+    position: SourcePosition
+  ): List<ClassPrepareRequest> {
     val file = position.file
     if (file !is KtFile) {
       throw NoDataException.INSTANCE
@@ -123,32 +127,37 @@
     // in order to locate breakpoints in ordinary Kotlin code.
     val kotlinRequests = kotlinPositionManager.createPrepareRequests(requestor, position)
 
-    val singletonRequest = debugProcess.requestsManager.createClassPrepareRequest(
-      requestor,
-      "${computeComposableSingletonsClassName(file)}\$*"
-    )
+    val singletonRequest =
+      debugProcess.requestsManager.createClassPrepareRequest(
+        requestor,
+        "${computeComposableSingletonsClassName(file)}\$*"
+      )
 
     return if (singletonRequest == null) kotlinRequests else kotlinRequests + singletonRequest
   }
 
   /**
-   * A method from [PositionManager] which was superseded by [createPrepareRequests] in [MultiRequestPositionManager].
-   * Intellij code should never call this method for subclasses of [MultiRequestPositionManager].
+   * A method from [PositionManager] which was superseded by [createPrepareRequests] in
+   * [MultiRequestPositionManager]. Intellij code should never call this method for subclasses of
+   * [MultiRequestPositionManager].
    */
-  override fun createPrepareRequest(requestor: ClassPrepareRequestor, position: SourcePosition): ClassPrepareRequest? {
+  override fun createPrepareRequest(
+    requestor: ClassPrepareRequestor,
+    position: SourcePosition
+  ): ClassPrepareRequest? {
     return createPrepareRequests(requestor, position).firstOrNull()
   }
 
   /**
    * Compute the name of the ComposableSingletons class for the given file.
    *
-   * The Compose compiler plugin creates per-file ComposableSingletons classes to cache
-   * composable lambdas without captured variables. We need to locate these classes in order
-   * to search them for breakpoint locations.
+   * The Compose compiler plugin creates per-file ComposableSingletons classes to cache composable
+   * lambdas without captured variables. We need to locate these classes in order to search them for
+   * breakpoint locations.
    *
-   * NOTE: The pattern for ComposableSingletons classes needs to be kept in sync with the
-   *       code in `ComposerLambdaMemoization.getOrCreateComposableSingletonsClass`.
-   *       The optimization was introduced in I8c967b14c5d9bf67e5646e60f630f2e29e006366
+   * NOTE: The pattern for ComposableSingletons classes needs to be kept in sync with the code in
+   * `ComposerLambdaMemoization.getOrCreateComposableSingletonsClass`. The optimization was
+   * introduced in I8c967b14c5d9bf67e5646e60f630f2e29e006366
    */
   private fun computeComposableSingletonsClassName(file: KtFile): String {
     // The code in `ComposerLambdaMemoization` always uses the file short name and
@@ -157,7 +166,8 @@
     val filePath = file.virtualFile?.path ?: file.name
     val fileName = filePath.split('/').last()
     val shortName = PackagePartClassUtils.getFilePartShortName(fileName)
-    val fileClassFqName = runReadAction { JvmFileClassUtil.getFileClassInfoNoResolve(file) }.facadeClassFqName
+    val fileClassFqName =
+      runReadAction { JvmFileClassUtil.getFileClassInfoNoResolve(file) }.facadeClassFqName
     return "${fileClassFqName.parent().asString()}.ComposableSingletons\$$shortName"
   }
 }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ComposeStateNode.kt b/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ComposeStateNode.kt
index 05d8c00..df3001b 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ComposeStateNode.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ComposeStateNode.kt
@@ -26,9 +26,9 @@
 import kotlin.collections.Map.Entry
 
 /**
- *  A [XNamedValue] representing the recomposition state of the enclosing Composable function/lambda
+ * A [XNamedValue] representing the recomposition state of the enclosing Composable function/lambda
  *
- *  The node looks something like this:
+ * The node looks something like this:
  *
  *  ```
  *  + Recomposition State = Composable fun FunctionName(): Arguments: Different: ["arg1"] Same: ["arg2", "this"]
@@ -39,8 +39,9 @@
  *    + this = Same
  *      + value = <value of this>
  *  ```
- *  Which means, for this recomposition, the value `arg1` has changed from the last time the Composable was composed. `arg2` & `this` have
- *  not changed.
+ *
+ * Which means, for this recomposition, the value `arg1` has changed from the last time the
+ * Composable was composed. `arg2` & `this` have not changed.
  */
 internal class ComposeStateNode(
   private val evaluationContext: EvaluationContextImpl,
@@ -70,7 +71,8 @@
   }
 
   private fun getStateSummary(): String {
-    fun Entry<ParamState, List<StateObject>>.toSummary() = "${key.name}: [${value.joinToString { """"${it.name}"""" }}]"
+    fun Entry<ParamState, List<StateObject>>.toSummary() =
+      "${key.name}: [${value.joinToString { """"${it.name}"""" }}]"
 
     val summary = stateObjects.groupBy { it.state }.entries.joinToString { it.toSummary() }
     return ComposeBundle.message("recomposition.state.summary", summary)
diff --git a/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ComposeValueContributor.kt b/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ComposeValueContributor.kt
index c5a53f3..c1bf664 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ComposeValueContributor.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ComposeValueContributor.kt
@@ -36,6 +36,7 @@
 import com.intellij.xdebugger.frame.XNamedValue
 import com.sun.jdi.IntegerValue
 import com.sun.jdi.Location
+import java.util.concurrent.CancellationException
 import org.jetbrains.kotlin.idea.codeinsight.utils.findExistingEditor
 import org.jetbrains.kotlin.idea.debugger.core.stackFrame.KotlinStackFrame
 import org.jetbrains.kotlin.idea.debugger.core.stackFrame.KotlinStackFrameValueContributor
@@ -43,15 +44,12 @@
 import org.jetbrains.kotlin.psi.KtFunction
 import org.jetbrains.kotlin.psi.KtFunctionLiteral
 import org.jetbrains.kotlin.psi.KtNamedFunction
-import java.util.concurrent.CancellationException
 
 private const val COMPOSER_VAR = "\$composer"
 private const val CHANGED_VAR = "\$changed"
 private const val DIRTY_VAR = "\$dirty"
 
-/**
- * Contributes Compose specific information to the debugger variable view.
- */
+/** Contributes Compose specific information to the debugger variable view. */
 internal class ComposeValueContributor : KotlinStackFrameValueContributor {
   override fun contributeValues(
     frame: KotlinStackFrame,
@@ -87,7 +85,15 @@
       if (nodeManager == null) {
         thisLogger().warn("Unable to add $COMPOSER_VAR. nodeManager is null")
       } else {
-        values.add(JavaValue.create(null, LocalVariableDescriptorImpl(context.project, composer), context, nodeManager, false))
+        values.add(
+          JavaValue.create(
+            null,
+            LocalVariableDescriptorImpl(context.project, composer),
+            context,
+            nodeManager,
+            false
+          )
+        )
       }
     }
 
@@ -99,7 +105,8 @@
 
     val stateObjects = mutableListOf<StateObject>()
 
-    // ComposeValueContributor.contributeValues() is called with "variables == thisVariables + otherVariables" so if there is a "this"
+    // ComposeValueContributor.contributeValues() is called with "variables == thisVariables +
+    // otherVariables" so if there is a "this"
     // variable, it's going to be the first one.
     val firstParameter = variables.first()
     if (firstParameter.name() == "this") {
@@ -108,7 +115,8 @@
     }
 
     try {
-      val functionInfo = getFunctionInfo(context.debugProcess.positionManager, frame.stackFrameProxy.location())
+      val functionInfo =
+        getFunctionInfo(context.debugProcess.positionManager, frame.stackFrameProxy.location())
       // Named parameters
       functionInfo.parameters.zip(states.drop(stateObjects.size)).forEach { (param, state) ->
         stateObjects.add(Parameter(state, param, variableMap[param]))
@@ -119,8 +127,7 @@
         stateObjects.add(ThisObject(states[stateObjects.size]))
       }
       values.add(ComposeStateNode(context, forced, functionInfo.description, stateObjects))
-    }
-    catch (e: IllegalStateException) {
+    } catch (e: IllegalStateException) {
       thisLogger().error("Error fetching parameters for $frame", e)
       values.add(ErrorNode(ComposeBundle.message("recomposition.state.missing.parameters")))
     }
@@ -130,12 +137,20 @@
   /**
    * Finds the parameter names of a function.
    *
-   * Inspired by [org.jetbrains.kotlin.idea.debugger.coroutine.KotlinVariableNameFinder.findVariableNames].
+   * Inspired by
+   * [org.jetbrains.kotlin.idea.debugger.coroutine.KotlinVariableNameFinder.findVariableNames].
    */
-  private fun getFunctionInfo(positionManager: CompoundPositionManager, location: Location): FunctionInfo {
+  private fun getFunctionInfo(
+    positionManager: CompoundPositionManager,
+    location: Location
+  ): FunctionInfo {
     return runReadAction {
-      val element = positionManager.getSourcePosition(location)?.elementAt ?: throw IllegalStateException("Unable to get source position")
-      val function = element.parentOfType<KtFunction>(withSelf = true) ?: throw IllegalStateException("Unable to find KtFunction element")
+      val element =
+        positionManager.getSourcePosition(location)?.elementAt
+          ?: throw IllegalStateException("Unable to get source position")
+      val function =
+        element.parentOfType<KtFunction>(withSelf = true)
+          ?: throw IllegalStateException("Unable to find KtFunction element")
       val parameters = function.valueParameters.mapNotNull { it.name }
       FunctionInfo(getDescription(function), parameters)
     }
@@ -146,18 +161,28 @@
 
 private fun getDescription(function: KtFunction): String {
   return when (function) {
-    is KtFunctionLiteral -> ComposeBundle.message("recomposition.state.function.description.lambda", getLambdaName(function))
-    else -> ComposeBundle.message("recomposition.state.function.description.function", function.nameAsSafeName.asString())
+    is KtFunctionLiteral ->
+      ComposeBundle.message(
+        "recomposition.state.function.description.lambda",
+        getLambdaName(function)
+      )
+    else ->
+      ComposeBundle.message(
+        "recomposition.state.function.description.function",
+        function.nameAsSafeName.asString()
+      )
   }
 }
 
 /**
- * Search parent hierarchy for either a declaration of a composable function or a call to a composable function.
+ * Search parent hierarchy for either a declaration of a composable function or a call to a
+ * composable function.
  */
 private fun getLambdaName(lambda: KtFunctionLiteral): String {
   var element: PsiElement = lambda
   while (true) {
-    element = element.parentOfTypes(KtNamedFunction::class, KtCallExpression::class) ?: return "lambda"
+    element =
+      element.parentOfTypes(KtNamedFunction::class, KtCallExpression::class) ?: return "lambda"
     when {
       element is KtNamedFunction && element.isComposableFunction() -> return element.getLambdaName()
       element is KtCallExpression && element.isTargetComposable() -> return element.getLambdaName()
@@ -167,21 +192,33 @@
 
 private fun KtNamedFunction.getLambdaName() = "lambda@${nameAsSafeName.asString()}"
 
-private fun KtCallExpression.getLambdaName() = calleeExpression?.let { "lambda@${it.text}" } ?: "lambda"
+private fun KtCallExpression.getLambdaName() =
+  calleeExpression?.let { "lambda@${it.text}" } ?: "lambda"
 
 private fun KtCallExpression.isTargetComposable(): Boolean {
   val editor = findExistingEditor() ?: return false
-  val target = TargetElementUtil.getInstance().findTargetElement(editor, REFERENCED_ELEMENT_ACCEPTED, startOffset) ?: return false
+  val target =
+    TargetElementUtil.getInstance()
+      .findTargetElement(editor, REFERENCED_ELEMENT_ACCEPTED, startOffset)
+      ?: return false
   return target.isComposableFunction()
 }
 
-private fun getParamStates(frame: KotlinStackFrame, variables: List<LocalVariableProxyImpl>): List<ParamState> {
-  val vars = (variables.filterByPrefix(DIRTY_VAR).takeIf { it.isNotEmpty() } ?: variables.filterByPrefix(CHANGED_VAR))
+private fun getParamStates(
+  frame: KotlinStackFrame,
+  variables: List<LocalVariableProxyImpl>
+): List<ParamState> {
+  val vars =
+    (variables.filterByPrefix(DIRTY_VAR).takeIf { it.isNotEmpty() }
+      ?: variables.filterByPrefix(CHANGED_VAR))
   return ParamState.decode(vars.map { it.intValue(frame) })
 }
 
-private fun LocalVariableProxyImpl.intValue(frame: KotlinStackFrame) = (frame.stackFrameProxy.getValue(this) as IntegerValue).value()
+private fun LocalVariableProxyImpl.intValue(frame: KotlinStackFrame) =
+  (frame.stackFrameProxy.getValue(this) as IntegerValue).value()
 
-private fun List<LocalVariableProxyImpl>.filterByPrefix(prefix: String) = filter { it.name().startsWith(prefix) }.sortedBy { it.name() }
+private fun List<LocalVariableProxyImpl>.filterByPrefix(prefix: String) =
+  filter { it.name().startsWith(prefix) }.sortedBy { it.name() }
 
-private fun KotlinStackFrame.findComposer() = stackFrameProxy.visibleVariables().find { it.name() == COMPOSER_VAR }
+private fun KotlinStackFrame.findComposer() =
+  stackFrameProxy.visibleVariables().find { it.name() == COMPOSER_VAR }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ErrorNode.kt b/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ErrorNode.kt
index ee9dd23..f368566 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ErrorNode.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ErrorNode.kt
@@ -21,10 +21,9 @@
 import com.intellij.xdebugger.frame.XValueNode
 import com.intellij.xdebugger.frame.XValuePlace
 
-/**
- *  A [XNamedValue] shown instead of a [ComposeStateNode] when some error has occurred
- */
-internal class ErrorNode(val errorText: String) : XNamedValue(ComposeBundle.message("recomposition.state.label")) {
+/** A [XNamedValue] shown instead of a [ComposeStateNode] when some error has occurred */
+internal class ErrorNode(val errorText: String) :
+  XNamedValue(ComposeBundle.message("recomposition.state.label")) {
   override fun computePresentation(node: XValueNode, place: XValuePlace) {
     node.setPresentation(AllIcons.General.Error, null, errorText, false)
   }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ParamState.kt b/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ParamState.kt
index 62cb5fc..9059757 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ParamState.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ParamState.kt
@@ -19,32 +19,29 @@
 
 private const val SLOTS_PER_INT = 10
 
-/**
- * Based on [androidx.compose.compiler.plugins.kotlin.lower.ParamState]
- */
+/** Based on [androidx.compose.compiler.plugins.kotlin.lower.ParamState] */
 internal enum class ParamState(private val nameResource: String, private val bits: Int) {
   /**
    * Indicates that nothing is certain about the current state of the parameter. It could be
-   * different from it was during the last execution, or it could be the same, but it is not
-   * known so the current function looking at it must call equals on it in order to find out.
-   * This is the only state that can cause the function to spend slot table space in order to
-   * look at it.
+   * different from it was during the last execution, or it could be the same, but it is not known
+   * so the current function looking at it must call equals on it in order to find out. This is the
+   * only state that can cause the function to spend slot table space in order to look at it.
    */
   Uncertain("recomposition.state.uncertain", 0b000),
 
   /**
    * This indicates that the value is known to be the same since the last time the function was
    * executed. There is no need to store the value in the slot table in this case because the
-   * calling function will *always* know whether the value was the same or different as it was
-   * in the previous execution.
+   * calling function will *always* know whether the value was the same or different as it was in
+   * the previous execution.
    */
   Same("recomposition.state.same", 0b001),
 
   /**
-   * This indicates that the value is known to be different since the last time the function
-   * was executed. There is no need to store the value in the slot table in this case because
-   * the calling function will *always* know whether the value was the same or different as it
-   * was in the previous execution.
+   * This indicates that the value is known to be different since the last time the function was
+   * executed. There is no need to store the value in the slot table in this case because the
+   * calling function will *always* know whether the value was the same or different as it was in
+   * the previous execution.
    */
   Different("recomposition.state.different", 0b010),
 
@@ -54,9 +51,7 @@
    */
   Static("recomposition.state.static", 0b011),
 
-  /**
-   * If the msb is set, it is unstable. Lower bits are ignored.
-   */
+  /** If the msb is set, it is unstable. Lower bits are ignored. */
   Unstable100("recomposition.state.unstable", 0b100),
   Unstable101("recomposition.state.unstable", 0b101),
   Unstable110("recomposition.state.unstable", 0b110),
@@ -68,9 +63,7 @@
   companion object {
     private val STATES = ParamState.values().sortedBy { it.bits }
 
-    /**
-     * Returns the decoded param states of [values].
-     */
+    /** Returns the decoded param states of [values]. */
     fun decode(values: List<Int>): List<ParamState> {
       val states = mutableListOf<ParamState>()
       values.forEach {
diff --git a/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ParameterNode.kt b/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ParameterNode.kt
index 2633980..8203b6e 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ParameterNode.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ParameterNode.kt
@@ -36,7 +36,8 @@
   private val state: ParamState,
 ) : XNamedValue(name) {
   // Create the child node early because we are known to be on the correct thread.
-  private val valueNode = if (param != null) createValueNode(param) else createOptimizedOutNode(name)
+  private val valueNode =
+    if (param != null) createValueNode(param) else createOptimizedOutNode(name)
 
   override fun computePresentation(node: XValueNode, place: XValuePlace) {
     node.setPresentation(AllIcons.Nodes.Parameter, null, state.getDisplayName(), true)
@@ -47,15 +48,19 @@
   }
 
   private fun createValueNode(param: LocalVariableProxyImpl): JavaValue {
-    val nodeManager = context.debugProcess.xdebugProcess?.nodeManager ?: throw IllegalStateException("Missing node manager")
-    val descriptor = object : LocalVariableDescriptorImpl(context.project, param) {
-      override fun getName() = ComposeBundle.message("recomposition.state.value")
-    }
+    val nodeManager =
+      context.debugProcess.xdebugProcess?.nodeManager
+        ?: throw IllegalStateException("Missing node manager")
+    val descriptor =
+      object : LocalVariableDescriptorImpl(context.project, param) {
+        override fun getName() = ComposeBundle.message("recomposition.state.value")
+      }
     return JavaValue.create(null, descriptor, context, nodeManager, false)
   }
 }
 
-private fun createOptimizedOutNode(name: String): XNamedValue = JavaStackFrame.createMessageNode(
-  ComposeBundle.message("recomposition.optimised.variable.message", "\'$name\'"),
-  AllIcons.General.Information
-)
+private fun createOptimizedOutNode(name: String): XNamedValue =
+  JavaStackFrame.createMessageNode(
+    ComposeBundle.message("recomposition.optimised.variable.message", "\'$name\'"),
+    AllIcons.General.Information
+  )
diff --git a/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/StateObject.kt b/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/StateObject.kt
index 82f0bad..b8e51e9 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/StateObject.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/StateObject.kt
@@ -22,17 +22,21 @@
 /**
  * Represents an object whose state is reported in the `$changed/$dirty` state vector.
  *
- * There are 2 types of objects, parameters (including an extension receiver) and a `this` pointer. A [StateObject] can be converted into an
- * [XNamedValue] which can then be added to the [ComposeStateNode].
+ * There are 2 types of objects, parameters (including an extension receiver) and a `this` pointer.
+ * A [StateObject] can be converted into an [XNamedValue] which can then be added to the
+ * [ComposeStateNode].
  */
 internal sealed class StateObject(val state: ParamState, val name: String) {
   abstract fun toXValue(context: EvaluationContextImpl): XNamedValue
 
-  class Parameter(state: ParamState, name: String, val param: LocalVariableProxyImpl?) : StateObject(state, name) {
-    override fun toXValue(context: EvaluationContextImpl): XNamedValue = ParameterNode(context, name, param, state)
+  class Parameter(state: ParamState, name: String, val param: LocalVariableProxyImpl?) :
+    StateObject(state, name) {
+    override fun toXValue(context: EvaluationContextImpl): XNamedValue =
+      ParameterNode(context, name, param, state)
   }
 
   class ThisObject(state: ParamState) : StateObject(state, "this") {
-    override fun toXValue(context: EvaluationContextImpl): XNamedValue = ThisObjectNode(context, state)
+    override fun toXValue(context: EvaluationContextImpl): XNamedValue =
+      ThisObjectNode(context, state)
   }
 }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ThisObjectNode.kt b/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ThisObjectNode.kt
index 2a2e2c1..ee02595 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ThisObjectNode.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/debug/recomposition/ThisObjectNode.kt
@@ -42,10 +42,13 @@
   }
 
   private fun createValueNode(): JavaValue {
-    val nodeManager = context.debugProcess.xdebugProcess?.nodeManager ?: throw IllegalStateException("Missing node manager")
-    val descriptor = object : ThisDescriptorImpl(context.project) {
-      override fun getName() = ComposeBundle.message("recomposition.state.value")
-    }
+    val nodeManager =
+      context.debugProcess.xdebugProcess?.nodeManager
+        ?: throw IllegalStateException("Missing node manager")
+    val descriptor =
+      object : ThisDescriptorImpl(context.project) {
+        override fun getName() = ComposeBundle.message("recomposition.state.value")
+      }
     return JavaValue.create(null, descriptor, context, nodeManager, false)
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/debug/render/ComposeStateObjectClassRenderer.kt b/compose-ide-plugin/src/com/android/tools/compose/debug/render/ComposeStateObjectClassRenderer.kt
index c8e4285..01ee360 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/debug/render/ComposeStateObjectClassRenderer.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/debug/render/ComposeStateObjectClassRenderer.kt
@@ -46,34 +46,35 @@
 import com.sun.jdi.ClassType
 import com.sun.jdi.Type
 import com.sun.jdi.Value
+import java.util.concurrent.CompletableFuture
 import org.jetbrains.kotlin.idea.debugger.KotlinClassRenderer
 import org.jetbrains.kotlin.idea.debugger.isInKotlinSources
-import java.util.concurrent.CompletableFuture
 
 /**
  * Renderer for a given compose `StateObject` type object.
  *
- * Basically, for a given compose state object, its underlying value (by invoking [DEBUGGER_DISPLAY_VALUE_METHOD_NAME])
- * determines how it's rendered in the "Variables" pane. This is to provide an auto-unboxing experience while debugging,
- * that users can identify the data by a glance at this more readable data view.
+ * Basically, for a given compose state object, its underlying value (by invoking
+ * [DEBUGGER_DISPLAY_VALUE_METHOD_NAME]) determines how it's rendered in the "Variables" pane. This
+ * is to provide an auto-unboxing experience while debugging, that users can identify the data by a
+ * glance at this more readable data view.
  *
  * E.g.
  * 1) if the underlying value is an integer `1`, the label is rendered `1`.
- * 2) if the underlying value is a list, then the given object is rendered by a `List` renderer instead of the
- * original `Kotlin class` renderer. That is, "size = xx" is the label, and the `ArrayRenderer` is the children renderer
- * in this case.
- * 3) if the underlying value is a map, then the given object is rendered by a `Map` renderer instead of the original
- * `Kotlin class` renderer. That is, "size = xx" is the label, and the `ArrayRenderer` is the children renderer in
- * this case. When expanding, each of the entry is rendered by the `Map.Entry` renderer.
+ * 2) if the underlying value is a list, then the given object is rendered by a `List` renderer
+ *    instead of the original `Kotlin class` renderer. That is, "size = xx" is the label, and the
+ *    `ArrayRenderer` is the children renderer in this case.
+ * 3) if the underlying value is a map, then the given object is rendered by a `Map` renderer
+ *    instead of the original `Kotlin class` renderer. That is, "size = xx" is the label, and the
+ *    `ArrayRenderer` is the children renderer in this case. When expanding, each of the entry is
+ *    rendered by the `Map.Entry` renderer.
  *
- * @param fqcn the fully qualified class name of the Compose State Object to apply this custom renderer to.
+ * @param fqcn the fully qualified class name of the Compose State Object to apply this custom
+ *   renderer to.
  */
 class ComposeStateObjectClassRenderer(private val fqcn: String) : ClassRenderer() {
   // We fallback to [KotlinClassRenderer] when the following exception is thrown:
   // Unable to evaluate the expression No such instance method: 'getDebuggerDisplayValue',
-  private val fallbackRenderer by lazy {
-    KotlinClassRenderer()
-  }
+  private val fallbackRenderer by lazy { KotlinClassRenderer() }
 
   private val prioritizedCollectionRenderers by lazy {
     NodeRendererSettings.getInstance()
@@ -87,7 +88,8 @@
 
   init {
     setIsApplicableChecker { type: Type? ->
-      if (type !is ClassType || !type.isInKotlinSources()) return@setIsApplicableChecker CompletableFuture.completedFuture(false)
+      if (type !is ClassType || !type.isInKotlinSources())
+        return@setIsApplicableChecker CompletableFuture.completedFuture(false)
 
       DebuggerUtilsAsync.instanceOf(type, fqcn)
     }
@@ -96,22 +98,27 @@
   companion object {
     private val NODE_RENDERER_KEY = Key.create<NodeRenderer>(this::class.java.simpleName)
 
-    // The name of the method we expect the Compose State Object to implement. We invoke it to retrieve the underlying
+    // The name of the method we expect the Compose State Object to implement. We invoke it to
+    // retrieve the underlying
     // Compose State Object value.
     private const val DEBUGGER_DISPLAY_VALUE_METHOD_NAME = "getDebuggerDisplayValue"
   }
 
-  override fun buildChildren(value: Value, builder: ChildrenBuilder, evaluationContext: EvaluationContext) {
-    val debuggerDisplayValueDescriptor = try {
-      getDebuggerDisplayValueDescriptor(value, evaluationContext, null)
-    }
-    catch (evaluateException: EvaluateException) {
-      if (evaluateException.localizedMessage.startsWith("No such instance method:")) {
-        return fallbackRenderer.buildChildren(value, builder, evaluationContext)
-      }
+  override fun buildChildren(
+    value: Value,
+    builder: ChildrenBuilder,
+    evaluationContext: EvaluationContext
+  ) {
+    val debuggerDisplayValueDescriptor =
+      try {
+        getDebuggerDisplayValueDescriptor(value, evaluationContext, null)
+      } catch (evaluateException: EvaluateException) {
+        if (evaluateException.localizedMessage.startsWith("No such instance method:")) {
+          return fallbackRenderer.buildChildren(value, builder, evaluationContext)
+        }
 
-      throw evaluateException
-    }
+        throw evaluateException
+      }
 
     getDelegatedRendererAsync(evaluationContext.debugProcess, debuggerDisplayValueDescriptor)
       .thenAccept { renderer ->
@@ -120,8 +127,13 @@
       }
   }
 
-  override fun getChildValueExpression(node: DebuggerTreeNode, context: DebuggerContext): PsiElement? {
-    return node.parent.descriptor.getUserData(NODE_RENDERER_KEY)?.getChildValueExpression(node, context)
+  override fun getChildValueExpression(
+    node: DebuggerTreeNode,
+    context: DebuggerContext
+  ): PsiElement? {
+    return node.parent.descriptor
+      .getUserData(NODE_RENDERER_KEY)
+      ?.getChildValueExpression(node, context)
   }
 
   override fun isExpandableAsync(
@@ -129,26 +141,31 @@
     evaluationContext: EvaluationContext,
     parentDescriptor: NodeDescriptor
   ): CompletableFuture<Boolean> {
-    val debuggerDisplayValueDescriptor = try {
-      getDebuggerDisplayValueDescriptor(value, evaluationContext, null)
-    }
-    catch (evaluateException: EvaluateException) {
-      if (evaluateException.localizedMessage.startsWith("No such instance method:")) {
-        return fallbackRenderer.isExpandableAsync(value, evaluationContext, parentDescriptor)
-      }
+    val debuggerDisplayValueDescriptor =
+      try {
+        getDebuggerDisplayValueDescriptor(value, evaluationContext, null)
+      } catch (evaluateException: EvaluateException) {
+        if (evaluateException.localizedMessage.startsWith("No such instance method:")) {
+          return fallbackRenderer.isExpandableAsync(value, evaluationContext, parentDescriptor)
+        }
 
-      return CompletableFuture.failedFuture(evaluateException)
-    }
+        return CompletableFuture.failedFuture(evaluateException)
+      }
 
     return getDelegatedRendererAsync(evaluationContext.debugProcess, debuggerDisplayValueDescriptor)
       .thenCompose { renderer ->
-        renderer.isExpandableAsync(debuggerDisplayValueDescriptor.value, evaluationContext, debuggerDisplayValueDescriptor)
+        renderer.isExpandableAsync(
+          debuggerDisplayValueDescriptor.value,
+          evaluationContext,
+          debuggerDisplayValueDescriptor
+        )
       }
   }
 
   /**
-   * Returns a [ValueDescriptor] for the underlying "debugger display value", which is evaluated by invoking the
-   * [DEBUGGER_DISPLAY_VALUE_METHOD_NAME] method of the Compose `StateObject` type object: [value].
+   * Returns a [ValueDescriptor] for the underlying "debugger display value", which is evaluated by
+   * invoking the [DEBUGGER_DISPLAY_VALUE_METHOD_NAME] method of the Compose `StateObject` type
+   * object: [value].
    */
   private fun getDebuggerDisplayValueDescriptor(
     value: Value,
@@ -160,11 +177,13 @@
     if (!debugProcess.isAttached) throw EvaluateExceptionUtil.PROCESS_EXITED
 
     val thisEvaluationContext = evaluationContext.createEvaluationContext(value)
-    val debuggerDisplayValue = debuggerDisplayValueEvaluator.evaluate(debugProcess.project, thisEvaluationContext)
+    val debuggerDisplayValue =
+      debuggerDisplayValueEvaluator.evaluate(debugProcess.project, thisEvaluationContext)
 
     return object : ValueDescriptorImpl(evaluationContext.project, debuggerDisplayValue) {
       override fun getDescriptorEvaluation(context: DebuggerContext): PsiExpression? = null
-      override fun calcValue(evaluationContext: EvaluationContextImpl?): Value = debuggerDisplayValue
+      override fun calcValue(evaluationContext: EvaluationContextImpl?): Value =
+        debuggerDisplayValue
       override fun calcValueName(): String = "value"
 
       override fun setValueLabel(label: String) {
@@ -174,26 +193,31 @@
   }
 
   /**
-   * Return an ID of this renderer class, used by the IntelliJ platform to identify our renderer among all active
-   * renderers in the system.
+   * Return an ID of this renderer class, used by the IntelliJ platform to identify our renderer
+   * among all active renderers in the system.
    */
   override fun getUniqueId(): String {
     return fqcn
   }
 
-  override fun calcLabel(descriptor: ValueDescriptor, evaluationContext: EvaluationContext, listener: DescriptorLabelListener): String {
-    val debuggerDisplayValueDescriptor: ValueDescriptor = try {
-      getDebuggerDisplayValueDescriptor(descriptor.value, evaluationContext, descriptor)
-    }
-    catch (evaluateException: EvaluateException) {
-      if (evaluateException.localizedMessage.startsWith("No such instance method:")) {
-        return fallbackRenderer.calcLabel(descriptor, evaluationContext, listener)
+  override fun calcLabel(
+    descriptor: ValueDescriptor,
+    evaluationContext: EvaluationContext,
+    listener: DescriptorLabelListener
+  ): String {
+    val debuggerDisplayValueDescriptor: ValueDescriptor =
+      try {
+        getDebuggerDisplayValueDescriptor(descriptor.value, evaluationContext, descriptor)
+      } catch (evaluateException: EvaluateException) {
+        if (evaluateException.localizedMessage.startsWith("No such instance method:")) {
+          return fallbackRenderer.calcLabel(descriptor, evaluationContext, listener)
+        }
+
+        throw evaluateException
       }
 
-      throw evaluateException
-    }
-
-    val renderer = getDelegatedRendererAsync(evaluationContext.debugProcess, debuggerDisplayValueDescriptor)
+    val renderer =
+      getDelegatedRendererAsync(evaluationContext.debugProcess, debuggerDisplayValueDescriptor)
     return calcLabelAsync(renderer, debuggerDisplayValueDescriptor, evaluationContext, listener)
       .getNow(XDebuggerUIConstants.getCollectingDataMessage())
   }
@@ -210,8 +234,7 @@
         descriptor.setValueLabel(label)
         listener.labelChanged()
         return@thenApply label
-      }
-      catch (evaluateException: EvaluateException) {
+      } catch (evaluateException: EvaluateException) {
         descriptor.setValueLabelFailed(evaluateException)
         listener.labelChanged()
         return@thenApply ""
@@ -222,29 +245,34 @@
   /**
    * Returns a [CompletableFuture] of the first applicable renderer for the given [valueDescriptor].
    */
-  private fun getDelegatedRendererAsync(debugProcess: DebugProcess, valueDescriptor: ValueDescriptor): CompletableFuture<NodeRenderer> {
+  private fun getDelegatedRendererAsync(
+    debugProcess: DebugProcess,
+    valueDescriptor: ValueDescriptor
+  ): CompletableFuture<NodeRenderer> {
     val type = valueDescriptor.type
     return DebuggerUtilsImpl.getApplicableRenderers(prioritizedCollectionRenderers, type)
       .thenCompose { renderers ->
-        // Return any applicable renderer of [prioritizedCollectionRenderers]. This is to de-prioritize `Kotlin class` renderer.
+        // Return any applicable renderer of [prioritizedCollectionRenderers]. This is to
+        // de-prioritize `Kotlin class` renderer.
         // Or fallback to the default renderer.
-        val found = renderers.firstOrNull() ?: return@thenCompose (debugProcess as DebugProcessImpl).getAutoRendererAsync(type)
+        val found =
+          renderers.firstOrNull()
+            ?: return@thenCompose (debugProcess as DebugProcessImpl).getAutoRendererAsync(type)
 
         CompletableFuture.completedFuture(found)
       }
   }
 
-  /**
-   * [CachedEvaluator] used to invoke the [DEBUGGER_DISPLAY_VALUE_METHOD_NAME] method.
-   */
+  /** [CachedEvaluator] used to invoke the [DEBUGGER_DISPLAY_VALUE_METHOD_NAME] method. */
   private class DebuggerDisplayValueEvaluator(private val fqcn: String) : CachedEvaluator() {
     init {
-      referenceExpression = TextWithImportsImpl(
-        CodeFragmentKind.EXPRESSION,
-        "this.$DEBUGGER_DISPLAY_VALUE_METHOD_NAME()",
-        "",
-        JavaFileType.INSTANCE
-      )
+      referenceExpression =
+        TextWithImportsImpl(
+          CodeFragmentKind.EXPRESSION,
+          "this.$DEBUGGER_DISPLAY_VALUE_METHOD_NAME()",
+          "",
+          JavaFileType.INSTANCE
+        )
     }
 
     override fun getClassName(): String {
@@ -255,4 +283,4 @@
       return getEvaluator(project).evaluate(context)
     }
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/debug/render/ComposeStateObjectRendererProviderBase.kt b/compose-ide-plugin/src/com/android/tools/compose/debug/render/ComposeStateObjectRendererProviderBase.kt
index af2ff5d..975e3c7 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/debug/render/ComposeStateObjectRendererProviderBase.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/debug/render/ComposeStateObjectRendererProviderBase.kt
@@ -25,16 +25,16 @@
 /**
  * Base custom renderer provider for rendering a given compose `StateObject` type object.
  *
- * [stateObjectClassRenderer] is the actual underlying renderer for the label and the children nodes. Users can select
- * the provided renderer by [rendererName] if applicable.
+ * [stateObjectClassRenderer] is the actual underlying renderer for the label and the children
+ * nodes. Users can select the provided renderer by [rendererName] if applicable.
  *
- * @param fqcn the fully qualified class name of the Compose State Object to apply the underlying custom renderer to.
+ * @param fqcn the fully qualified class name of the Compose State Object to apply the underlying
+ *   custom renderer to.
  */
-sealed class ComposeStateObjectRendererProviderBase(private val fqcn: String) : CompoundRendererProvider() {
+sealed class ComposeStateObjectRendererProviderBase(private val fqcn: String) :
+  CompoundRendererProvider() {
   private val rendererName = "Compose State Object"
-  private val stateObjectClassRenderer by lazy {
-    ComposeStateObjectClassRenderer(fqcn)
-  }
+  private val stateObjectClassRenderer by lazy { ComposeStateObjectClassRenderer(fqcn) }
 
   override fun getName(): String {
     return rendererName
@@ -43,9 +43,7 @@
   override fun isEnabled() = true
 
   override fun getIsApplicableChecker(): Function<Type?, CompletableFuture<Boolean>> {
-    return Function { type: Type? ->
-      stateObjectClassRenderer.isApplicableAsync(type)
-    }
+    return Function { type: Type? -> stateObjectClassRenderer.isApplicableAsync(type) }
   }
 
   override fun getValueLabelRenderer(): ValueLabelRenderer {
@@ -57,18 +55,14 @@
   }
 }
 
-class SnapshotMutableStateImplRendererProvider : ComposeStateObjectRendererProviderBase(
-  "androidx.compose.runtime.SnapshotMutableStateImpl"
-)
+class SnapshotMutableStateImplRendererProvider :
+  ComposeStateObjectRendererProviderBase("androidx.compose.runtime.SnapshotMutableStateImpl")
 
-class DerivedSnapshotStateRendererProvider : ComposeStateObjectRendererProviderBase(
-  "androidx.compose.runtime.DerivedSnapshotState"
-)
+class DerivedSnapshotStateRendererProvider :
+  ComposeStateObjectRendererProviderBase("androidx.compose.runtime.DerivedSnapshotState")
 
-class ComposeStateObjectListRendererProvider : ComposeStateObjectRendererProviderBase(
-  "androidx.compose.runtime.snapshots.SnapshotStateList"
-)
+class ComposeStateObjectListRendererProvider :
+  ComposeStateObjectRendererProviderBase("androidx.compose.runtime.snapshots.SnapshotStateList")
 
-class ComposeStateObjectMapRendererProvider : ComposeStateObjectRendererProviderBase(
-  "androidx.compose.runtime.snapshots.SnapshotStateMap"
-)
\ No newline at end of file
+class ComposeStateObjectMapRendererProvider :
+  ComposeStateObjectRendererProviderBase("androidx.compose.runtime.snapshots.SnapshotStateMap")
diff --git a/compose-ide-plugin/src/com/android/tools/compose/debug/render/KotlinMapEntryRenderer.kt b/compose-ide-plugin/src/com/android/tools/compose/debug/render/KotlinMapEntryRenderer.kt
index 18347e3..b790007 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/debug/render/KotlinMapEntryRenderer.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/debug/render/KotlinMapEntryRenderer.kt
@@ -23,22 +23,21 @@
 import com.intellij.debugger.ui.tree.render.ValueLabelRenderer
 import com.sun.jdi.ClassType
 import com.sun.jdi.Type
-import org.jetbrains.kotlin.idea.debugger.isInKotlinSources
 import java.util.concurrent.CompletableFuture
 import java.util.function.Function
+import org.jetbrains.kotlin.idea.debugger.isInKotlinSources
 
 /**
  * Custom renderer for "MapEntry" type objects.
  *
- * This is to precede the `Kotlin class` renderer, as [KotlinMapEntryRenderer] provides a more readable data view,
- * that the underlying `Map.Entry` renderer does the real work.
+ * This is to precede the `Kotlin class` renderer, as [KotlinMapEntryRenderer] provides a more
+ * readable data view, that the underlying `Map.Entry` renderer does the real work.
  */
 class KotlinMapEntryRenderer : CompoundRendererProvider() {
   private val MAP_ENTRY_FQCN = "java.util.Map\$Entry"
 
-  private val mapEntryLabelRender = NodeRendererSettings.getInstance().alternateCollectionRenderers.find {
-    it.name == "Map.Entry"
-  }
+  private val mapEntryLabelRender =
+    NodeRendererSettings.getInstance().alternateCollectionRenderers.find { it.name == "Map.Entry" }
 
   override fun isEnabled() = true
 
@@ -48,7 +47,8 @@
 
   override fun getIsApplicableChecker(): Function<Type?, CompletableFuture<Boolean>> {
     return Function { type: Type? ->
-      if (type !is ClassType || !type.isInKotlinSources()) return@Function CompletableFuture.completedFuture(false)
+      if (type !is ClassType || !type.isInKotlinSources())
+        return@Function CompletableFuture.completedFuture(false)
 
       DebuggerUtilsAsync.instanceOf(type, MAP_ENTRY_FQCN)
     }
@@ -59,6 +59,8 @@
   }
 
   override fun getChildrenRenderer(): ChildrenRenderer {
-    return NodeRendererSettings.createEnumerationChildrenRenderer(arrayOf(arrayOf("key", "getKey()"), arrayOf("value", "getValue()")))
+    return NodeRendererSettings.createEnumerationChildrenRenderer(
+      arrayOf(arrayOf("key", "getKey()"), arrayOf("value", "getValue()"))
+    )
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/formatting/ComposePostFormatProcessor.kt b/compose-ide-plugin/src/com/android/tools/compose/formatting/ComposePostFormatProcessor.kt
index eed507b..4160808 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/formatting/ComposePostFormatProcessor.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/formatting/ComposePostFormatProcessor.kt
@@ -35,24 +35,33 @@
 import org.jetbrains.kotlin.psi.KtTreeVisitorVoid
 
 /**
- * Runs after explicit code formatting invocation and for Modifier(androidx.compose.ui.Modifier) chain that is two modifiers or longer,
- * splits it in one modifier per line.
+ * Runs after explicit code formatting invocation and for Modifier(androidx.compose.ui.Modifier)
+ * chain that is two modifiers or longer, splits it in one modifier per line.
  */
 class ComposePostFormatProcessor : PostFormatProcessor {
 
   private fun isAvailable(psiElement: PsiElement, settings: CodeStyleSettings): Boolean {
     return psiElement.containingFile is KtFile &&
-           isComposeEnabled(psiElement) &&
-           !DumbService.isDumb(psiElement.project) &&
-           settings.getCustomSettings(ComposeCustomCodeStyleSettings::class.java).USE_CUSTOM_FORMATTING_FOR_MODIFIERS
+      isComposeEnabled(psiElement) &&
+      !DumbService.isDumb(psiElement.project) &&
+      settings
+        .getCustomSettings(ComposeCustomCodeStyleSettings::class.java)
+        .USE_CUSTOM_FORMATTING_FOR_MODIFIERS
   }
 
   override fun processElement(source: PsiElement, settings: CodeStyleSettings): PsiElement {
-    return if (isAvailable(source, settings)) ComposeModifierProcessor(settings).process(source) else source
+    return if (isAvailable(source, settings)) ComposeModifierProcessor(settings).process(source)
+    else source
   }
 
-  override fun processText(source: PsiFile, rangeToReformat: TextRange, settings: CodeStyleSettings): TextRange {
-    return if (isAvailable(source, settings)) ComposeModifierProcessor(settings).processText(source, rangeToReformat) else rangeToReformat
+  override fun processText(
+    source: PsiFile,
+    rangeToReformat: TextRange,
+    settings: CodeStyleSettings
+  ): TextRange {
+    return if (isAvailable(source, settings))
+      ComposeModifierProcessor(settings).processText(source, rangeToReformat)
+    else rangeToReformat
   }
 }
 
@@ -77,10 +86,7 @@
     return formatted
   }
 
-  fun processText(
-    source: PsiFile,
-    rangeToReformat: TextRange
-  ): TextRange {
+  fun processText(source: PsiFile, rangeToReformat: TextRange): TextRange {
     myPostProcessor.resultTextRange = rangeToReformat
     source.accept(this)
     return myPostProcessor.resultTextRange
@@ -88,25 +94,22 @@
 }
 
 /**
- * Returns true if it's Modifier(androidx.compose.ui.Modifier) chain that is two modifiers or longer.
+ * Returns true if it's Modifier(androidx.compose.ui.Modifier) chain that is two modifiers or
+ * longer.
  */
 private fun isModifierChainThatNeedToBeWrapped(element: KtElement): Boolean {
-  // Take very top KtDotQualifiedExpression, e.g for `Modifier.adjust1().adjust2()` take whole expression, not only `Modifier.adjust1()`.
+  // Take very top KtDotQualifiedExpression, e.g for `Modifier.adjust1().adjust2()` take whole
+  // expression, not only `Modifier.adjust1()`.
   return element is KtDotQualifiedExpression &&
-         element.parent !is KtDotQualifiedExpression &&
-         isModifierChainLongerThanTwo(element)
+    element.parent !is KtDotQualifiedExpression &&
+    isModifierChainLongerThanTwo(element)
 }
 
-/**
- * Splits KtDotQualifiedExpression it one call per line.
- */
+/** Splits KtDotQualifiedExpression it one call per line. */
 internal fun wrapModifierChain(element: KtDotQualifiedExpression, settings: CodeStyleSettings) {
-  CodeStyle.doWithTemporarySettings(
-    element.project,
-    settings
-  ) { tempSettings: CodeStyleSettings ->
+  CodeStyle.doWithTemporarySettings(element.project, settings) { tempSettings: CodeStyleSettings ->
     tempSettings.kotlinCommonSettings.METHOD_CALL_CHAIN_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS
     tempSettings.kotlinCommonSettings.WRAP_FIRST_METHOD_IN_CALL_CHAIN = true
     CodeFormatterFacade(tempSettings, element.language).processElement(element.node)
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/intentions/AddComposableToFunctionQuickFix.kt b/compose-ide-plugin/src/com/android/tools/compose/intentions/AddComposableToFunctionQuickFix.kt
index 4e0e196..2b34383 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/intentions/AddComposableToFunctionQuickFix.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/intentions/AddComposableToFunctionQuickFix.kt
@@ -15,20 +15,22 @@
  */
 package com.android.tools.compose.intentions
 
+import androidx.compose.compiler.plugins.kotlin.ComposeClassIds
 import androidx.compose.compiler.plugins.kotlin.k1.ComposeErrors
-import com.android.tools.compose.COMPOSABLE_ANNOTATION_FQ_NAME
 import com.android.tools.compose.ComposeBundle
 import com.intellij.codeInsight.intention.IntentionAction
 import com.intellij.openapi.editor.Editor
 import com.intellij.openapi.project.Project
 import com.intellij.psi.PsiElement
+import org.jetbrains.kotlin.analysis.api.fir.diagnostics.KtCompilerPluginDiagnostic0
 import org.jetbrains.kotlin.diagnostics.Diagnostic
+import org.jetbrains.kotlin.idea.codeinsight.api.applicators.fixes.KotlinDiagnosticFixFactory
+import org.jetbrains.kotlin.idea.codeinsight.api.applicators.fixes.diagnosticFixFactory
 import org.jetbrains.kotlin.idea.codeinsight.api.classic.quickfixes.KotlinQuickFixAction
 import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
 import org.jetbrains.kotlin.idea.quickfix.QuickFixContributor
 import org.jetbrains.kotlin.idea.quickfix.QuickFixes
 import org.jetbrains.kotlin.idea.util.addAnnotation
-import org.jetbrains.kotlin.name.FqName
 import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
 import org.jetbrains.kotlin.psi.KtClass
 import org.jetbrains.kotlin.psi.KtElement
@@ -46,7 +48,6 @@
  * Quick fix addressing @Composable function invocations from non-@Composable functions.
  *
  * As an example:
- *
  * ```kotlin
  * @Composable
  * fun ComposableFunction() {}
@@ -56,56 +57,78 @@
  * }
  * ```
  *
- * The call to `ComposableFunction()` within `NonComposableFunction` is not allowed. Both the invocation `ComposableFunction()` and the
- * function declaration `NonComposableFunction` will have an error.
+ * The call to `ComposableFunction()` within `NonComposableFunction` is not allowed. Both the
+ * invocation `ComposableFunction()` and the function declaration `NonComposableFunction` will have
+ * an error.
  *
- * This quick fix appears on both errors, and offers to add `@Composable` to `NonComposableFunction`.
+ * This quick fix appears on both errors, and offers to add `@Composable` to
+ * `NonComposableFunction`.
  */
-class AddComposableToFunctionQuickFix private constructor(element: KtModifierListOwner, private val displayName: String)
-  : KotlinQuickFixAction<KtModifierListOwner>(element) {
+class AddComposableToFunctionQuickFix
+private constructor(element: KtModifierListOwner, private val displayName: String) :
+  KotlinQuickFixAction<KtModifierListOwner>(element) {
 
   override fun getFamilyName(): String = ComposeBundle.message("add.composable.to.function")
 
-  override fun getText(): String = ComposeBundle.message("add.composable.to.function.with.name", displayName)
+  override fun getText(): String =
+    ComposeBundle.message("add.composable.to.function.with.name", displayName)
 
   override fun invoke(project: Project, editor: Editor?, file: KtFile) {
-    element?.addAnnotation(FqName(COMPOSABLE_ANNOTATION_FQ_NAME))
+    element?.addAnnotation(ComposeClassIds.Composable)
   }
 
   /**
-   * Creates a fix for the COMPOSABLE_EXPECTED error, which appears on a Composable function call from within a non-Composable function.
+   * Creates a fix for the COMPOSABLE_INVOCATION error, which appears on a non-Composable function
+   * that contains a Composable call.
    */
   object ComposableInvocationFactory : KotlinSingleIntentionActionFactory() {
-    override fun createAction(diagnostic: Diagnostic): IntentionAction? {
-      // Look for the containing function. This logic is based on ComposableCallChecker.check, which walks up the tree and terminates at
+    override fun createAction(diagnostic: Diagnostic): IntentionAction? =
+      createAction(diagnostic.psiElement)
+
+    fun createAction(psiElement: PsiElement): AddComposableToFunctionQuickFix? {
+      // Look for the containing function. This logic is based on ComposableCallChecker.check, which
+      // walks up the tree and terminates at
       // various places depending on the structure of the code.
-      var node: PsiElement? = diagnostic.psiElement as? KtElement
-      while(node != null) {
-        // Order of when statements (and empty statements) are kept, to mimic the behavior in ComposableCallChecker.check.
-        // In cases where we terminate without returning a fix, it indicates the compiler didn't identify a containing function that could
+      var node: PsiElement? = psiElement as? KtElement
+      while (node != null) {
+        // Order of when statements (and empty statements) are kept, to mimic the behavior in
+        // ComposableCallChecker.check.
+        // In cases where we terminate without returning a fix, it indicates the compiler didn't
+        // identify a containing function that could
         // be annotated with @Composable to fix the error.
-        when(node) {
-          is KtFunctionLiteral -> { /* keep going */ }
+        when (node) {
+          is KtFunctionLiteral -> {
+            /* keep going */
+          }
           is KtLambdaExpression -> {
-            // Terminate at containing lambda. There are some scenarios where the compiler may not terminate (if the lambda is inline) and
-            // therefore may go higher up to a containing named function, and we won't offer the fix in those scenarios even though it may
-            // apply. This is a tactical decision because (1) the full logic is relatively complex to reimplement here, and (2) checking for
-            // inline labmdas isn't actually correct (per the TODO in compiler code, it should be looking for CALLS_IN_PLACE instead).
+            // Terminate at containing lambda. There are some scenarios where the compiler may not
+            // terminate (if the lambda is inline) and
+            // therefore may go higher up to a containing named function, and we won't offer the fix
+            // in those scenarios even though it may
+            // apply. This is a tactical decision because (1) the full logic is relatively complex
+            // to reimplement here, and (2) checking for
+            // inline labmdas isn't actually correct (per the TODO in compiler code, it should be
+            // looking for CALLS_IN_PLACE instead).
             //
-            // This means the quick fix will not fire in some more complicated scenarios where it could actually be applicable; but that's
-            // preferable to firing in scenarios where it doesn't actually fix a problem and actually makes things worse. But if there's a
-            // containing function that can/should be annotated, it will also have an error which *will* have the quick fix, so it's still
+            // This means the quick fix will not fire in some more complicated scenarios where it
+            // could actually be applicable; but that's
+            // preferable to firing in scenarios where it doesn't actually fix a problem and
+            // actually makes things worse. But if there's a
+            // containing function that can/should be annotated, it will also have an error which
+            // *will* have the quick fix, so it's still
             // available somewhere to the user.
             return null
           }
-          is KtTryExpression -> { /* keep going */ }
+          is KtTryExpression -> {
+            /* keep going */
+          }
           is KtFunction -> {
             // Terminate at containing KtFunction.
             if (node !is KtNamedFunction) return null
             val displayName = node.name ?: return null
             return AddComposableToFunctionQuickFix(node, displayName)
           }
-          is KtProperty -> return null  // Terminate at containing property initializer.
+          is KtProperty -> return null // Terminate at containing property initializer.
           is KtPropertyAccessor -> {
             // Terminate at containing property accessor.
             if (!node.isGetter) return null
@@ -124,17 +147,35 @@
   }
 
   /**
-   * Creates a fix for the COMPOSABLE_INVOCATION error, which appears on a non-Composable function that contains a Composable call.
+   * Creates a fix for the COMPOSABLE_EXPECTED error, which appears on a Composable function call
+   * from within a non-Composable function.
    */
   object ComposableExpectedFactory : KotlinSingleIntentionActionFactory() {
-    override fun createAction(diagnostic: Diagnostic): IntentionAction? {
-      val parentNamedFunction = diagnostic.psiElement.parent as? KtNamedFunction ?: return null
-      val displayName = parentNamedFunction.name ?: return null
+    override fun createAction(diagnostic: Diagnostic): IntentionAction? =
+      createAction(diagnostic.psiElement.parent)
 
-      return AddComposableToFunctionQuickFix(parentNamedFunction, displayName)
+    fun createAction(psiElement: PsiElement): AddComposableToFunctionQuickFix? {
+      val namedFunction = psiElement as? KtNamedFunction ?: return null
+      val displayName = namedFunction.name ?: return null
+
+      return AddComposableToFunctionQuickFix(namedFunction, displayName)
     }
   }
 
+  companion object {
+    val k2DiagnosticFixFactory: KotlinDiagnosticFixFactory<KtCompilerPluginDiagnostic0> =
+      diagnosticFixFactory(KtCompilerPluginDiagnostic0::class) { diagnostic ->
+        val psiElement = diagnostic.psi
+        listOfNotNull(
+          when (diagnostic.factoryName) {
+            "COMPOSABLE_INVOCATION" -> ComposableInvocationFactory.createAction(psiElement)
+            "COMPOSABLE_EXPECTED" -> ComposableExpectedFactory.createAction(psiElement)
+            else -> null
+          }
+        )
+      }
+  }
+
   class Contributor : QuickFixContributor {
     override fun registerQuickFixes(quickFixes: QuickFixes) {
       // COMPOSABLE_INVOCATION: error goes on the Composable call in a non-Composable function
diff --git a/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeCreateComposableFunction.kt b/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeCreateComposableFunction.kt
index 2b2c2af..8cc9608 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeCreateComposableFunction.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeCreateComposableFunction.kt
@@ -51,7 +51,6 @@
 import org.jetbrains.kotlin.types.Variance
 import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations
 
-
 class ComposeUnresolvedFunctionFixContributor : QuickFixContributor {
   override fun registerQuickFixes(quickFixes: QuickFixes) {
     quickFixes.register(Errors.UNRESOLVED_REFERENCE, ComposeUnresolvedFunctionFixFactory())
@@ -63,21 +62,15 @@
  *
  * Created action creates new function with @Composable annotation.
  *
- * Example:
- * For
+ * Example: For
  *
- * @Composable
- * fun myComposable() {
- *  <caret>newFunction()
- * }
+ * @Composable fun myComposable() { <caret>newFunction() }
  *
  * creates
  *
- * @Composable
- * fun newFunction() {
- *  TODO("Not yet implemented")
- * }
+ * @Composable fun newFunction() {
  *
+ *     TODO("Not yet implemented") }
  */
 private class ComposeUnresolvedFunctionFixFactory : KotlinSingleIntentionActionFactory() {
   override fun createAction(diagnostic: Diagnostic): IntentionAction? {
@@ -85,17 +78,22 @@
     val parentFunction = unresolvedCall.getStrictParentOfType<KtNamedFunction>() ?: return null
     if (!parentFunction.isComposableFunction()) return null
 
-    val name = (unresolvedCall.calleeExpression as? KtSimpleNameExpression)?.getReferencedName() ?: return null
+    val name =
+      (unresolvedCall.calleeExpression as? KtSimpleNameExpression)?.getReferencedName()
+        ?: return null
     // Composable function usually starts with uppercase first letter.
     if (name.isBlank() || !name[0].isUpperCase()) return null
 
-    val ktCreateCallableFromUsageFix = CreateCallableFromUsageFix(unresolvedCall) {
-      listOfNotNull(createNewComposeFunctionInfo(name, it, parentFunction))
-    }
+    val ktCreateCallableFromUsageFix =
+      CreateCallableFromUsageFix(unresolvedCall) {
+        listOfNotNull(createNewComposeFunctionInfo(name, it, parentFunction))
+      }
 
-    // Since CreateCallableFromUsageFix is no longer an 'open' class, we instead use delegation to customize the text.
+    // Since CreateCallableFromUsageFix is no longer an 'open' class, we instead use delegation to
+    // customize the text.
     return object : IntentionAction by ktCreateCallableFromUsageFix {
-      override fun getText(): String = ComposeBundle.message("create.composable.function") + " '$name'"
+      override fun getText(): String =
+        ComposeBundle.message("create.composable.function") + " '$name'"
     }
   }
 
@@ -103,45 +101,65 @@
 
   // n.b. Do not cache this CallableInfo anywhere, otherwise it is easy to leak Kotlin descriptors.
   // (see https://github.com/JetBrains/intellij-community/commit/608589428c).
-  private fun createNewComposeFunctionInfo(name: String,
-                                           element: KtCallExpression,
-                                           parentComposableFunction: KtNamedFunction): CallableInfo? {
+  private fun createNewComposeFunctionInfo(
+    name: String,
+    element: KtCallExpression,
+    parentComposableFunction: KtNamedFunction
+  ): CallableInfo? {
     val analysisResult = element.analyzeAndGetResult()
     val fullCallExpression = element.getQualifiedExpressionForSelectorOrThis()
-    val expectedType = fullCallExpression.guessTypes(analysisResult.bindingContext, analysisResult.moduleDescriptor).singleOrNull()
+    val expectedType =
+      fullCallExpression
+        .guessTypes(analysisResult.bindingContext, analysisResult.moduleDescriptor)
+        .singleOrNull()
     if (expectedType != null && KotlinBuiltIns.isUnit(expectedType)) {
       val typeParameters = element.getTypeInfoForTypeArguments()
       val returnType = TypeInfo(expectedType, Variance.OUT_VARIANCE)
       val modifierList = KtPsiFactory(element.project).createModifierList(composableAnnotation)
       val containers = element.getQualifiedExpressionForSelectorOrThis().getExtractionContainers()
 
-      val parameters = if (element.valueArguments.lastOrNull() is KtLambdaArgument) {
-        // If the last argument is a lambda, treat it as a `content` parameter containing another Composable.
-        // In this case, we want the resulting argument name to be "content" and it should have a @Composable attribute.
-        val parameterInfos = element.getParameterInfos()
-        val modifiedLastParameter = parameterInfos.last().let {
-          ParameterInfo(
-            typeInfo = ComposableLambdaTypeInfo(it.typeInfo, parentComposableFunction),
-            nameSuggestions = listOf("content") + it.nameSuggestions)
+      val parameters =
+        if (element.valueArguments.lastOrNull() is KtLambdaArgument) {
+          // If the last argument is a lambda, treat it as a `content` parameter containing another
+          // Composable.
+          // In this case, we want the resulting argument name to be "content" and it should have a
+          // @Composable attribute.
+          val parameterInfos = element.getParameterInfos()
+          val modifiedLastParameter =
+            parameterInfos.last().let {
+              ParameterInfo(
+                typeInfo = ComposableLambdaTypeInfo(it.typeInfo, parentComposableFunction),
+                nameSuggestions = listOf("content") + it.nameSuggestions
+              )
+            }
+
+          parameterInfos.dropLast(1) + listOf(modifiedLastParameter)
+        } else {
+          element.getParameterInfos()
         }
 
-        parameterInfos.dropLast(1) + listOf(modifiedLastParameter)
-      }
-      else {
-        element.getParameterInfos()
-      }
-
-      return FunctionInfo(name, TypeInfo.Empty, returnType, containers, parameters, typeParameters, modifierList = modifierList)
+      return FunctionInfo(
+        name,
+        TypeInfo.Empty,
+        returnType,
+        containers,
+        parameters,
+        typeParameters,
+        modifierList = modifierList
+      )
     }
     return null
   }
 
   /** Wrapper around [TypeInfo] adding a @Composable annotation to the argument type. */
-  private class ComposableLambdaTypeInfo(private val wrapped: TypeInfo,
-                                         private val parentComposableFunction: KtNamedFunction) : TypeInfo(wrapped.variance) {
+  private class ComposableLambdaTypeInfo(
+    private val wrapped: TypeInfo,
+    private val parentComposableFunction: KtNamedFunction
+  ) : TypeInfo(wrapped.variance) {
     override fun getPossibleTypes(builder: CallableBuilder): List<KotlinType> {
       val wrappedTypes = wrapped.getPossibleTypes(builder)
-      val composableAnnotationDescriptor = parentComposableFunction.getComposableAnnotation()?.resolveToDescriptorIfAny()
+      val composableAnnotationDescriptor =
+        parentComposableFunction.getComposableAnnotation()?.resolveToDescriptorIfAny()
 
       if (composableAnnotationDescriptor == null) {
         thisLogger().warn("Could not resolve @Composable annotation descriptor.")
@@ -149,7 +167,8 @@
       }
 
       return wrappedTypes.map {
-        val newAnnotations = Annotations.create(it.annotations + listOf(composableAnnotationDescriptor))
+        val newAnnotations =
+          Annotations.create(it.annotations + listOf(composableAnnotationDescriptor))
         it.replaceAnnotations(newAnnotations)
       }
     }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeCreatePreviewAction.kt b/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeCreatePreviewAction.kt
index 50ffd4d..c1c63d2 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeCreatePreviewAction.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeCreatePreviewAction.kt
@@ -33,7 +33,8 @@
 import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespace
 
 /**
- * Adds a @Preview annotation when a full @Composable is selected or cursor at @Composable annotation.
+ * Adds a @Preview annotation when a full @Composable is selected or cursor at @Composable
+ * annotation.
  */
 class ComposeCreatePreviewAction : IntentionAction {
   override fun startInWriteAction() = true
@@ -52,18 +53,25 @@
 
   private fun getComposableAnnotationEntry(editor: Editor, file: PsiFile): KtAnnotationEntry? {
     if (editor.selectionModel.hasSelection()) {
-      val elementAtCaret = file.findElementAt(editor.selectionModel.selectionStart)?.parentOfType<KtAnnotationEntry>()
+      val elementAtCaret =
+        file.findElementAt(editor.selectionModel.selectionStart)?.parentOfType<KtAnnotationEntry>()
       if (elementAtCaret?.isComposableAnnotation() == true) {
         return elementAtCaret
-      }
-      else {
+      } else {
         // Case when user selected few extra blank lines before @Composable annotation.
-        val elementAtCaretAfterSpace = file.findElementAt(editor.selectionModel.selectionStart)?.getNextSiblingIgnoringWhitespace()
-        return (elementAtCaretAfterSpace as? KtFunction)?.annotationEntries?.find { it.fqNameMatches(COMPOSABLE_ANNOTATION_FQ_NAME) }
+        val elementAtCaretAfterSpace =
+          file
+            .findElementAt(editor.selectionModel.selectionStart)
+            ?.getNextSiblingIgnoringWhitespace()
+        return (elementAtCaretAfterSpace as? KtFunction)?.annotationEntries?.find {
+          it.fqNameMatches(COMPOSABLE_ANNOTATION_FQ_NAME)
+        }
       }
-    }
-    else {
-      return file.findElementAt(editor.caretModel.offset)?.parentOfType<KtAnnotationEntry>()?.takeIf { it.isComposableAnnotation() }
+    } else {
+      return file
+        .findElementAt(editor.caretModel.offset)
+        ?.parentOfType<KtAnnotationEntry>()
+        ?.takeIf { it.isComposableAnnotation() }
     }
   }
 
@@ -71,8 +79,10 @@
     if (editor == null || file == null) return
     val composableAnnotationEntry = getComposableAnnotationEntry(editor, file) ?: return
     val composableFunction = composableAnnotationEntry.parentOfType<KtFunction>() ?: return
-    val previewAnnotationEntry = KtPsiFactory(project).createAnnotationEntry("@${COMPOSE_PREVIEW_ANNOTATION_FQN}")
+    val previewAnnotationEntry =
+      KtPsiFactory(project).createAnnotationEntry("@${COMPOSE_PREVIEW_ANNOTATION_FQN}")
 
-    ShortenReferencesFacility.getInstance().shorten(composableFunction.addAnnotationEntry(previewAnnotationEntry))
+    ShortenReferencesFacility.getInstance()
+      .shorten(composableFunction.addAnnotationEntry(previewAnnotationEntry))
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeSurroundWithWidgetAction.kt b/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeSurroundWithWidgetAction.kt
index 777e777..7843808 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeSurroundWithWidgetAction.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeSurroundWithWidgetAction.kt
@@ -44,40 +44,54 @@
 import org.jetbrains.kotlin.psi.KtNamedFunction
 
 /**
- * Intention action that includes [ComposeSurroundWithBoxAction], [ComposeSurroundWithRowAction], [ComposeSurroundWithColumnAction].
+ * Intention action that includes [ComposeSurroundWithBoxAction], [ComposeSurroundWithRowAction],
+ * [ComposeSurroundWithColumnAction].
  *
- * After this action is selected, a new pop-up appears, in which user can choose between actions listed above.
+ * After this action is selected, a new pop-up appears, in which user can choose between actions
+ * listed above.
  *
  * @see intentionDescriptions/ComposeSurroundWithWidgetActionGroup/before.kt.template
- *      intentionDescriptions/ComposeSurroundWithWidgetActionGroup/after.kt.template
+ *   intentionDescriptions/ComposeSurroundWithWidgetActionGroup/after.kt.template
  */
 class ComposeSurroundWithWidgetActionGroup :
   IntentionActionGroup<ComposeSurroundWithWidgetAction>(
-    listOf(ComposeSurroundWithBoxAction(), ComposeSurroundWithRowAction(), ComposeSurroundWithColumnAction())
+    listOf(
+      ComposeSurroundWithBoxAction(),
+      ComposeSurroundWithRowAction(),
+      ComposeSurroundWithColumnAction()
+    )
   ) {
   override fun getGroupText(actions: List<ComposeSurroundWithWidgetAction>) =
     ComposeBundle.message("surround.with.widget.intention.text")
 
-  override fun chooseAction(project: Project,
-                            editor: Editor,
-                            file: PsiFile,
-                            actions: List<ComposeSurroundWithWidgetAction>,
-                            invokeAction: (ComposeSurroundWithWidgetAction) -> Unit) {
+  override fun chooseAction(
+    project: Project,
+    editor: Editor,
+    file: PsiFile,
+    actions: List<ComposeSurroundWithWidgetAction>,
+    invokeAction: (ComposeSurroundWithWidgetAction) -> Unit
+  ) {
     createPopup(project, actions, invokeAction).showInBestPositionFor(editor)
   }
 
-  private fun createPopup(project: Project,
-                          actions: List<ComposeSurroundWithWidgetAction>,
-                          invokeAction: (ComposeSurroundWithWidgetAction) -> Unit): ListPopup {
+  private fun createPopup(
+    project: Project,
+    actions: List<ComposeSurroundWithWidgetAction>,
+    invokeAction: (ComposeSurroundWithWidgetAction) -> Unit
+  ): ListPopup {
 
-    val step = object : BaseListPopupStep<ComposeSurroundWithWidgetAction>(null, actions) {
-      override fun getTextFor(action: ComposeSurroundWithWidgetAction) = action.text
+    val step =
+      object : BaseListPopupStep<ComposeSurroundWithWidgetAction>(null, actions) {
+        override fun getTextFor(action: ComposeSurroundWithWidgetAction) = action.text
 
-      override fun onChosen(selectedValue: ComposeSurroundWithWidgetAction, finalChoice: Boolean): PopupStep<*>? {
-        invokeAction(selectedValue)
-        return FINAL_CHOICE
+        override fun onChosen(
+          selectedValue: ComposeSurroundWithWidgetAction,
+          finalChoice: Boolean
+        ): PopupStep<*>? {
+          invokeAction(selectedValue)
+          return FINAL_CHOICE
+        }
       }
-    }
 
     return ListPopupImpl(project, step)
   }
@@ -86,51 +100,66 @@
 }
 
 /**
- * Finds the first [KtCallExpression] at the given offset stopping if it finds any [KtNamedFunction] so it does not
- * exit the `Composable`.
+ * Finds the first [KtCallExpression] at the given offset stopping if it finds any [KtNamedFunction]
+ * so it does not exit the `Composable`.
  */
 private fun PsiFile.findParentCallExpression(offset: Int): PsiElement? =
-  PsiTreeUtil.findElementOfClassAtOffsetWithStopSet(this, offset, KtCallExpression::class.java,
-                                                    false, KtNamedFunction::class.java)
+  PsiTreeUtil.findElementOfClassAtOffsetWithStopSet(
+    this,
+    offset,
+    KtCallExpression::class.java,
+    false,
+    KtNamedFunction::class.java
+  )
 
 /**
- * Finds the nearest surroundable [PsiElement] starting at the given offset and looking at the parents. If the offset is at
- * the end of a line, this method might look in the immediately previous offset.
+ * Finds the nearest surroundable [PsiElement] starting at the given offset and looking at the
+ * parents. If the offset is at the end of a line, this method might look in the immediately
+ * previous offset.
  */
 private fun findNearestSurroundableElement(file: PsiFile, offset: Int): PsiElement? {
-  val nearestElement = file.findElementAt(offset)?.let {
-    if (it.isLineBreak()) {
-      file.findParentCallExpression(it.prevLeaf(true)?.startOffset ?: (offset - 1))
+  val nearestElement =
+    file.findElementAt(offset)?.let {
+      if (it.isLineBreak()) {
+        file.findParentCallExpression(it.prevLeaf(true)?.startOffset ?: (offset - 1))
+      } else it
     }
-    else it
-  } ?: return null
+      ?: return null
 
   return file.findParentCallExpression(nearestElement.startOffset)
 }
 
 /**
- * Finds the [TextRange] to surround based on the current [editor] selection. It returns null if there is no block that
- * can be selected.
+ * Finds the [TextRange] to surround based on the current [editor] selection. It returns null if
+ * there is no block that can be selected.
  */
 fun findSurroundingSelectionRange(file: PsiFile, editor: Editor): TextRange? {
   if (!editor.selectionModel.hasSelection()) return null
 
-  // We try to select full call elements to avoid the selection falling in the middle of, for example, a string.
-  // This way, selecting the middle of two strings would still wrap the parent calls like for the following example:
+  // We try to select full call elements to avoid the selection falling in the middle of, for
+  // example, a string.
+  // This way, selecting the middle of two strings would still wrap the parent calls like for the
+  // following example:
   //
   // Text("Hello <selection>world!")
   // Button(...)
   // Text("By</selection>e")
   //
   // Would wrap the three elements instead of just the Button.
-  val startSelectionOffset = findNearestSurroundableElement(file, editor.selectionModel.selectionStart)?.startOffset ?: Int.MAX_VALUE
-  val endSelectionOffset = findNearestSurroundableElement(file, editor.selectionModel.selectionEnd)?.endOffset ?: -1
+  val startSelectionOffset =
+    findNearestSurroundableElement(file, editor.selectionModel.selectionStart)?.startOffset
+      ?: Int.MAX_VALUE
+  val endSelectionOffset =
+    findNearestSurroundableElement(file, editor.selectionModel.selectionEnd)?.endOffset ?: -1
 
-  val statements = findElements(file,
-                                minOf(editor.selectionModel.selectionStart, startSelectionOffset),
-                                maxOf(editor.selectionModel.selectionEnd, endSelectionOffset),
-                                ElementKind.EXPRESSION)
-    .filter { it.isInsideComposableCode() }
+  val statements =
+    findElements(
+        file,
+        minOf(editor.selectionModel.selectionStart, startSelectionOffset),
+        maxOf(editor.selectionModel.selectionEnd, endSelectionOffset),
+        ElementKind.EXPRESSION
+      )
+      .filter { it.isInsideComposableCode() }
   if (statements.isNotEmpty()) {
     return TextRange.create(statements.minOf { it.startOffset }, statements.maxOf { it.endOffset })
   }
@@ -141,25 +170,26 @@
  * Surrounds selected statements inside a @Composable function with a widget.
  *
  * @see intentionDescriptions/ComposeSurroundWithWidgetActionGroup/before.kt.template
- *      intentionDescriptions/ComposeSurroundWithWidgetActionGroup/after.kt.template
+ *   intentionDescriptions/ComposeSurroundWithWidgetActionGroup/after.kt.template
  */
 abstract class ComposeSurroundWithWidgetAction : IntentionAction, HighPriorityAction {
   override fun getFamilyName() = "Compose Surround With Action"
 
   override fun startInWriteAction(): Boolean = true
 
-  private fun findSurroundableRange(file: PsiFile, editor: Editor): TextRange? = if (editor.selectionModel.hasSelection()) {
-    findSurroundingSelectionRange(file, editor)
-  }
-  else {
-    findNearestSurroundableElement(file, editor.caretModel.offset)?.textRange
-  }
+  private fun findSurroundableRange(file: PsiFile, editor: Editor): TextRange? =
+    if (editor.selectionModel.hasSelection()) {
+      findSurroundingSelectionRange(file, editor)
+    } else {
+      findNearestSurroundableElement(file, editor.caretModel.offset)?.textRange
+    }
 
-  override fun isAvailable(project: Project, editor: Editor?, file: PsiFile?): Boolean = when {
-    file == null || editor == null -> false
-    !file.isWritable || file !is KtFile -> false
-    else -> findSurroundableRange(file, editor) != null
-  }
+  override fun isAvailable(project: Project, editor: Editor?, file: PsiFile?): Boolean =
+    when {
+      file == null || editor == null -> false
+      !file.isWritable || file !is KtFile -> false
+      else -> findSurroundableRange(file, editor) != null
+    }
 
   protected abstract fun getTemplate(): TemplateImpl?
 
@@ -168,18 +198,17 @@
 
     val surroundRange = findSurroundableRange(file, editor) ?: return
     // Extend the selection if it does not match the inferred range
-    if (editor.selectionModel.selectionStart != surroundRange.startOffset ||
-      editor.selectionModel.selectionEnd != surroundRange.endOffset) {
+    if (
+      editor.selectionModel.selectionStart != surroundRange.startOffset ||
+        editor.selectionModel.selectionEnd != surroundRange.endOffset
+    ) {
       editor.selectionModel.setSelection(surroundRange.startOffset, surroundRange.endOffset)
     }
     InvokeTemplateAction(getTemplate(), editor, project, HashSet()).perform()
   }
-
 }
 
-/**
- * Surrounds selected statements inside a @Composable function with Box widget.
- */
+/** Surrounds selected statements inside a @Composable function with Box widget. */
 class ComposeSurroundWithBoxAction : ComposeSurroundWithWidgetAction() {
   override fun getText(): String = ComposeBundle.message("surround.with.box.intention.text")
 
@@ -188,9 +217,7 @@
   }
 }
 
-/**
- * Surrounds selected statements inside a @Composable function with Row widget.
- */
+/** Surrounds selected statements inside a @Composable function with Row widget. */
 class ComposeSurroundWithRowAction : ComposeSurroundWithWidgetAction() {
   override fun getText(): String = ComposeBundle.message("surround.with.row.intention.text")
 
@@ -199,9 +226,7 @@
   }
 }
 
-/**
- * Surrounds selected statements inside a @Composable function with Column widget.
- */
+/** Surrounds selected statements inside a @Composable function with Column widget. */
 class ComposeSurroundWithColumnAction : ComposeSurroundWithWidgetAction() {
   override fun getText(): String = ComposeBundle.message("surround.with.column.intention.text")
 
@@ -209,4 +234,3 @@
     return TemplateSettings.getInstance().getTemplate("WC", "AndroidCompose")
   }
 }
-
diff --git a/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeUnwrapAction.kt b/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeUnwrapAction.kt
index bfab3f2..ddb28c5 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeUnwrapAction.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeUnwrapAction.kt
@@ -29,16 +29,14 @@
 import org.jetbrains.kotlin.psi.KtNameReferenceExpression
 import org.jetbrains.kotlin.psi.KtNamedFunction
 
-
-/**
- * Removes wrappers like Row, Column and Box around widgets.
- */
+/** Removes wrappers like Row, Column and Box around widgets. */
 class ComposeUnwrapAction : IntentionAction {
-  private val WRAPPERS_FQ_NAMES = setOf(
-    "androidx.compose.foundation.layout.Box",
-    "androidx.compose.foundation.layout.Row",
-    "androidx.compose.foundation.layout.Column"
-  )
+  private val WRAPPERS_FQ_NAMES =
+    setOf(
+      "androidx.compose.foundation.layout.Box",
+      "androidx.compose.foundation.layout.Row",
+      "androidx.compose.foundation.layout.Column"
+    )
 
   override fun startInWriteAction() = true
 
@@ -55,17 +53,21 @@
   }
 
   private fun isCaretAtWrapper(editor: Editor, file: PsiFile): Boolean {
-    val elementAtCaret = file.findElementAt(editor.caretModel.offset)?.parentOfType<KtNameReferenceExpression>() ?: return false
+    val elementAtCaret =
+      file.findElementAt(editor.caretModel.offset)?.parentOfType<KtNameReferenceExpression>()
+        ?: return false
     val name = (elementAtCaret.resolve() as? KtNamedFunction)?.fqName?.asString() ?: return false
     return WRAPPERS_FQ_NAMES.contains(name)
   }
 
   override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
     if (file == null || editor == null) return
-    val wrapper = file.findElementAt(editor.caretModel.offset)?.parentOfType<KtNameReferenceExpression>() ?: return
+    val wrapper =
+      file.findElementAt(editor.caretModel.offset)?.parentOfType<KtNameReferenceExpression>()
+        ?: return
     val outerBlock = wrapper.parent as? KtCallExpression ?: return
-    val lambdaBlock = PsiTreeUtil.findChildOfType(outerBlock, KtBlockExpression::class.java, true) ?: return
+    val lambdaBlock =
+      PsiTreeUtil.findChildOfType(outerBlock, KtBlockExpression::class.java, true) ?: return
     outerBlock.replace(lambdaBlock)
   }
-
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeWrapModifiersAction.kt b/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeWrapModifiersAction.kt
index ed18073..f7b616d 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeWrapModifiersAction.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/intentions/ComposeWrapModifiersAction.kt
@@ -29,7 +29,8 @@
 import org.jetbrains.kotlin.psi.psiUtil.getLastParentOfTypeInRowWithSelf
 
 /**
- * Wraps Modifier(androidx.compose.ui.Modifier) chain that is two modifiers or longer, in one modifier per line.
+ * Wraps Modifier(androidx.compose.ui.Modifier) chain that is two modifiers or longer, in one
+ * modifier per line.
  */
 class ComposeWrapModifiersAction : IntentionAction {
   private companion object {
@@ -47,19 +48,23 @@
       file == null || editor == null -> false
       !file.isWritable || file !is KtFile -> false
       else -> {
-        val elementAtCaret = file.findElementAt(editor.caretModel.offset)?.parentOfType<KtDotQualifiedExpression>()
-        val topLevelExpression = elementAtCaret?.getLastParentOfTypeInRowWithSelf<KtDotQualifiedExpression>() ?: return false
+        val elementAtCaret =
+          file.findElementAt(editor.caretModel.offset)?.parentOfType<KtDotQualifiedExpression>()
+        val topLevelExpression =
+          elementAtCaret?.getLastParentOfTypeInRowWithSelf<KtDotQualifiedExpression>()
+            ?: return false
         isModifierChainLongerThanTwo(topLevelExpression) &&
-        NO_NEW_LINE_BEFORE_DOT.containsMatchIn(topLevelExpression.text)
+          NO_NEW_LINE_BEFORE_DOT.containsMatchIn(topLevelExpression.text)
       }
     }
   }
 
   override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
     if (file == null || editor == null) return
-    val elementAtCaret = file.findElementAt(editor.caretModel.offset)?.parentOfType<KtDotQualifiedExpression>()
-    val topLevelExpression = elementAtCaret?.getLastParentOfTypeInRowWithSelf<KtDotQualifiedExpression>() ?: return
+    val elementAtCaret =
+      file.findElementAt(editor.caretModel.offset)?.parentOfType<KtDotQualifiedExpression>()
+    val topLevelExpression =
+      elementAtCaret?.getLastParentOfTypeInRowWithSelf<KtDotQualifiedExpression>() ?: return
     wrapModifierChain(topLevelExpression, CodeStyle.getSettings(file))
   }
-
 }
diff --git a/compose-ide-plugin/src/com/android/tools/compose/settings/ComposeFormattingCodeStyleSettingsProvider.kt b/compose-ide-plugin/src/com/android/tools/compose/settings/ComposeFormattingCodeStyleSettingsProvider.kt
index 7ba8444..5a74c7c 100644
--- a/compose-ide-plugin/src/com/android/tools/compose/settings/ComposeFormattingCodeStyleSettingsProvider.kt
+++ b/compose-ide-plugin/src/com/android/tools/compose/settings/ComposeFormattingCodeStyleSettingsProvider.kt
@@ -23,13 +23,10 @@
 import com.intellij.psi.codeStyle.CustomCodeStyleSettings
 import com.intellij.ui.dsl.builder.panel
 import com.intellij.ui.dsl.builder.selected
-import org.jetbrains.kotlin.idea.KotlinLanguage
 import javax.swing.JCheckBox
+import org.jetbrains.kotlin.idea.KotlinLanguage
 
-
-/**
- * Allows to turn on and off [ComposePostFormatProcessor] in Code Style settings.
- */
+/** Allows to turn on and off [ComposePostFormatProcessor] in Code Style settings. */
 class ComposeFormattingCodeStyleSettingsProvider : CodeStyleSettingsProvider() {
 
   override fun hasSettingsPage() = false
@@ -41,7 +38,10 @@
   override fun getConfigurableDisplayName(): String = ComposeBundle.message("compose")
   override fun getLanguage() = KotlinLanguage.INSTANCE
 
-  override fun createConfigurable(originalSettings: CodeStyleSettings, modelSettings: CodeStyleSettings): CodeStyleConfigurable {
+  override fun createConfigurable(
+    originalSettings: CodeStyleSettings,
+    modelSettings: CodeStyleSettings
+  ): CodeStyleConfigurable {
     return object : CodeStyleConfigurable {
 
       private lateinit var checkBox: JCheckBox
@@ -50,29 +50,35 @@
         return panel {
           group("Compose formatting") {
             row {
-              checkBox = checkBox(ComposeBundle.message("compose.enable.formatting.for.modifiers"))
-                .selected(ComposeCustomCodeStyleSettings.getInstance(originalSettings).USE_CUSTOM_FORMATTING_FOR_MODIFIERS)
-                .component
+              checkBox =
+                checkBox(ComposeBundle.message("compose.enable.formatting.for.modifiers"))
+                  .selected(
+                    ComposeCustomCodeStyleSettings.getInstance(originalSettings)
+                      .USE_CUSTOM_FORMATTING_FOR_MODIFIERS
+                  )
+                  .component
             }
           }
         }
       }
 
-      override fun isModified() = ComposeCustomCodeStyleSettings.getInstance(
-        originalSettings).USE_CUSTOM_FORMATTING_FOR_MODIFIERS != checkBox.isSelected
+      override fun isModified() =
+        ComposeCustomCodeStyleSettings.getInstance(originalSettings)
+          .USE_CUSTOM_FORMATTING_FOR_MODIFIERS != checkBox.isSelected
 
       override fun apply(settings: CodeStyleSettings) {
-        ComposeCustomCodeStyleSettings.getInstance(settings).USE_CUSTOM_FORMATTING_FOR_MODIFIERS = checkBox.isSelected
+        ComposeCustomCodeStyleSettings.getInstance(settings).USE_CUSTOM_FORMATTING_FOR_MODIFIERS =
+          checkBox.isSelected
       }
 
       override fun apply() = apply(originalSettings)
 
       override fun reset(settings: CodeStyleSettings) {
-        checkBox.isSelected = ComposeCustomCodeStyleSettings.getInstance(settings).USE_CUSTOM_FORMATTING_FOR_MODIFIERS
+        checkBox.isSelected =
+          ComposeCustomCodeStyleSettings.getInstance(settings).USE_CUSTOM_FORMATTING_FOR_MODIFIERS
       }
 
       override fun getDisplayName() = ComposeBundle.message("compose")
     }
-
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testData/projects/appWithLibWithSamples/app/src/main/java/com/example/appforsamplestest/Main.kt b/compose-ide-plugin/testData/projects/appWithLibWithSamples/app/src/main/java/com/example/appforsamplestest/Main.kt
index 1083c86..20f5344 100644
--- a/compose-ide-plugin/testData/projects/appWithLibWithSamples/app/src/main/java/com/example/appforsamplestest/Main.kt
+++ b/compose-ide-plugin/testData/projects/appWithLibWithSamples/app/src/main/java/com/example/appforsamplestest/Main.kt
@@ -3,5 +3,5 @@
 import app.main.myFunction
 
 fun main() {
-    myFunction()
+  myFunction()
 }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableElementAutomaticRenamerFactoryTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableElementAutomaticRenamerFactoryTest.kt
index 9c58650..487c8ce 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableElementAutomaticRenamerFactoryTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableElementAutomaticRenamerFactoryTest.kt
@@ -29,10 +29,11 @@
 import org.junit.Test
 
 class ComposableElementAutomaticRenamerFactoryTest {
-  @get:Rule
-  val projectRule = AndroidProjectRule.inMemory().onEdt()
+  @get:Rule val projectRule = AndroidProjectRule.inMemory().onEdt()
 
-  private val myFixture: CodeInsightTestFixtureImpl by lazy { projectRule.fixture as CodeInsightTestFixtureImpl }
+  private val myFixture: CodeInsightTestFixtureImpl by lazy {
+    projectRule.fixture as CodeInsightTestFixtureImpl
+  }
 
   @Before
   fun setUp() {
@@ -43,22 +44,26 @@
   @RunsInEdt
   @Test
   fun testRenaming() {
-    val kotlinFile = myFixture.addFileToProject(
-      "/scr/com/example/Greeting.kt",
-      //language=kotlin
-      """
+    val kotlinFile =
+      myFixture.addFileToProject(
+        "/scr/com/example/Greeting.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
 
       @Composable
       fun Greeting() {}
-    """.trimIndent())
+    """
+          .trimIndent()
+      )
 
-    val javaFile = myFixture.addFileToProject(
-      "src/com/example/MyClass.java",
-      //language=Java
-      """
+    val javaFile =
+      myFixture.addFileToProject(
+        "src/com/example/MyClass.java",
+        // language=Java
+        """
       package com.example;
 
       public class MyClass {
@@ -66,7 +71,9 @@
           GreetingKt.Greeting();
         }
       }
-    """.trimIndent())
+    """
+          .trimIndent()
+      )
 
     myFixture.openFileInEditor(kotlinFile.virtualFile)
     myFixture.moveCaret("Gree|ting")
@@ -80,13 +87,14 @@
 
       @Composable
       fun GreetingNew() {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // Check the file name is changed.
     assertThat(myFixture.file?.name).isEqualTo("GreetingNew.kt")
 
-    //Check references to the file name are changed.
+    // Check references to the file name are changed.
     myFixture.openFileInEditor(javaFile.virtualFile)
     myFixture.checkResult(
       """
@@ -97,7 +105,8 @@
           GreetingNewKt.GreetingNew();
         }
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableFunctionExtractableAnalyserTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableFunctionExtractableAnalyserTest.kt
index 70c7caa..3cb07e1 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableFunctionExtractableAnalyserTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableFunctionExtractableAnalyserTest.kt
@@ -24,6 +24,7 @@
 import com.intellij.openapi.project.Project
 import com.intellij.testFramework.RunsInEdt
 import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl
+import java.util.Collections
 import org.jetbrains.android.compose.stubComposableAnnotation
 import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.EXTRACT_FUNCTION
 import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ExtractKotlinFunctionHandler
@@ -35,14 +36,14 @@
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
-import java.util.Collections
 
 class ComposableFunctionExtractableAnalyserTest {
 
-  @get:Rule
-  val projectRule = AndroidProjectRule.inMemory().onEdt()
+  @get:Rule val projectRule = AndroidProjectRule.inMemory().onEdt()
 
-  private val myFixture: CodeInsightTestFixtureImpl by lazy { projectRule.fixture as CodeInsightTestFixtureImpl }
+  private val myFixture: CodeInsightTestFixtureImpl by lazy {
+    projectRule.fixture as CodeInsightTestFixtureImpl
+  }
 
   @Before
   fun setUp() {
@@ -50,15 +51,24 @@
     myFixture.stubComposableAnnotation()
   }
 
-  private val helper = object : ExtractionEngineHelper(EXTRACT_FUNCTION) {
-    override fun configureAndRun(project: Project,
-                                 editor: Editor,
-                                 descriptorWithConflicts: ExtractableCodeDescriptorWithConflicts,
-                                 onFinish: (ExtractionResult) -> Unit) {
-      val newDescriptor = descriptorWithConflicts.descriptor.copy(suggestedNames = Collections.singletonList("newComposableFunction"))
-      doRefactor(ExtractionGeneratorConfiguration(newDescriptor, ExtractionGeneratorOptions.DEFAULT), onFinish)
+  private val helper =
+    object : ExtractionEngineHelper(EXTRACT_FUNCTION) {
+      override fun configureAndRun(
+        project: Project,
+        editor: Editor,
+        descriptorWithConflicts: ExtractableCodeDescriptorWithConflicts,
+        onFinish: (ExtractionResult) -> Unit
+      ) {
+        val newDescriptor =
+          descriptorWithConflicts.descriptor.copy(
+            suggestedNames = Collections.singletonList("newComposableFunction")
+          )
+        doRefactor(
+          ExtractionGeneratorConfiguration(newDescriptor, ExtractionGeneratorOptions.DEFAULT),
+          onFinish
+        )
+      }
     }
-  }
 
   @RunsInEdt
   @Test
@@ -75,13 +85,15 @@
       fun sourceFunction() {
         <selection>print(true)</selection>
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    ExtractKotlinFunctionHandler(helper = helper).invoke(myFixture.project, myFixture.editor, myFixture.file!!, null)
+    ExtractKotlinFunctionHandler(helper = helper)
+      .invoke(myFixture.project, myFixture.editor, myFixture.file!!, null)
 
     myFixture.checkResult(
-      //language=kotlin
+      // language=kotlin
       """
         package com.example
 
@@ -96,7 +108,8 @@
         private fun newComposableFunction() {
             print(true)
         }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -119,13 +132,15 @@
           <selection>print(true)</selection>
         }
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    ExtractKotlinFunctionHandler(helper = helper).invoke(myFixture.project, myFixture.editor, myFixture.file!!, null)
+    ExtractKotlinFunctionHandler(helper = helper)
+      .invoke(myFixture.project, myFixture.editor, myFixture.file!!, null)
 
     myFixture.checkResult(
-      //language=kotlin
+      // language=kotlin
       """
       package com.example
 
@@ -144,7 +159,8 @@
       private fun newComposableFunction() {
           print(true)
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableHighlighterExtensionTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableHighlighterExtensionTest.kt
index 40a5225..ac38b91 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableHighlighterExtensionTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableHighlighterExtensionTest.kt
@@ -41,8 +41,7 @@
 
 @RunWith(JUnit4::class)
 class ComposableHighlighterExtensionTest {
-  @get:Rule
-  var projectRule = AndroidProjectRule.inMemory()
+  @get:Rule var projectRule = AndroidProjectRule.inMemory()
 
   private val highlighter = ComposableHighlighterExtension()
 
@@ -76,10 +75,13 @@
     whenever(mockContainingFile.isValid).thenReturn(true)
     whenever(mockContainingFile.project).thenReturn(projectRule.project)
     whenever(mockContainingFile.virtualFile).thenReturn(mockVirtualFile)
-    whenever(mockContainingFile.getUserData(ModuleUtilCore.KEY_MODULE)).thenReturn(projectRule.module)
+    whenever(mockContainingFile.getUserData(ModuleUtilCore.KEY_MODULE))
+      .thenReturn(projectRule.module)
 
     // Setup mocks to return whether the function is composable
-    whenever(mockProjectFileIndex.isInLibrarySource(mockVirtualFile)).thenAnswer { isInLibrarySource }
+    whenever(mockProjectFileIndex.isInLibrarySource(mockVirtualFile)).thenAnswer {
+      isInLibrarySource
+    }
 
     // Setup mocks to return whether the function is in library source.
     whenever(mockResolvedCall.candidateDescriptor).thenReturn(mockCandidateDescriptor)
@@ -123,24 +125,25 @@
     isComposableInvocation = true
     moduleUsesCompose = true
 
-    // If the call is outside a compose-enabled module or library source, there should be no highlighting.
+    // If the call is outside a compose-enabled module or library source, there should be no
+    // highlighting.
     moduleUsesCompose = false
     isInLibrarySource = false
     assertThat(highlighter.highlightCall(mockElement, mockResolvedCall)).isNull()
 
     moduleUsesCompose = false
     isInLibrarySource = true
-    assertThat(highlighter.highlightCall(mockElement, mockResolvedCall)).isEqualTo(
-      ComposableHighlighterExtension.COMPOSABLE_CALL_TEXT_TYPE)
+    assertThat(highlighter.highlightCall(mockElement, mockResolvedCall))
+      .isEqualTo(ComposableHighlighterExtension.COMPOSABLE_CALL_TEXT_TYPE)
 
     moduleUsesCompose = true
     isInLibrarySource = false
-    assertThat(highlighter.highlightCall(mockElement, mockResolvedCall)).isEqualTo(
-      ComposableHighlighterExtension.COMPOSABLE_CALL_TEXT_TYPE)
+    assertThat(highlighter.highlightCall(mockElement, mockResolvedCall))
+      .isEqualTo(ComposableHighlighterExtension.COMPOSABLE_CALL_TEXT_TYPE)
 
     moduleUsesCompose = true
     isInLibrarySource = true
-    assertThat(highlighter.highlightCall(mockElement, mockResolvedCall)).isEqualTo(
-      ComposableHighlighterExtension.COMPOSABLE_CALL_TEXT_TYPE)
+    assertThat(highlighter.highlightCall(mockElement, mockResolvedCall))
+      .isEqualTo(ComposableHighlighterExtension.COMPOSABLE_CALL_TEXT_TYPE)
   }
 }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableIconProviderTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableIconProviderTest.kt
index 75104a5..6e51e42 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableIconProviderTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableIconProviderTest.kt
@@ -32,26 +32,31 @@
 
 @RunWith(JUnit4::class)
 class ComposableIconProviderTest {
-  @get:Rule
-  var projectRule = AndroidProjectRule.inMemory()
+  @get:Rule var projectRule = AndroidProjectRule.inMemory()
 
   @Before
   fun setup() {
     // Allow @Composable attribute to be used in snippets below.
-    projectRule.fixture.addFileToProject("androidx/compose/runtime/Composable.kt", """
+    projectRule.fixture.addFileToProject(
+      "androidx/compose/runtime/Composable.kt",
+      """
 package androidx.compose.runtime
 
-annotation class Composable""")
+annotation class Composable"""
+    )
   }
 
   @Test
   fun getPresentation_notAFunction() {
-    projectRule.fixture.configureByText(KotlinFileType.INSTANCE, """
+    projectRule.fixture.configureByText(
+      KotlinFileType.INSTANCE,
+      """
 package com.example
 
 val fo<caret>o = 1234
 
-""")
+"""
+    )
 
     runReadAction {
       val element = projectRule.fixture.elementAtCaret
@@ -63,12 +68,15 @@
 
   @Test
   fun getPresentation_notComposeFunction() {
-    projectRule.fixture.configureByText(KotlinFileType.INSTANCE, """
+    projectRule.fixture.configureByText(
+      KotlinFileType.INSTANCE,
+      """
 package com.example
 
 fun testFun<caret>ction() {}
 
-""")
+"""
+    )
 
     runReadAction {
       val element = projectRule.fixture.elementAtCaret
@@ -80,7 +88,9 @@
 
   @Test
   fun getPresentation_composeFunctionWithVisibility() {
-    projectRule.fixture.configureByText(KotlinFileType.INSTANCE, """
+    projectRule.fixture.configureByText(
+      KotlinFileType.INSTANCE,
+      """
 package com.example
 
 import androidx.compose.runtime.Composable
@@ -88,7 +98,8 @@
 @Composable
 fun testFun<caret>ction() {}
 
-""")
+"""
+    )
 
     runReadAction {
       val element = projectRule.fixture.elementAtCaret
@@ -105,7 +116,9 @@
 
   @Test
   fun getPresentation_composeFunctionWithoutVisibility() {
-    projectRule.fixture.configureByText(KotlinFileType.INSTANCE, """
+    projectRule.fixture.configureByText(
+      KotlinFileType.INSTANCE,
+      """
 package com.example
 
 import androidx.compose.runtime.Composable
@@ -113,7 +126,8 @@
 @Composable
 fun testFun<caret>ction() {}
 
-""")
+"""
+    )
 
     runReadAction {
       val element = projectRule.fixture.elementAtCaret
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableItemPresentationProviderTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableItemPresentationProviderTest.kt
index db4d478..60720b9 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableItemPresentationProviderTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposableItemPresentationProviderTest.kt
@@ -28,8 +28,7 @@
 
 @RunWith(JUnit4::class)
 class ComposableItemPresentationProviderTest {
-  @get:Rule
-  var projectRule = AndroidProjectRule.inMemory()
+  @get:Rule var projectRule = AndroidProjectRule.inMemory()
 
   private val provider = ComposableItemPresentationProvider()
 
@@ -42,7 +41,9 @@
 
       val testFunction = <caret>{ }
 
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     runReadAction {
       val function = runReadAction { projectRule.fixture.elementAtCaret }
@@ -61,7 +62,9 @@
 
       fun testFun<caret>ction(arg0: Int, arg1: Int) {}
 
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     runReadAction {
       val function = projectRule.fixture.elementAtCaret
@@ -73,12 +76,16 @@
 
   @Test
   fun getPresentation_functionIsComposable_composablePresentationReturned() {
-    projectRule.fixture.addFileToProject("androidx/compose/runtime/Composable.kt", """
+    projectRule.fixture.addFileToProject(
+      "androidx/compose/runtime/Composable.kt",
+      """
       package androidx.compose.runtime
 
       annotation class Composable
 
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     projectRule.fixture.configureByText(
       KotlinFileType.INSTANCE,
@@ -90,7 +97,9 @@
       @Composable
       fun testFun<caret>ction(arg0: Int, arg1: Int = 0) {}
 
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     runReadAction {
       val function = projectRule.fixture.elementAtCaret
@@ -103,12 +112,16 @@
 
   @Test
   fun getPresentation_functionIsComposable_composablePresentationReturnedWithLambda() {
-    projectRule.fixture.addFileToProject("androidx/compose/runtime/Composable.kt", """
+    projectRule.fixture.addFileToProject(
+      "androidx/compose/runtime/Composable.kt",
+      """
       package androidx.compose.runtime
 
       annotation class Composable
 
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     projectRule.fixture.configureByText(
       KotlinFileType.INSTANCE,
@@ -120,14 +133,17 @@
       @Composable
       fun testFun<caret>ction(arg0: Int, arg1: Int = 0, arg2: @Composable () -> Unit) {}
 
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     runReadAction {
       val function = projectRule.fixture.elementAtCaret
       assertThat(function).isInstanceOf(KtFunction::class.java)
 
       val presentation = provider.getPresentation(function as KtFunction)!!
-      assertThat(presentation.presentableText).isEqualTo("@Composable testFunction(arg0: Int, ...) {...}")
+      assertThat(presentation.presentableText)
+        .isEqualTo("@Composable testFunction(arg0: Int, ...) {...}")
     }
   }
 }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeAutoDocumentationTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeAutoDocumentationTest.kt
index ede9c39..79c380d 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeAutoDocumentationTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeAutoDocumentationTest.kt
@@ -34,8 +34,7 @@
 
 @RunWith(JUnit4::class)
 class ComposeAutoDocumentationTest {
-  @get:Rule
-  val projectRule = AndroidProjectRule.onDisk().onEdt()
+  @get:Rule val projectRule = AndroidProjectRule.onDisk().onEdt()
 
   private val fixture by lazy { projectRule.fixture as JavaCodeInsightTestFixture }
 
@@ -50,10 +49,11 @@
   fun documentationForComposables() {
     (fixture.module.getModuleSystem() as DefaultModuleSystem).usesCompose = true
     fixture.stubComposableAnnotation()
-    val file = fixture.addFileToProject(
-      "/src/the/hold/steady/Albums.kt",
-      // language=kotlin
-      """
+    val file =
+      fixture.addFileToProject(
+        "/src/the/hold/steady/Albums.kt",
+        // language=kotlin
+        """
       package the.hold.steady
 
       import androidx.compose.runtime.Composable
@@ -68,8 +68,9 @@
       fun ThePriceOfProgress(optional: Int = 42, children: @Composable() () -> Unit) {}
 
       fun OpenDoorPolicy() {}
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     fixture.openFileInEditor(file.virtualFile)
 
@@ -79,7 +80,8 @@
       assertThat(fixture.findParentElement<KtNamedFunction>(it).shouldShowDocumentation()).isTrue()
     }
 
-    assertThat(fixture.findParentElement<KtNamedFunction>("Open|Door").shouldShowDocumentation()).isFalse()
+    assertThat(fixture.findParentElement<KtNamedFunction>("Open|Door").shouldShowDocumentation())
+      .isFalse()
   }
 
   @RunsInEdt
@@ -91,19 +93,22 @@
       """
       package androidx.compose.ui
       interface Modifier
-      """.trimIndent()
-    )
-    val file = fixture.addFileToProject(
-      "/src/metric/Albums.kt",
-      // language=kotlin
       """
+        .trimIndent()
+    )
+    val file =
+      fixture.addFileToProject(
+        "/src/metric/Albums.kt",
+        // language=kotlin
+        """
       package metric
       // For whatever reason, these don't come back qualified in the test, so fully qualify here.
       fun androidx.compose.ui.Modifier.artOfDoubt(): Modifier = this
       fun androidx.compose.ui.Modifier.formentera(): Modifier = this
       fun String.growUpAndBlowAway(): Int = 8675309
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
     fixture.openFileInEditor(file.virtualFile)
 
     val windows = listOf("artOf|Doubt", "formen|tera")
@@ -112,16 +117,18 @@
       assertThat(fixture.findParentElement<KtNamedFunction>(it).shouldShowDocumentation()).isTrue()
     }
 
-    assertThat(fixture.findParentElement<KtNamedFunction>("Blow|Away").shouldShowDocumentation()).isFalse()
+    assertThat(fixture.findParentElement<KtNamedFunction>("Blow|Away").shouldShowDocumentation())
+      .isFalse()
   }
 
   @RunsInEdt
   @Test
   fun documentationForModifierBlahBlah() {
-    val file = fixture.addFileToProject(
-    "/src/androidx/compose/ui/Modifier.kt",
-    // language=kotlin
-    """
+    val file =
+      fixture.addFileToProject(
+        "/src/androidx/compose/ui/Modifier.kt",
+        // language=kotlin
+        """
       package androidx.compose.ui
       interface Modifier {
         fun fantasies() {}
@@ -130,8 +137,9 @@
           fun pagansInVegas() = 42L
         }
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     fixture.openFileInEditor(file.virtualFile)
 
@@ -141,4 +149,4 @@
       assertThat(fixture.findParentElement<KtNamedFunction>(it).shouldShowDocumentation()).isTrue()
     }
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeColorAnnotatorTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeColorLineMarkerProviderDescriptorTest.kt
similarity index 73%
rename from compose-ide-plugin/testSrc/com/android/tools/compose/ComposeColorAnnotatorTest.kt
rename to compose-ide-plugin/testSrc/com/android/tools/compose/ComposeColorLineMarkerProviderDescriptorTest.kt
index b83f18e..4a47eec 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeColorAnnotatorTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeColorLineMarkerProviderDescriptorTest.kt
@@ -23,47 +23,43 @@
 import com.android.tools.idea.testing.moveCaret
 import com.android.tools.idea.ui.resourcemanager.rendering.MultipleColorIcon
 import com.google.common.truth.Truth.assertThat
+import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl
+import com.intellij.openapi.application.runReadAction
 import com.intellij.openapi.command.WriteCommandAction
-import com.intellij.psi.util.parentOfType
 import com.intellij.testFramework.EdtRule
 import com.intellij.testFramework.RunsInEdt
-import com.intellij.testFramework.fixtures.CodeInsightTestUtil
 import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
 import com.intellij.testFramework.runInEdtAndGet
 import com.intellij.testFramework.runInEdtAndWait
+import java.awt.Color
 import org.jetbrains.android.AndroidAnnotatorUtil
 import org.jetbrains.android.compose.stubComposableAnnotation
-import com.intellij.openapi.application.runReadAction
-import org.jetbrains.kotlin.psi.KtCallExpression
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.rules.RuleChain
-import java.awt.Color
 
-/**
- * Tests for [ComposeColorAnnotator]
- */
-class ComposeColorAnnotatorTest {
-  @get:Rule
-  val projectRule = AndroidProjectRule.onDisk()
+/** Tests for [ComposeColorLineMarkerProviderDescriptor] */
+class ComposeColorLineMarkerProviderDescriptorTest {
+  @get:Rule val projectRule = AndroidProjectRule.onDisk()
 
-  private val myFixture: JavaCodeInsightTestFixture by lazy { projectRule.fixture as JavaCodeInsightTestFixture }
+  private val myFixture: JavaCodeInsightTestFixture by lazy { projectRule.fixture }
 
   @Before
   fun setUp() {
     (myFixture.module.getModuleSystem() as DefaultModuleSystem).usesCompose = true
     myFixture.addClass(
-      //language=java
+      // language=java
       """
       package androidx.compose.ui.graphics;
       class ColorSpace {
         public static final ColorSpace TEST_SPACE = ColorSpace();
       }
-      """)
+      """
+    )
     myFixture.addFileToProject(
       "src/com/androidx/compose/ui/graphics/Color.kt",
-      //language=kotlin
+      // language=kotlin
       """
       package androidx.compose.ui.graphics
       fun Color(color: Int): Long = 1L
@@ -81,15 +77,18 @@
         alpha: Float = 1f,
         colorSpace: ColorSpace? = null
       ): Long = 1L
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
   }
 
   @Test
   fun testColorLong() {
-    val psiFile = myFixture.addFileToProject(
-      "src/com/android/test/A.kt",
-      //language=kotlin
-      """
+    val psiFile =
+      myFixture.addFileToProject(
+        "src/com/android/test/A.kt",
+        // language=kotlin
+        """
       package com.android.test
       import androidx.compose.ui.graphics.Color
       class A {
@@ -101,7 +100,9 @@
           val secondaryVariant = Color(color = 0x8057AD28)
         }
       }
-      """.trimIndent())
+      """
+          .trimIndent()
+      )
     myFixture.configureFromExistingVirtualFile(psiFile.virtualFile)
     checkGutterIconInfos(
       listOf(
@@ -110,14 +111,14 @@
         Color(74, 138, 123, 255),
         Color(87, 173, 40, 255),
         Color(87, 173, 40, 128)
-      ),
-      includeClickAction = true
+      )
     )
     setNewColor("Co|lor(0xFF4A8A7B)", Color(0xFFAABBCC.toInt()))
     setNewColor("Co|lor(color = 0xFF57AD28)", Color(0xFFAABBCC.toInt()))
-    assertThat(myFixture.editor.document.text).isEqualTo(
-      //language=kotlin
-      """
+    assertThat(myFixture.editor.document.text)
+      .isEqualTo(
+        // language=kotlin
+        """
       package com.android.test
       import androidx.compose.ui.graphics.Color
       class A {
@@ -129,48 +130,54 @@
           val secondaryVariant = Color(color = 0x8057AD28)
         }
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
   }
 
   @Test
   fun testColorWithLeadingZero() {
-    val psiFile = myFixture.addFileToProject(
-      "src/com/android/test/A.kt",
-      //language=kotlin
-      """
+    val psiFile =
+      myFixture.addFileToProject(
+        "src/com/android/test/A.kt",
+        // language=kotlin
+        """
       package com.android.test
       import androidx.compose.ui.graphics.Color
       class A {
         val other = Color(0xFFFF0000)
       }
-      """.trimIndent())
+      """
+          .trimIndent()
+      )
     myFixture.configureFromExistingVirtualFile(psiFile.virtualFile)
     checkGutterIconInfos(
       listOf(
         Color(255, 0, 0, 255),
-      ),
-      includeClickAction = true
+      )
     )
     setNewColor("Co|lor(0xFFFF0000)", Color(0x0DFF0000, true))
-    assertThat(myFixture.editor.document.text).isEqualTo(
-      //language=kotlin
-      """
+    assertThat(myFixture.editor.document.text)
+      .isEqualTo(
+        // language=kotlin
+        """
       package com.android.test
       import androidx.compose.ui.graphics.Color
       class A {
         val other = Color(0x0DFF0000)
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
   }
 
   @Test
   fun testColorInt() {
-    val psiFile = myFixture.addFileToProject(
-      "src/com/android/test/A.kt",
-      //language=kotlin
-      """
+    val psiFile =
+      myFixture.addFileToProject(
+        "src/com/android/test/A.kt",
+        // language=kotlin
+        """
       package com.android.test
       import androidx.compose.ui.graphics.Color
       class A {
@@ -182,7 +189,9 @@
           val secondaryVariant = Color(color = 0x4057AD28)
         }
       }
-      """.trimIndent())
+      """
+          .trimIndent()
+      )
     myFixture.configureFromExistingVirtualFile(psiFile.virtualFile)
     checkGutterIconInfos(
       listOf(
@@ -190,14 +199,15 @@
         Color(74, 138, 123, 0),
         Color(74, 138, 123, 128),
         Color(87, 173, 40, 0),
-        Color(87, 173, 40, 64)),
-      includeClickAction = true
+        Color(87, 173, 40, 64)
+      )
     )
     setNewColor("Co|lor(0x4A8A7B)", Color(0xFFAABBCC.toInt()))
     setNewColor("Co|lor(color = 0x57AD28)", Color(0xFFAABBCC.toInt()))
-    assertThat(myFixture.editor.document.text).isEqualTo(
-      //language=kotlin
-      """
+    assertThat(myFixture.editor.document.text)
+      .isEqualTo(
+        // language=kotlin
+        """
       package com.android.test
       import androidx.compose.ui.graphics.Color
       class A {
@@ -209,15 +219,18 @@
           val secondaryVariant = Color(color = 0x4057AD28)
         }
       }
-      """.trimIndent())
+      """
+          .trimIndent()
+      )
   }
 
   @Test
   fun testColorInt_X3() {
-    val psiFile = myFixture.addFileToProject(
-      "src/com/android/test/A.kt",
-      //language=kotlin
-      """
+    val psiFile =
+      myFixture.addFileToProject(
+        "src/com/android/test/A.kt",
+        // language=kotlin
+        """
       package com.android.test
       import androidx.compose.ui.graphics.Color
       class A {
@@ -229,7 +242,9 @@
           val secondaryVariant = Color(green = 200, red = 180, blue = 120)
         }
       }
-      """.trimIndent())
+      """
+          .trimIndent()
+      )
     myFixture.configureFromExistingVirtualFile(psiFile.virtualFile)
     checkGutterIconInfos(
       listOf(
@@ -237,16 +252,17 @@
         Color(74, 138, 123),
         Color(170, 187, 204),
         Color(87, 173, 40),
-        Color(180, 200, 120)),
-      includeClickAction = true
+        Color(180, 200, 120)
+      )
     )
     setNewColor("Co|lor(0x4A, 0x8A, 0x7B)", Color(0xFFAABBCC.toInt()))
     setNewColor("Co|lor(170, 187, 204)", Color(0xFF406080.toInt()))
     setNewColor("Co|lor(red = 0x57, green = 0xAD, blue = 0x28)", Color(0xFFAABBCC.toInt()))
     setNewColor("Co|lor(green = 200, red = 180, blue = 120)", Color(0x80112233.toInt()))
-    assertThat(myFixture.editor.document.text).isEqualTo(
-      //language=kotlin
-      """
+    assertThat(myFixture.editor.document.text)
+      .isEqualTo(
+        // language=kotlin
+        """
       package com.android.test
       import androidx.compose.ui.graphics.Color
       class A {
@@ -258,15 +274,18 @@
           val secondaryVariant = Color(red = 17, green = 34, blue = 51, alpha = 255)
         }
       }
-      """.trimIndent())
+      """
+          .trimIndent()
+      )
   }
 
   @Test
   fun testColorInt_X4() {
-    val psiFile = myFixture.addFileToProject(
-      "src/com/android/test/A.kt",
-      //language=kotlin
-      """
+    val psiFile =
+      myFixture.addFileToProject(
+        "src/com/android/test/A.kt",
+        // language=kotlin
+        """
       package com.android.test
       import androidx.compose.ui.graphics.Color
       class A {
@@ -278,7 +297,9 @@
           val secondaryVariant = Color(green = 120, red = 64, alpha = 255, blue = 192)
         }
       }
-      """.trimIndent())
+      """
+          .trimIndent()
+      )
     myFixture.configureFromExistingVirtualFile(psiFile.virtualFile)
     checkGutterIconInfos(
       listOf(
@@ -286,14 +307,15 @@
         Color(74, 138, 123),
         Color(170, 187, 204),
         Color(87, 173, 40),
-        Color(64, 120, 192)),
-      includeClickAction = true
+        Color(64, 120, 192)
+      )
     )
     setNewColor("Co|lor(0x4A, 0x8A, 0x7B, 0xFF)", Color(0xFFAABBCC.toInt()))
     setNewColor("Co|lor(green = 120, red = 64, alpha = 255, blue = 192)", Color(0xFFAABBCC.toInt()))
-    assertThat(myFixture.editor.document.text).isEqualTo(
-      //language=kotlin
-      """
+    assertThat(myFixture.editor.document.text)
+      .isEqualTo(
+        // language=kotlin
+        """
       package com.android.test
       import androidx.compose.ui.graphics.Color
       class A {
@@ -305,16 +327,18 @@
           val secondaryVariant = Color(red = 170, green = 187, blue = 204, alpha = 255)
         }
       }
-      """.trimIndent())
+      """
+          .trimIndent()
+      )
   }
 
-
   @Test
   fun testColorFloat_X3() {
-    val psiFile = myFixture.addFileToProject(
-      "src/com/android/test/A.kt",
-      //language=kotlin
-      """
+    val psiFile =
+      myFixture.addFileToProject(
+        "src/com/android/test/A.kt",
+        // language=kotlin
+        """
       package com.android.test
       import androidx.compose.ui.graphics.Color
       class A {
@@ -326,7 +350,9 @@
           val primaryVariant = Color(green = 0.68f, red = 0.34f, blue = 0.15f)
         }
       }
-      """.trimIndent())
+      """
+          .trimIndent()
+      )
     myFixture.configureFromExistingVirtualFile(psiFile.virtualFile)
     checkGutterIconInfos(
       listOf(
@@ -334,14 +360,15 @@
         Color(77, 138, 122),
         Color(77, 138, 122),
         Color(87, 173, 38),
-        Color(87, 173, 38)),
-      includeClickAction = true
+        Color(87, 173, 38)
+      )
     )
     setNewColor("Co|lor(0.3f, 0.54f, 0.48f)", Color(0xFFAABBCC.toInt()))
     setNewColor("Co|lor(green = 0.68f, red = 0.34f, blue = 0.15f)", Color(0xFFAABBCC.toInt()))
-    assertThat(myFixture.editor.document.text).isEqualTo(
-      //language=kotlin
-      """
+    assertThat(myFixture.editor.document.text)
+      .isEqualTo(
+        // language=kotlin
+        """
       package com.android.test
       import androidx.compose.ui.graphics.Color
       class A {
@@ -353,15 +380,18 @@
           val primaryVariant = Color(red = 0.667f, green = 0.733f, blue = 0.8f, alpha = 1.0f)
         }
       }
-      """.trimIndent())
+      """
+          .trimIndent()
+      )
   }
 
   @Test
   fun testColorFloat_X4() {
-    val psiFile = myFixture.addFileToProject(
-      "src/com/android/test/A.kt",
-      //language=kotlin
-      """
+    val psiFile =
+      myFixture.addFileToProject(
+        "src/com/android/test/A.kt",
+        // language=kotlin
+        """
       package com.android.test
       import androidx.compose.ui.graphics.Color
       class A {
@@ -373,7 +403,9 @@
           val primaryVariant = Color(alpha = 0.25f, green = 0.173f, blue = 0.4f, red = 0.87f)
         }
       }
-      """.trimIndent())
+      """
+          .trimIndent()
+      )
     myFixture.configureFromExistingVirtualFile(psiFile.virtualFile)
     checkGutterIconInfos(
       listOf(
@@ -381,14 +413,18 @@
         Color(189, 35, 77, 215),
         Color(189, 35, 77, 215),
         Color(222, 44, 102, 64),
-        Color(222, 44, 102, 64)),
-      includeClickAction = true
+        Color(222, 44, 102, 64)
+      )
     )
     setNewColor("Co|lor(0.74f, 0.138f, 0.3f, 0.845f)", Color(0xFFAABBCC.toInt()))
-    setNewColor("Co|lor(alpha = 0.25f, green = 0.173f, blue = 0.4f, red = 0.87f)", Color(0xFFAABBCC.toInt()))
-    assertThat(myFixture.editor.document.text).isEqualTo(
-      //language=kotlin
-      """
+    setNewColor(
+      "Co|lor(alpha = 0.25f, green = 0.173f, blue = 0.4f, red = 0.87f)",
+      Color(0xFFAABBCC.toInt())
+    )
+    assertThat(myFixture.editor.document.text)
+      .isEqualTo(
+        // language=kotlin
+        """
       package com.android.test
       import androidx.compose.ui.graphics.Color
       class A {
@@ -400,16 +436,20 @@
           val primaryVariant = Color(red = 0.667f, green = 0.733f, blue = 0.8f, alpha = 1.0f)
         }
       }
-      """.trimIndent())
+      """
+          .trimIndent()
+      )
   }
 
   @Test
   fun testColorFloat_X4_ColorSpace() {
-    // Note: We don't offer neither color preview nor picker for Color(Float, Float, Float, Float, ColorSpace) function.
-    val psiFile = myFixture.addFileToProject(
-      "src/com/android/test/A.kt",
-      //language=kotlin
-      """
+    // Note: We don't offer neither color preview nor picker for Color(Float, Float, Float, Float,
+    // ColorSpace) function.
+    val psiFile =
+      myFixture.addFileToProject(
+        "src/com/android/test/A.kt",
+        // language=kotlin
+        """
       package com.android.test
       import androidx.compose.ui.graphics.Color
       import androidx.compose.ui.graphics.ColorSpace
@@ -422,53 +462,67 @@
           val primaryVariant = Color(red = 1.0f, green = 1.0f, blue = 1.0f, alpha = 1.0f, colorSpace = ColorSpace.TEST_SPACE)
         }
       }
-      """.trimIndent())
+      """
+          .trimIndent()
+      )
     myFixture.configureFromExistingVirtualFile(psiFile.virtualFile)
     // No gutter for color space.
-    checkGutterIconInfos(listOf(), includeClickAction = false)
+    checkGutterIconInfos(listOf())
   }
 
   private fun setNewColor(window: String, newColor: Color) {
     val element = runInEdtAndGet { myFixture.moveCaret(window) }
-    val annotations = runReadAction {
-      CodeInsightTestUtil.testAnnotator(ComposeColorAnnotator(), element.parentOfType<KtCallExpression>()!!)
+
+    myFixture.doHighlighting()
+    val highlightInfo = runReadAction {
+      DaemonCodeAnalyzerImpl.getLineMarkers(myFixture.editor.document, myFixture.project).single {
+        lineMarkerInfo ->
+        lineMarkerInfo.navigationHandler is ColorIconRenderer && lineMarkerInfo.element == element
+      }
     }
+
     runInEdtAndWait {
-      val iconRenderer = annotations[0].gutterIconRenderer as ColorIconRenderer
       val project = myFixture.project
-      val setColorTask = iconRenderer.getSetColorTask() ?: return@runInEdtAndWait
-      WriteCommandAction.runWriteCommandAction(project, "Change Color", null, { setColorTask.invoke(newColor) })
+      val setColorTask =
+        (highlightInfo.navigationHandler as ColorIconRenderer).getSetColorTask()
+          ?: return@runInEdtAndWait
+      WriteCommandAction.runWriteCommandAction(
+        project,
+        "Change Color",
+        null,
+        { setColorTask.invoke(newColor) }
+      )
     }
   }
 
-  private fun checkGutterIconInfos(expectedColorIcons: List<Color>, includeClickAction: Boolean) {
-    val iconList = myFixture.doHighlighting().filter { it.gutterIconRenderer is ColorIconRenderer }.sortedBy { it.startOffset }
-    assertThat(iconList).hasSize(expectedColorIcons.size)
-    iconList.forEach {
-      assertThat(it.gutterIconRenderer.icon).isNotNull()
-      if (includeClickAction) {
-        val action = runReadAction { (it.gutterIconRenderer as ColorIconRenderer).clickAction }
-        assertThat(action).isNotNull()
-      }
-      else {
-        val action = runReadAction { (it.gutterIconRenderer as ColorIconRenderer).clickAction }
-        assertThat(action).isNull()
-      }
+  private fun checkGutterIconInfos(expectedColorIcons: List<Color>) {
+    myFixture.doHighlighting()
+    val highlightInfos = runReadAction {
+      DaemonCodeAnalyzerImpl.getLineMarkers(myFixture.editor.document, myFixture.project)
+        .filter { lineMarkerInfo -> lineMarkerInfo.navigationHandler is ColorIconRenderer }
+        .sortedBy { it.startOffset }
     }
-    assertThat(iconList.map { (it.gutterIconRenderer as ColorIconRenderer).color }).containsExactlyElementsIn(expectedColorIcons)
+
+    assertThat(highlightInfos).hasSize(expectedColorIcons.size)
+    highlightInfos.forEach {
+      assertThat(it.icon).isNotNull()
+      assertThat(it.navigationHandler).isNotNull()
+    }
+
+    assertThat(highlightInfos.map { (it.navigationHandler as ColorIconRenderer).color })
+      .containsExactlyElementsIn(expectedColorIcons)
   }
 }
 
-/**
- * Tests for [AndroidKotlinResourceExternalAnnotator]
- */
+/** Tests for [AndroidKotlinResourceExternalAnnotator] */
 class ComposeColorReferenceAnnotatorTest {
   private val projectRule = AndroidProjectRule.onDisk()
 
-  @get:Rule
-  val ruleChain: RuleChain = RuleChain.outerRule(projectRule).around(EdtRule())
+  @get:Rule val ruleChain: RuleChain = RuleChain.outerRule(projectRule).around(EdtRule())
 
-  private val myFixture: JavaCodeInsightTestFixture by lazy { projectRule.fixture as JavaCodeInsightTestFixture }
+  private val myFixture: JavaCodeInsightTestFixture by lazy {
+    projectRule.fixture as JavaCodeInsightTestFixture
+  }
 
   @Before
   fun setUp() {
@@ -476,7 +530,10 @@
     myFixture.stubComposableAnnotation()
     myFixture.testDataPath = getComposePluginTestDataPath()
     myFixture.copyFileToProject("annotator/colors.xml", "res/values/colors.xml")
-    myFixture.copyFileToProject("annotator/AndroidManifest.xml", SdkConstants.FN_ANDROID_MANIFEST_XML)
+    myFixture.copyFileToProject(
+      "annotator/AndroidManifest.xml",
+      SdkConstants.FN_ANDROID_MANIFEST_XML
+    )
   }
 
   // Regression test for https://issuetracker.google.com/144560843
@@ -496,11 +553,13 @@
         val drawable = R.drawable.ic_tick
         val color = R.color.color1
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     val icons = myFixture.findAllGutters()
-    val colorGutterIconRenderer = icons.first {it is AndroidAnnotatorUtil.ColorRenderer}
-    assertThat((colorGutterIconRenderer.icon as MultipleColorIcon).colors).containsExactlyElementsIn(arrayOf(Color(63, 81, 181)))
+    val colorGutterIconRenderer = icons.first { it is AndroidAnnotatorUtil.ColorRenderer }
+    assertThat((colorGutterIconRenderer.icon as MultipleColorIcon).colors)
+      .containsExactlyElementsIn(arrayOf(Color(63, 81, 181)))
   }
 }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeFoldingBuilderTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeFoldingBuilderTest.kt
index 0e99c99..430eabb 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeFoldingBuilderTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeFoldingBuilderTest.kt
@@ -15,7 +15,6 @@
  */
 package com.android.tools.compose
 
-
 import com.android.tools.idea.project.DefaultModuleSystem
 import com.android.tools.idea.projectsystem.getModuleSystem
 import com.android.tools.idea.testing.AndroidProjectRule
@@ -27,14 +26,13 @@
 import org.junit.Rule
 import org.junit.Test
 
-/**
- * Test for [ComposeFoldingBuilder].
- */
+/** Test for [ComposeFoldingBuilder]. */
 class ComposeFoldingBuilderTest {
-  @get:Rule
-  val projectRule = AndroidProjectRule.inMemory()
+  @get:Rule val projectRule = AndroidProjectRule.inMemory()
 
-  private val myFixture: CodeInsightTestFixtureImpl by lazy { projectRule.fixture as CodeInsightTestFixtureImpl }
+  private val myFixture: CodeInsightTestFixtureImpl by lazy {
+    projectRule.fixture as CodeInsightTestFixtureImpl
+  }
 
   @Before
   fun setUp() {
@@ -52,17 +50,19 @@
         fun adjust():Modifier {}
       }
     }
-    """.trimIndent()
+    """
+        .trimIndent()
     )
   }
 
   @Test
   fun test() {
-    // We can't use standard [myFixture.testFolding] because we need properly load file to be able resolve references inside
+    // We can't use standard [myFixture.testFolding] because we need properly load file to be able
+    // resolve references inside
     // [ComposeFoldingBuilder].
     myFixture.loadNewFile(
       "src/com/example/Test.kt",
-      //language=kotlin
+      // language=kotlin
       """
       package com.example
 
@@ -75,12 +75,15 @@
           .adjust()
           .adjust()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     val res = myFixture.getFoldingDescription(false)
 
-    assertThat(res).isEqualTo("""
+    assertThat(res)
+      .isEqualTo(
+        """
       package com.example
 
       import <fold text='...'>androidx.compose.runtime.Composable
@@ -92,6 +95,8 @@
           .adjust()
           .adjust()</fold>
       }</fold>
-    """.trimIndent())
+    """
+          .trimIndent()
+      )
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeOverrideImplementsAnnotationsFilterTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeOverrideImplementsAnnotationsFilterTest.kt
index 4970c9b..23c0349 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeOverrideImplementsAnnotationsFilterTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeOverrideImplementsAnnotationsFilterTest.kt
@@ -27,11 +27,13 @@
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
 
-/** Tests both [ComposeOverrideImplementsAnnotationsFilter] and that it's defined correctly in extension XML. */
+/**
+ * Tests both [ComposeOverrideImplementsAnnotationsFilter] and that it's defined correctly in
+ * extension XML.
+ */
 @RunWith(JUnit4::class)
 class ComposeOverrideImplementsAnnotationsFilterTest {
-  @get:Rule
-  var projectRule = AndroidProjectRule.inMemory()
+  @get:Rule var projectRule = AndroidProjectRule.inMemory()
 
   @Before
   fun setup() {
@@ -42,10 +44,11 @@
   @Test
   fun composableAnnotationRetainedOnFunction() {
     val fixture = projectRule.fixture
-    val file = fixture.loadNewFile(
-      "src/com/example/Foo.kt",
-      // language=kotlin
-      """
+    val file =
+      fixture.loadNewFile(
+        "src/com/example/Foo.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -57,10 +60,13 @@
 
       class Impleme<caret>ntation : Interface {
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
-    val intention = fixture.availableIntentions.singleOrNull { it.familyName == "Implement members" } ?: error("Intention not found")
+    val intention =
+      fixture.availableIntentions.singleOrNull { it.familyName == "Implement members" }
+        ?: error("Intention not found")
     WriteCommandAction.runWriteCommandAction(projectRule.project) {
       intention.invoke(fixture.project, fixture.editor, file)
     }
@@ -83,7 +89,8 @@
               TODO("Not yet implemented")
           }
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -91,10 +98,11 @@
   fun composableAnnotationRetainedOnArgument() {
 
     val fixture = projectRule.fixture
-    val file = fixture.loadNewFile(
-      "src/com/example/Foo.kt",
-      // language=kotlin
-      """
+    val file =
+      fixture.loadNewFile(
+        "src/com/example/Foo.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -105,10 +113,13 @@
 
       class Impleme<caret>ntation : Interface {
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
-    val intention = fixture.availableIntentions.singleOrNull { it.familyName == "Implement members" } ?: error("Intention not found")
+    val intention =
+      fixture.availableIntentions.singleOrNull { it.familyName == "Implement members" }
+        ?: error("Intention not found")
     WriteCommandAction.runWriteCommandAction(projectRule.project) {
       intention.invoke(fixture.project, fixture.editor, file)
     }
@@ -129,7 +140,8 @@
               TODO("Not yet implemented")
           }
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeSampleResolutionServiceTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeSampleResolutionServiceTest.kt
index b2928d8..a5f33d6 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeSampleResolutionServiceTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeSampleResolutionServiceTest.kt
@@ -15,8 +15,6 @@
  */
 package com.android.tools.compose
 
-import com.android.builder.model.SyncIssue
-import com.android.ide.gradle.model.artifacts.AdditionalClassifierArtifactsModel
 import com.android.tools.idea.flags.StudioFlags
 import com.android.tools.idea.gradle.LibraryFilePaths
 import com.android.tools.idea.testing.AndroidGradleTestCase
@@ -27,17 +25,15 @@
 import com.intellij.openapi.vfs.VfsUtil
 import com.intellij.psi.util.PsiTreeUtil
 import com.intellij.util.PathUtil
+import java.io.File
+import java.nio.file.Paths
 import org.jetbrains.annotations.SystemIndependent
 import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
 import org.jetbrains.kotlin.idea.references.mainReference
 import org.jetbrains.kotlin.kdoc.psi.impl.KDocName
 import org.jetbrains.kotlin.psi.KtNamedFunction
-import java.io.File
-import java.nio.file.Paths
 
-/**
- * Tests for [ComposeSampleResolutionService]
- */
+/** Tests for [ComposeSampleResolutionService] */
 class ComposeSampleResolutionServiceTest : AndroidGradleTestCase() {
   override fun setUp() {
     super.setUp()
@@ -45,10 +41,16 @@
     StudioFlags.SAMPLES_SUPPORT_ENABLED.override(true)
   }
 
-  override fun getTestDataDirectoryWorkspaceRelativePath(): @SystemIndependent String = "tools/adt/idea/compose-ide-plugin/testData"
+  override fun getTestDataDirectoryWorkspaceRelativePath(): @SystemIndependent String =
+    "tools/adt/idea/compose-ide-plugin/testData"
 
-  override fun getAdditionalRepos() = listOf(
-    File(getComposePluginTestDataPath(), PathUtil.toSystemDependentName(TestProjectPaths.REPO_FOR_SAMPLES_ARTIFACT_TEST)))
+  override fun getAdditionalRepos() =
+    listOf(
+      File(
+        getComposePluginTestDataPath(),
+        PathUtil.toSystemDependentName(TestProjectPaths.REPO_FOR_SAMPLES_ARTIFACT_TEST)
+      )
+    )
 
   fun testDownloadingAndAttachingSamples() {
     loadProject(TestProjectPaths.APP_WITH_LIB_WITH_SAMPLES)
@@ -59,10 +61,13 @@
     // We download samples only for androidx libraries.
     assume().that(samples).isNull()
 
-    val androidxSamples = libraryFilePaths.getCachedPathsForArtifact("androidx.ui:lib:3.0")?.sampleSource
+    val androidxSamples =
+      libraryFilePaths.getCachedPathsForArtifact("androidx.ui:lib:3.0")?.sampleSource
     assume().that(androidxSamples).isNotNull()
-    // Note: the classifer here is not the same as what is required by the Gradle metadata, this was an accident but we leave
-    // as is to also test that this actually correctly picks up the name of the artifact by relying on the Gradle module metadata rather
+    // Note: the classifer here is not the same as what is required by the Gradle metadata, this was
+    // an accident but we leave
+    // as is to also test that this actually correctly picks up the name of the artifact by relying
+    // on the Gradle module metadata rather
     // than just the classifer.
     assertThat(androidxSamples!!.name).isEqualTo("lib-3.0-samplesources.jar")
   }
@@ -70,7 +75,11 @@
   fun testResolveSampleReference() {
     loadProject(TestProjectPaths.APP_WITH_LIB_WITH_SAMPLES)
 
-    val file = VfsUtil.findFile(Paths.get(project.basePath, "/app/src/main/java/com/example/appforsamplestest/Main.kt"), false)
+    val file =
+      VfsUtil.findFile(
+        Paths.get(project.basePath, "/app/src/main/java/com/example/appforsamplestest/Main.kt"),
+        false
+      )
     assume().that(file).isNotNull()
     myFixture.openFileInEditor(file!!)
 
@@ -79,8 +88,11 @@
     assume().that(librarySourceFunction).isNotNull()
 
     val sampleTag = librarySourceFunction.docComment!!.getDefaultSection().findTagByName("sample")!!
-    val sample = PsiTreeUtil.findChildOfType<KDocName>(sampleTag, KDocName::class.java)?.mainReference?.resolve()
+    val sample =
+      PsiTreeUtil.findChildOfType<KDocName>(sampleTag, KDocName::class.java)
+        ?.mainReference
+        ?.resolve()
     assume().that(sample).isNotNull()
     assertThat(sample!!.getKotlinFqName()!!.asString()).isEqualTo("app.samples.sampleFunction")
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeSuppressorTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeSuppressorTest.kt
index ae9cda8..546f484 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeSuppressorTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeSuppressorTest.kt
@@ -19,18 +19,18 @@
 import org.jetbrains.android.compose.stubComposableAnnotation
 import org.jetbrains.kotlin.idea.inspections.FunctionNameInspection
 
-/**
- * Test for [ComposeSuppressor].
- */
+/** Test for [ComposeSuppressor]. */
 class ComposeSuppressorTest : JavaCodeInsightFixtureTestCase() {
 
-  fun testFunctionNameWarning(): Unit = myFixture.run {
-    enableInspections(FunctionNameInspection::class.java)
-    stubComposableAnnotation()
+  fun testFunctionNameWarning(): Unit =
+    myFixture.run {
+      enableInspections(FunctionNameInspection::class.java)
+      stubComposableAnnotation()
 
-    val file = addFileToProject(
-      "src/com/example/views.kt",
-      """
+      val file =
+        addFileToProject(
+          "src/com/example/views.kt",
+          """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -39,10 +39,11 @@
       fun MyView() {}
 
       fun <weak_warning descr="Function name 'NormalFunction' should start with a lowercase letter">NormalFunction</weak_warning>() {}
-      """.trimIndent()
-    )
+      """
+            .trimIndent()
+        )
 
-    configureFromExistingVirtualFile(file.virtualFile)
-    checkHighlighting()
-  }
+      configureFromExistingVirtualFile(file.virtualFile)
+      checkHighlighting()
+    }
 }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeUsageGroupingRuleProviderTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeUsageGroupingRuleProviderTest.kt
index 466abe4..cca5948 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeUsageGroupingRuleProviderTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/ComposeUsageGroupingRuleProviderTest.kt
@@ -15,7 +15,6 @@
  */
 package com.android.tools.compose
 
-
 import androidx.compose.compiler.plugins.kotlin.ComposeFqNames
 import com.android.testutils.MockitoKt.mock
 import com.android.tools.idea.project.DefaultModuleSystem
@@ -46,17 +45,19 @@
 /** Test basic cases for the [ComposeUsageGroupingRuleProvider]. */
 @RunWith(JUnit4::class)
 class ComposeUsageGroupingRuleProviderTest {
-  @get:Rule
-  val projectRule = AndroidProjectRule.onDisk()
+  @get:Rule val projectRule = AndroidProjectRule.onDisk()
 
   private val project by lazy { projectRule.project }
 
   private val groupingRuleProvider = ComposeUsageGroupingRuleProvider()
-  private val groupingRule by lazy { groupingRuleProvider.getActiveRules(project).single() as UsageGroupingRuleEx }
+  private val groupingRule by lazy {
+    groupingRuleProvider.getActiveRules(project).single() as UsageGroupingRuleEx
+  }
 
   @Test
   fun activeRulesAreAllRules() {
-    assertThat(groupingRuleProvider.getActiveRules(project)).isEqualTo(groupingRuleProvider.getAllRules(project, null))
+    assertThat(groupingRuleProvider.getActiveRules(project))
+      .isEqualTo(groupingRuleProvider.getAllRules(project, null))
   }
 
   @Test
@@ -72,8 +73,10 @@
 
   @Test
   fun groupingRuleHasCorrectRank() {
-    assertThat(groupingRule.rank).isGreaterThan(UsageGroupingRulesDefaultRanks.AFTER_SCOPE.absoluteRank)
-    assertThat(groupingRule.rank).isAtMost(UsageGroupingRulesDefaultRanks.BEFORE_USAGE_TYPE.absoluteRank)
+    assertThat(groupingRule.rank)
+      .isGreaterThan(UsageGroupingRulesDefaultRanks.AFTER_SCOPE.absoluteRank)
+    assertThat(groupingRule.rank)
+      .isAtMost(UsageGroupingRulesDefaultRanks.BEFORE_USAGE_TYPE.absoluteRank)
   }
 
   @Test
@@ -89,12 +92,14 @@
 
   @Test
   fun previewGroupHasCorrectText() {
-    assertThat(PreviewUsageGroup.presentableGroupText).isEqualTo(ComposeBundle.message("usage.group.in.preview.function"))
+    assertThat(PreviewUsageGroup.presentableGroupText)
+      .isEqualTo(ComposeBundle.message("usage.group.in.preview.function"))
   }
 
   @Test
   fun productionGroupHasCorrectText() {
-    assertThat(ProductionUsageGroup.presentableGroupText).isEqualTo(ComposeBundle.message("usage.group.in.nonpreview.function"))
+    assertThat(ProductionUsageGroup.presentableGroupText)
+      .isEqualTo(ComposeBundle.message("usage.group.in.nonpreview.function"))
   }
 
   @Test
@@ -106,34 +111,39 @@
   }
 }
 
-/** Test more complex cases for the [ComposeUsageGroupingRuleProvider], covering all relevant potential annotations. */
+/**
+ * Test more complex cases for the [ComposeUsageGroupingRuleProvider], covering all relevant
+ * potential annotations.
+ */
 @RunWith(Parameterized::class)
 class ComposeUsageGroupingRuleProviderParameterizedTest(
   private val targetAnnotations: List<String>,
   private val usageAnnotations: List<String>
 ) {
-  @get:Rule
-  val projectRule = AndroidProjectRule.onDisk().onEdt()
+  @get:Rule val projectRule = AndroidProjectRule.onDisk().onEdt()
 
   private val fixture by lazy { projectRule.fixture }
   private val project by lazy { projectRule.project }
 
   private val groupingRuleProvider = ComposeUsageGroupingRuleProvider()
-  private val groupingRule by lazy { groupingRuleProvider.getActiveRules(project).single() as UsageGroupingRuleEx }
+  private val groupingRule by lazy {
+    groupingRuleProvider.getActiveRules(project).single() as UsageGroupingRuleEx
+  }
 
   companion object {
     @Parameterized.Parameters(name = "{0}_target_{1}_element")
     @JvmStatic
-    fun data(): List<Array<List<String>>> = listOf(
-      arrayOf(listOf(), listOf()),
-      arrayOf(listOf(), listOf(COMPOSABLE)),
-      arrayOf(listOf(), listOf(PREVIEW)),
-      arrayOf(listOf(), listOf(PREVIEW, COMPOSABLE)),
-      arrayOf(listOf(COMPOSABLE), listOf()),
-      arrayOf(listOf(COMPOSABLE), listOf(COMPOSABLE)),
-      arrayOf(listOf(COMPOSABLE), listOf(PREVIEW)),
-      arrayOf(listOf(COMPOSABLE), listOf(PREVIEW, COMPOSABLE)),
-    )
+    fun data(): List<Array<List<String>>> =
+      listOf(
+        arrayOf(listOf(), listOf()),
+        arrayOf(listOf(), listOf(COMPOSABLE)),
+        arrayOf(listOf(), listOf(PREVIEW)),
+        arrayOf(listOf(), listOf(PREVIEW, COMPOSABLE)),
+        arrayOf(listOf(COMPOSABLE), listOf()),
+        arrayOf(listOf(COMPOSABLE), listOf(COMPOSABLE)),
+        arrayOf(listOf(COMPOSABLE), listOf(PREVIEW)),
+        arrayOf(listOf(COMPOSABLE), listOf(PREVIEW, COMPOSABLE)),
+      )
 
     private const val COMPOSABLE = "Composable"
     private const val PREVIEW = "Preview"
@@ -142,42 +152,67 @@
   @RunsInEdt
   @Test
   fun getParentGroupsFor() {
-    val (usage, targets) = fixture.configureCode(
-      targetAnnotations, usageAnnotations, "target|Function() // usage", "fun target|Function()")
+    val (usage, targets) =
+      fixture.configureCode(
+        targetAnnotations,
+        usageAnnotations,
+        "target|Function() // usage",
+        "fun target|Function()"
+      )
     checkUsageGroups(groupingRule.getParentGroupsFor(usage, targets))
   }
 
   @RunsInEdt
   @Test
   fun getParentGroupsFor_nested() {
-    val (usage, targets) = fixture.configureCode(
-      targetAnnotations, usageAnnotations, "target|Function() // nested usage", "fun target|Function()")
+    val (usage, targets) =
+      fixture.configureCode(
+        targetAnnotations,
+        usageAnnotations,
+        "target|Function() // nested usage",
+        "fun target|Function()"
+      )
     checkUsageGroups(groupingRule.getParentGroupsFor(usage, targets))
   }
 
   @RunsInEdt
   @Test
   fun ignoresNonKtFunctionTarget() {
-    val (usage, targets) = fixture.configureCode(
-      targetAnnotations, usageAnnotations, "target|Function() // usage", "PROP|ERTY", "fun target|Function()")
+    val (usage, targets) =
+      fixture.configureCode(
+        targetAnnotations,
+        usageAnnotations,
+        "target|Function() // usage",
+        "PROP|ERTY",
+        "fun target|Function()"
+      )
     checkUsageGroups(groupingRule.getParentGroupsFor(usage, targets))
   }
 
   @RunsInEdt
   @Test
   fun ignoresNonPsiElementTarget() {
-    val (usage, targets) = fixture.configureCode(
-      targetAnnotations, usageAnnotations, "target|Function() // usage", "fun target|Function()")
+    val (usage, targets) =
+      fixture.configureCode(
+        targetAnnotations,
+        usageAnnotations,
+        "target|Function() // usage",
+        "fun target|Function()"
+      )
     val usageTarget: UsageTarget = mock()
     checkUsageGroups(groupingRule.getParentGroupsFor(usage, arrayOf(usageTarget, *targets)))
     verifyNoInteractions(usageTarget)
   }
 
-  /** Asserts that we get [PreviewUsageGroup] iff all the annotations are present, else [ProductionUsageGroup]. */
+  /**
+   * Asserts that we get [PreviewUsageGroup] iff all the annotations are present, else
+   * [ProductionUsageGroup].
+   */
   private fun checkUsageGroups(usageGroups: List<UsageGroup>) {
     when {
       COMPOSABLE !in targetAnnotations -> assertThat(usageGroups).isEmpty()
-      COMPOSABLE in usageAnnotations && PREVIEW in usageAnnotations -> assertThat(usageGroups).containsExactly(PreviewUsageGroup)
+      COMPOSABLE in usageAnnotations && PREVIEW in usageAnnotations ->
+        assertThat(usageGroups).containsExactly(PreviewUsageGroup)
       else -> assertThat(usageGroups).containsExactly(ProductionUsageGroup)
     }
   }
@@ -210,12 +245,14 @@
         }
         targetFunction() // usage
       }
-      """.trimIndent()
+      """
+        .trimIndent()
 
     val file = addFileToProject("/src/the/regrettes/LaDiDa.kt", contents)
     openFileInEditor(file.virtualFile)
     val element = findParentElement<PsiElement>(elementWindow)
-    val targets = targetWindows.map { findParentElement<PsiElement>(it) }.map(::TestUsageTarget).toTypedArray()
+    val targets =
+      targetWindows.map { findParentElement<PsiElement>(it) }.map(::TestUsageTarget).toTypedArray()
 
     return TestUsage(element) to targets
   }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/TestUtils.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/TestUtils.kt
index c75746f..9f3a6f4 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/TestUtils.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/TestUtils.kt
@@ -19,8 +19,8 @@
 import com.intellij.openapi.application.ex.PathManagerEx
 import java.nio.file.Files
 
-fun getComposePluginTestDataPath():String {
+fun getComposePluginTestDataPath(): String {
   val adtPath = resolveWorkspacePath("tools/adt/idea/compose-ide-plugin/testData")
   return if (Files.exists(adtPath)) adtPath.toString()
-         else PathManagerEx.findFileUnderCommunityHome("plugins/android-compose-ide-plugin").path
+  else PathManagerEx.findFileUnderCommunityHome("plugins/android-compose-ide-plugin").path
 }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/analysis/ComposableDeclarationCheckerTests.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/analysis/ComposableDeclarationCheckerTests.kt
index 732b9f4..2a0555a 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/analysis/ComposableDeclarationCheckerTests.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/analysis/ComposableDeclarationCheckerTests.kt
@@ -474,10 +474,11 @@
 
   @Test
   fun testMissingOverrideComposableLambda() {
-    val functionDeclarationWithError = if (!isK2Plugin())
-      "<error descr=\"[CONFLICTING_OVERLOADS] @Composable annotation mismatch with overridden function: public open fun invoke(): Unit defined in com.example.Impl, public abstract operator fun invoke(): Unit defined in kotlin.Function0\" textAttributesKey=\"ERRORS_ATTRIBUTES\">override fun invoke()</error> {}"
-    else
-      "<error descr=\"[CONFLICTING_OVERLOADS] Conflicting overloads: [fun invoke(): Unit, @Composable() fun invoke(): R]\" textAttributesKey=\"ERRORS_ATTRIBUTES\">override fun invoke()</error> {}"
+    val functionDeclarationWithError =
+      if (!isK2Plugin())
+        "<error descr=\"[CONFLICTING_OVERLOADS] @Composable annotation mismatch with overridden function: public open fun invoke(): Unit defined in com.example.Impl, public abstract operator fun invoke(): Unit defined in kotlin.Function0\" textAttributesKey=\"ERRORS_ATTRIBUTES\">override fun invoke()</error> {}"
+      else
+        "<error descr=\"[CONFLICTING_OVERLOADS] Conflicting overloads: [fun invoke(): Unit, @Composable() fun invoke(): R]\" textAttributesKey=\"ERRORS_ATTRIBUTES\">override fun invoke()</error> {}"
     doTest(
       """
                 import androidx.compose.runtime.Composable
@@ -491,10 +492,11 @@
 
   @Test
   fun testWrongOverrideLambda() {
-    val functionDeclarationWithError = if (!isK2Plugin())
-      "<error descr=\"[CONFLICTING_OVERLOADS] @Composable annotation mismatch with overridden function: @Composable public open fun invoke(): Unit defined in com.example.Impl, public abstract operator fun invoke(): Unit defined in kotlin.Function0\" textAttributesKey=\"ERRORS_ATTRIBUTES\">@Composable override fun invoke()</error> {}"
-    else
-      "<error descr=\"[CONFLICTING_OVERLOADS] Conflicting overloads: [@Composable() fun invoke(): Unit, fun invoke(): R]\" textAttributesKey=\"ERRORS_ATTRIBUTES\">@Composable override fun invoke()</error> {}"
+    val functionDeclarationWithError =
+      if (!isK2Plugin())
+        "<error descr=\"[CONFLICTING_OVERLOADS] @Composable annotation mismatch with overridden function: @Composable public open fun invoke(): Unit defined in com.example.Impl, public abstract operator fun invoke(): Unit defined in kotlin.Function0\" textAttributesKey=\"ERRORS_ATTRIBUTES\">@Composable override fun invoke()</error> {}"
+      else
+        "<error descr=\"[CONFLICTING_OVERLOADS] Conflicting overloads: [@Composable() fun invoke(): Unit, fun invoke(): R]\" textAttributesKey=\"ERRORS_ATTRIBUTES\">@Composable override fun invoke()</error> {}"
     doTest(
       """
                 import androidx.compose.runtime.Composable
@@ -508,10 +510,11 @@
 
   @Test
   fun testMultipleOverrideLambda() {
-    val functionDeclarationWithError = if (!isK2Plugin())
-      "<error descr=\"[CONFLICTING_OVERLOADS] @Composable annotation mismatch with overridden function: @Composable public open fun invoke(): Unit defined in com.example.Impl, public abstract operator fun invoke(): Unit defined in kotlin.Function0\" textAttributesKey=\"ERRORS_ATTRIBUTES\">@Composable override fun invoke()</error> {}"
-    else
-      "<error descr=\"[CONFLICTING_OVERLOADS] Conflicting overloads: [@Composable() fun invoke(): Unit, fun invoke(): R]\" textAttributesKey=\"ERRORS_ATTRIBUTES\">@Composable override fun invoke()</error> {}"
+    val functionDeclarationWithError =
+      if (!isK2Plugin())
+        "<error descr=\"[CONFLICTING_OVERLOADS] @Composable annotation mismatch with overridden function: @Composable public open fun invoke(): Unit defined in com.example.Impl, public abstract operator fun invoke(): Unit defined in kotlin.Function0\" textAttributesKey=\"ERRORS_ATTRIBUTES\">@Composable override fun invoke()</error> {}"
+      else
+        "<error descr=\"[CONFLICTING_OVERLOADS] Conflicting overloads: [@Composable() fun invoke(): Unit, fun invoke(): R]\" textAttributesKey=\"ERRORS_ATTRIBUTES\">@Composable override fun invoke()</error> {}"
     doTest(
       """
                 import androidx.compose.runtime.Composable
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/code/ComposableFunctionRenderingTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/code/ComposableFunctionRenderingTest.kt
index 7443e02..b5527e6 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/code/ComposableFunctionRenderingTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/code/ComposableFunctionRenderingTest.kt
@@ -33,8 +33,7 @@
 
 @RunWith(JUnit4::class)
 class ComposableFunctionRenderingTest {
-  @get:Rule
-  val projectRule = AndroidProjectRule.inMemory()
+  @get:Rule val projectRule = AndroidProjectRule.inMemory()
 
   private val myFixture: CodeInsightTestFixture by lazy { projectRule.fixture }
 
@@ -56,7 +55,8 @@
 
       @Composable
       fun ${caret}HomeScreen() {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     with(getComposableFunctionRenderPartsAtCaret()) {
@@ -77,7 +77,8 @@
 
       @Composable
       fun ${caret}HomeScreen(foo: Int = 0, bar: String = "") {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     with(getComposableFunctionRenderPartsAtCaret()) {
@@ -98,7 +99,8 @@
 
       @Composable
       fun ${caret}HomeScreen(foo: Int, bar: String) {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     with(getComposableFunctionRenderPartsAtCaret()) {
@@ -119,7 +121,8 @@
 
       @Composable
       fun ${caret}HomeScreen(foo: Int, bar: String = "", baz: Int = "") {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     with(getComposableFunctionRenderPartsAtCaret()) {
@@ -140,7 +143,8 @@
 
       @Composable
       fun ${caret}HomeScreen(foo: @Composable () -> Unit) {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     with(getComposableFunctionRenderPartsAtCaret()) {
@@ -161,7 +165,8 @@
 
       @Composable
       fun ${caret}HomeScreen(foo: () -> Unit) {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     with(getComposableFunctionRenderPartsAtCaret()) {
@@ -182,7 +187,8 @@
 
       @Composable
       fun ${caret}HomeScreen(a: Int, b: Int = 0, foo: @Composable () -> Unit) {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     with(getComposableFunctionRenderPartsAtCaret()) {
@@ -203,10 +209,12 @@
 
       @Composable
       fun ${caret}HomeScreen(a: Int, b: Int = 0, foo: () -> Unit) {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    // This seems like odd behavior, but it's documenting the existing behavior at the time this test is being written.
+    // This seems like odd behavior, but it's documenting the existing behavior at the time this
+    // test is being written.
     with(getComposableFunctionRenderPartsAtCaret()) {
       assertThat(parameters).isEqualTo("(a: Int, foo: () -> Unit, ...)")
       assertThat(tail).isNull()
@@ -215,6 +223,7 @@
 
   private fun getComposableFunctionRenderPartsAtCaret() = runReadAction {
     val element = myFixture.elementAtCaret as KtDeclaration
-    element.getComposableFunctionRenderParts() ?: throw AssertionError("Test must contain a valid composable function")
+    element.getComposableFunctionRenderParts()
+      ?: throw AssertionError("Test must contain a valid composable function")
   }
 }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/code/ComposeLineMarkerProviderDescriptorTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/code/ComposeLineMarkerProviderDescriptorTest.kt
index 2dce28f..9c02263 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/code/ComposeLineMarkerProviderDescriptorTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/code/ComposeLineMarkerProviderDescriptorTest.kt
@@ -35,8 +35,7 @@
 
 @RunWith(JUnit4::class)
 class ComposeLineMarkerProviderDescriptorTest {
-  @get:Rule
-  val projectRule = AndroidProjectRule.onDisk()
+  @get:Rule val projectRule = AndroidProjectRule.onDisk()
 
   private lateinit var myFixture: CodeInsightTestFixture
 
@@ -50,10 +49,11 @@
 
   @Test
   fun composableFunction_identifierHasMarker() {
-    val psiFile = myFixture.addFileToProject(
-      "src/com/example/Test.kt",
-      // language=kotlin
-      """
+    val psiFile =
+      myFixture.addFileToProject(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -65,8 +65,9 @@
       fun HomeScreen() {
         MyButton() // invocation
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     var identifier: LeafPsiElement? = null
     ApplicationManager.getApplication().invokeAndWait {
@@ -74,16 +75,19 @@
       identifier = myFixture.moveCaret("MyBut|ton() // invocation") as LeafPsiElement
     }
 
-    val lineMarkerInfo = runReadAction { ComposeLineMarkerProviderDescriptor().getLineMarkerInfo(identifier!!) }
+    val lineMarkerInfo = runReadAction {
+      ComposeLineMarkerProviderDescriptor().getLineMarkerInfo(identifier!!)
+    }
     assertThat(lineMarkerInfo).isNotNull()
   }
 
   @Test
   fun composableFunction_ktFunctionElementHasNoMarker() {
-    val psiFile = myFixture.addFileToProject(
-      "src/com/example/Test.kt",
-      // language=kotlin
-      """
+    val psiFile =
+      myFixture.addFileToProject(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -95,8 +99,9 @@
       fun HomeScreen() {
         MyButton() // invocation
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     var functionElement: KtNamedFunction? = null
     ApplicationManager.getApplication().invokeAndWait {
@@ -104,16 +109,19 @@
       functionElement = myFixture.moveCaret("MyBut|ton() // invocation").parentOfType()!!
     }
 
-    val lineMarkerInfo = runReadAction { ComposeLineMarkerProviderDescriptor().getLineMarkerInfo(functionElement!!) }
+    val lineMarkerInfo = runReadAction {
+      ComposeLineMarkerProviderDescriptor().getLineMarkerInfo(functionElement!!)
+    }
     assertThat(lineMarkerInfo).isNull()
   }
 
   @Test
   fun nonComposableFunction_noMarker() {
-    val psiFile = myFixture.addFileToProject(
-      "src/com/example/Test.kt",
-      // language=kotlin
-      """
+    val psiFile =
+      myFixture.addFileToProject(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       fun MyButton() {}
@@ -121,8 +129,9 @@
       fun HomeScreen() {
         MyButton() // invocation
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     var identifier: LeafPsiElement? = null
     ApplicationManager.getApplication().invokeAndWait {
@@ -130,7 +139,9 @@
       identifier = myFixture.moveCaret("MyBut|ton() // invocation") as LeafPsiElement
     }
 
-    val lineMarkerInfo = runReadAction { ComposeLineMarkerProviderDescriptor().getLineMarkerInfo(identifier!!) }
+    val lineMarkerInfo = runReadAction {
+      ComposeLineMarkerProviderDescriptor().getLineMarkerInfo(identifier!!)
+    }
     assertThat(lineMarkerInfo).isNull()
   }
 }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/code/ComposeStateReadAnnotatorTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/code/ComposeStateReadAnnotatorTest.kt
index 0df0ff36..1ccc8ce 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/code/ComposeStateReadAnnotatorTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/code/ComposeStateReadAnnotatorTest.kt
@@ -43,8 +43,7 @@
 @RunWith(JUnit4::class)
 @RunsInEdt
 class ComposeStateReadAnnotatorTest {
-  @get:Rule
-  val projectRule = AndroidProjectRule.inMemory().onEdt()
+  @get:Rule val projectRule = AndroidProjectRule.inMemory().onEdt()
 
   private val fixture: CodeInsightTestFixture by lazy { projectRule.fixture }
   private val annotator = ComposeStateReadAnnotator()
@@ -60,10 +59,11 @@
 
   @Test
   fun delegatedPropertyRead() {
-    val psiFile = fixture.loadNewFile(
-      "src/com/example/Test.kt",
-      // language=kotlin
-      """
+    val psiFile =
+      fixture.loadNewFile(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -80,20 +80,22 @@
 
       @Composable
       fun HelloContent(name: String, onNameChange: (String) -> Unit) { }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     val allElements = psiFile.collectDescendantsOfType<PsiElement>()
     val annotations = CodeInsightTestUtil.testAnnotator(annotator, *allElements.toTypedArray())
 
-    assertThat(annotations).hasSize(1);
+    assertThat(annotations).hasSize(1)
     with(annotations.first()) {
       assertThat(message).isEqualTo(createMessage("name", "HelloScreen"))
       assertThat(message).isEqualTo(message)
       assertThat(gutterIconRenderer).isNotNull()
       assertThat(gutterIconRenderer!!.icon).isEqualTo(EXPECTED_ICON)
       assertThat(gutterIconRenderer!!.tooltipText).isEqualTo(message)
-      assertThat(textAttributes).isEqualTo(ComposeStateReadAnnotator.COMPOSE_STATE_READ_TEXT_ATTRIBUTES_KEY)
+      assertThat(textAttributes)
+        .isEqualTo(ComposeStateReadAnnotator.COMPOSE_STATE_READ_TEXT_ATTRIBUTES_KEY)
       assertThat(startOffset).isEqualTo(fixture.offsetForWindow("HelloContent(name = |name)"))
       assertThat(endOffset).isEqualTo(fixture.offsetForWindow("HelloContent(name = name|)"))
     }
@@ -101,10 +103,11 @@
 
   @Test
   fun assignedPropertyRead() {
-    val psiFile = fixture.loadNewFile(
-      "src/com/example/Test.kt",
-      // language=kotlin
-      """
+    val psiFile =
+      fixture.loadNewFile(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -119,30 +122,35 @@
 
       @Composable
       fun HelloContent(name: String, onNameChange: (String) -> Unit) { }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     val allElements = psiFile.collectDescendantsOfType<PsiElement>()
     val annotations = CodeInsightTestUtil.testAnnotator(annotator, *allElements.toTypedArray())
 
-    assertThat(annotations).hasSize(1);
+    assertThat(annotations).hasSize(1)
     with(annotations.first()) {
       assertThat(message).isEqualTo(createMessage("assignedName", "HelloScreen"))
       assertThat(message).isEqualTo(message)
       assertThat(gutterIconRenderer).isNotNull()
       assertThat(gutterIconRenderer!!.icon).isEqualTo(EXPECTED_ICON)
       assertThat(gutterIconRenderer!!.tooltipText).isEqualTo(message)
-      assertThat(textAttributes).isEqualTo(ComposeStateReadAnnotator.COMPOSE_STATE_READ_TEXT_ATTRIBUTES_KEY)
-      assertThat(startOffset).isEqualTo(fixture.offsetForWindow("HelloContent(name = assignedName.|value)"))
-      assertThat(endOffset).isEqualTo(fixture.offsetForWindow("HelloContent(name = assignedName.value|)"))
+      assertThat(textAttributes)
+        .isEqualTo(ComposeStateReadAnnotator.COMPOSE_STATE_READ_TEXT_ATTRIBUTES_KEY)
+      assertThat(startOffset)
+        .isEqualTo(fixture.offsetForWindow("HelloContent(name = assignedName.|value)"))
+      assertThat(endOffset)
+        .isEqualTo(fixture.offsetForWindow("HelloContent(name = assignedName.value|)"))
     }
   }
   @Test
   fun listPropertyRead() {
-    val psiFile = fixture.loadNewFile(
-      "src/com/example/Test.kt",
-      // language=kotlin
-      """
+    val psiFile =
+      fixture.loadNewFile(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -157,30 +165,35 @@
 
       @Composable
       fun HelloContent(name: String, onNameChange: (String) -> Unit) { }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     val allElements = psiFile.collectDescendantsOfType<PsiElement>()
     val annotations = CodeInsightTestUtil.testAnnotator(annotator, *allElements.toTypedArray())
 
-    assertThat(annotations).hasSize(1);
+    assertThat(annotations).hasSize(1)
     with(annotations.first()) {
       assertThat(message).isEqualTo(createMessage("listName[0]", "HelloScreen"))
       assertThat(gutterIconRenderer).isNotNull()
       assertThat(gutterIconRenderer!!.icon).isEqualTo(EXPECTED_ICON)
       assertThat(gutterIconRenderer!!.tooltipText).isEqualTo(message)
-      assertThat(textAttributes).isEqualTo(ComposeStateReadAnnotator.COMPOSE_STATE_READ_TEXT_ATTRIBUTES_KEY)
-      assertThat(startOffset).isEqualTo(fixture.offsetForWindow("HelloContent(name = listName[0].|value)"))
-      assertThat(endOffset).isEqualTo(fixture.offsetForWindow("HelloContent(name = listName[0].value|)"))
+      assertThat(textAttributes)
+        .isEqualTo(ComposeStateReadAnnotator.COMPOSE_STATE_READ_TEXT_ATTRIBUTES_KEY)
+      assertThat(startOffset)
+        .isEqualTo(fixture.offsetForWindow("HelloContent(name = listName[0].|value)"))
+      assertThat(endOffset)
+        .isEqualTo(fixture.offsetForWindow("HelloContent(name = listName[0].value|)"))
     }
   }
 
   @Test
   fun nestedPropertyRead() {
-    val psiFile = fixture.loadNewFile(
-      "src/com/example/Test.kt",
-      // language=kotlin
-      """
+    val psiFile =
+      fixture.loadNewFile(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -198,21 +211,25 @@
       fun HelloContent(name: String, onNameChange: (String) -> Unit) { }
 
       class StateHolder(val name: MutableState<String>)
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     val allElements = psiFile.collectDescendantsOfType<PsiElement>()
     val annotations = CodeInsightTestUtil.testAnnotator(annotator, *allElements.toTypedArray())
 
-    assertThat(annotations).hasSize(1);
+    assertThat(annotations).hasSize(1)
     with(annotations.first()) {
       assertThat(message).isEqualTo(createMessage("name", "HelloScreen"))
       assertThat(gutterIconRenderer).isNotNull()
       assertThat(gutterIconRenderer!!.icon).isEqualTo(EXPECTED_ICON)
       assertThat(gutterIconRenderer!!.tooltipText).isEqualTo(message)
-      assertThat(textAttributes).isEqualTo(ComposeStateReadAnnotator.COMPOSE_STATE_READ_TEXT_ATTRIBUTES_KEY)
-      assertThat(startOffset).isEqualTo(fixture.offsetForWindow("HelloContent(name = container.name.|value)"))
-      assertThat(endOffset).isEqualTo(fixture.offsetForWindow("HelloContent(name = container.name.value|)"))
+      assertThat(textAttributes)
+        .isEqualTo(ComposeStateReadAnnotator.COMPOSE_STATE_READ_TEXT_ATTRIBUTES_KEY)
+      assertThat(startOffset)
+        .isEqualTo(fixture.offsetForWindow("HelloContent(name = container.name.|value)"))
+      assertThat(endOffset)
+        .isEqualTo(fixture.offsetForWindow("HelloContent(name = container.name.value|)"))
     }
   }
 
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/code/actions/ComposeProximityWeigherTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/code/actions/ComposeProximityWeigherTest.kt
index e06cb01..44f5d5a 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/code/actions/ComposeProximityWeigherTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/code/actions/ComposeProximityWeigherTest.kt
@@ -40,18 +40,19 @@
 /**
  * Tests for [ComposeProximityWeigher].
  *
- * Unfortunately it's not possible to validate the order of items in the "Add Imports" list end to end in a unit test, because most of the
- * logic involved is internal in the Kotlin plugin. We can execute the correct intention, but in a unit test it will not pop up a dialog,
- * instead just selecting the first item.
+ * Unfortunately it's not possible to validate the order of items in the "Add Imports" list end to
+ * end in a unit test, because most of the logic involved is internal in the Kotlin plugin. We can
+ * execute the correct intention, but in a unit test it will not pop up a dialog, instead just
+ * selecting the first item.
  *
- * This file contains some tests that validate that the Weigher is correctly wired up, by validating that the intention results in an import
- * being added that wouldn't have been used if [ComposeProximityWeigher] isn't running. The remaining tests are more traditional unit tests,
+ * This file contains some tests that validate that the Weigher is correctly wired up, by validating
+ * that the intention results in an import being added that wouldn't have been used if
+ * [ComposeProximityWeigher] isn't running. The remaining tests are more traditional unit tests,
  * working directly with [ComposeProximityWeigher] outside the context of the intention.
  */
 @RunWith(JUnit4::class)
 class ComposeProximityWeigherTest {
-  @get:Rule
-  val projectRule = AndroidProjectRule.onDisk()
+  @get:Rule val projectRule = AndroidProjectRule.onDisk()
 
   private val myFixture: CodeInsightTestFixture by lazy { projectRule.fixture }
 
@@ -63,8 +64,10 @@
 
   @Test
   fun validateWeigherIsWiredUp() {
-    // When two imports have equal weight (which will be the default in the unit test), the Kotlin plugin's logic falls back to using
-    // lexicographic ordering. This "Modifier" class will begin with "aaa", and thus would be listed first absent [ComposeProximityWeigher]
+    // When two imports have equal weight (which will be the default in the unit test), the Kotlin
+    // plugin's logic falls back to using
+    // lexicographic ordering. This "Modifier" class will begin with "aaa", and thus would be listed
+    // first absent [ComposeProximityWeigher]
     // changing the order.
     myFixture.addFileToProject(
       "src/aaa/example/foo/Modifier.kt",
@@ -73,7 +76,8 @@
       package aaa.example.foo
 
       interface Modifier
-      """)
+      """
+    )
 
     myFixture.addFileToProject(
       "src/androidx/compose/ui/Modifier.kt",
@@ -82,25 +86,26 @@
       package androidx.compose.ui
 
       interface Modifier
-      """)
-
-    val psiFile = myFixture.loadNewFile(
-      "src/com/example/Test.kt",
-      // language=kotlin
       """
+    )
+
+    val psiFile =
+      myFixture.loadNewFile(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
 
       @Composable
       fun HomeScreen(modifier: Mod${caret}ifier) {}
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     val action = myFixture.getIntentionAction("Import class 'Modifier'")!!
-    runInEdt {
-      action.invoke(myFixture.project, myFixture.editor, psiFile)
-    }
+    runInEdt { action.invoke(myFixture.project, myFixture.editor, psiFile) }
 
     myFixture.checkResult(
       // language=kotlin
@@ -112,15 +117,19 @@
 
       @Composable
       fun HomeScreen(modifier: Mod${caret}ifier) {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
   @Test
   fun validateWeigherIsBeforeJavaInheritance() {
-    // IntelliJ's com.intellij.psi.util.proximity.JavaInheritanceWeigher is promoting Java classes above everything else in the import list,
-    // presumably by accident. We can avoid that behavior for @Composable functions by ensuring our weigher runs before that one. This test
-    // validates that scenario, by including a Java class in the potential import list and ensuring it's below a promoted class.
+    // IntelliJ's com.intellij.psi.util.proximity.JavaInheritanceWeigher is promoting Java classes
+    // above everything else in the import list,
+    // presumably by accident. We can avoid that behavior for @Composable functions by ensuring our
+    // weigher runs before that one. This test
+    // validates that scenario, by including a Java class in the potential import list and ensuring
+    // it's below a promoted class.
     myFixture.addFileToProject(
       "src/android/graphics/Color.java",
       // language=java
@@ -128,7 +137,8 @@
       package android.graphics;
 
       public class Color {}
-      """)
+      """
+    )
 
     myFixture.addFileToProject(
       "src/androidx/compose/ui/graphics/Color.kt",
@@ -137,7 +147,8 @@
       package androidx.compose.ui.graphics
 
       value class Color
-      """)
+      """
+    )
 
     myFixture.addFileToProject(
       "src/androidx/compose/material/Surface.kt",
@@ -150,12 +161,14 @@
 
       @Composable
       fun Surface(color: Color) {}
-      """)
-
-    val psiFile = myFixture.loadNewFile(
-      "src/com/example/Test.kt",
-      // language=kotlin
       """
+    )
+
+    val psiFile =
+      myFixture.loadNewFile(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.material.Surface
@@ -166,13 +179,12 @@
         Surface(color = Co<caret>lor.White) {
         }
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     val action = myFixture.getIntentionAction("Import class 'Color'")!!
-    runInEdt {
-      action.invoke(myFixture.project, myFixture.editor, psiFile)
-    }
+    runInEdt { action.invoke(myFixture.project, myFixture.editor, psiFile) }
 
     myFixture.checkResult(
       // language=kotlin
@@ -188,31 +200,35 @@
         Surface(color = Co<caret>lor.White) {
         }
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
   @Test
   fun validateBasicOrdering() {
-    val composableFunction = addFileAndFindElement(
-      "src/com/example/composable/ComposableFunction.kt",
-      // language=kotlin
-      """
+    val composableFunction =
+      addFileAndFindElement(
+        "src/com/example/composable/ComposableFunction.kt",
+        // language=kotlin
+        """
       package com.example.composable
 
       import androidx.compose.runtime.Composable
 
       @Composable
       fun ComposableFunction()
-      """.trimIndent(),
-      "ComposableFunction",
-      KtNamedFunction::class.java
-    )
-
-    val deprecatedComposableFunction = addFileAndFindElement(
-      "src/com/example/composable/DeprecatedComposableFunction.kt",
-      // language=kotlin
       """
+          .trimIndent(),
+        "ComposableFunction",
+        KtNamedFunction::class.java
+      )
+
+    val deprecatedComposableFunction =
+      addFileAndFindElement(
+        "src/com/example/composable/DeprecatedComposableFunction.kt",
+        // language=kotlin
+        """
       package com.example.composable
 
       import androidx.compose.runtime.Composable
@@ -220,60 +236,85 @@
       @Composable
       @Deprecated
       fun DeprecatedComposableFunction()
-      """.trimIndent(),
-      "ComposableFunction",
-      KtNamedFunction::class.java
-    )
-
-    val nonComposableFunction = addFileAndFindElement(
-      "src/com/example/noncomposable/NonComposableFunction.kt",
-      // language=kotlin
       """
+          .trimIndent(),
+        "ComposableFunction",
+        KtNamedFunction::class.java
+      )
+
+    val nonComposableFunction =
+      addFileAndFindElement(
+        "src/com/example/noncomposable/NonComposableFunction.kt",
+        // language=kotlin
+        """
       package com.example.noncomposable
 
       fun NonComposableFunction()
-      """.trimIndent(),
-      "NonComposableFunction",
-      KtNamedFunction::class.java
-    )
-
-    val manuallyWeightedElement = addFileAndFindElement(
-      "src/androidx/compose/ui/Modifier.kt",
-      // language=kotlin
       """
+          .trimIndent(),
+        "NonComposableFunction",
+        KtNamedFunction::class.java
+      )
+
+    val manuallyWeightedElement =
+      addFileAndFindElement(
+        "src/androidx/compose/ui/Modifier.kt",
+        // language=kotlin
+        """
       package androidx.compose.ui
 
       object Modifier
-      """.trimIndent(),
-      "Modifier",
-      KtObjectDeclaration::class.java
-    )
-
-    val locationFile = myFixture.loadNewFile(
-      "src/com/example/Test.kt",
-      // language=kotlin
       """
+          .trimIndent(),
+        "Modifier",
+        KtObjectDeclaration::class.java
+      )
+
+    val locationFile =
+      myFixture.loadNewFile(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     val proximityLocation = ProximityLocation(locationFile, myFixture.module)
     val sortedList = runReadAction {
-      listOf(nonComposableFunction, deprecatedComposableFunction, composableFunction, manuallyWeightedElement)
-        .sortedByDescending { element -> ComposeProximityWeigher().weigh(element, proximityLocation) }
+      listOf(
+          nonComposableFunction,
+          deprecatedComposableFunction,
+          composableFunction,
+          manuallyWeightedElement
+        )
+        .sortedByDescending { element ->
+          ComposeProximityWeigher().weigh(element, proximityLocation)
+        }
     }
 
-    assertThat(sortedList).containsExactly(manuallyWeightedElement, composableFunction, nonComposableFunction,
-                                           deprecatedComposableFunction).inOrder()
+    assertThat(sortedList)
+      .containsExactly(
+        manuallyWeightedElement,
+        composableFunction,
+        nonComposableFunction,
+        deprecatedComposableFunction
+      )
+      .inOrder()
   }
 
-  fun <T : PsiElement> addFileAndFindElement(relativePath: String,
-                                             fileText: String,
-                                             targetElementText: String,
-                                             targetElementClass: Class<T>): T {
+  fun <T : PsiElement> addFileAndFindElement(
+    relativePath: String,
+    fileText: String,
+    targetElementText: String,
+    targetElementClass: Class<T>
+  ): T {
     val psiFile = myFixture.addFileToProject(relativePath, fileText)
     return runReadAction {
-      PsiTreeUtil.getParentOfType(psiFile.findElementAt(psiFile.text.indexOf(targetElementText)), targetElementClass)!!
+      PsiTreeUtil.getParentOfType(
+        psiFile.findElementAt(psiFile.text.indexOf(targetElementText)),
+        targetElementClass
+      )!!
     }
   }
 }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposeCompletionContributorTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposeCompletionContributorTest.kt
index afe7ff8..f422eeb 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposeCompletionContributorTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposeCompletionContributorTest.kt
@@ -27,18 +27,16 @@
 import com.intellij.openapi.application.runReadAction
 import com.intellij.testFramework.fixtures.CodeInsightTestFixture
 import org.jetbrains.android.compose.stubComposableAnnotation
+import org.jetbrains.kotlin.idea.base.plugin.isK2Plugin
 import org.jetbrains.kotlin.psi.KtProperty
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 
-/**
- * Tests for [ComposeCompletionContributor].
- */
+/** Tests for [ComposeCompletionContributor]. */
 class ComposeCompletionContributorTest {
 
-  @get:Rule
-  val projectRule = AndroidProjectRule.inMemory()
+  @get:Rule val projectRule = AndroidProjectRule.inMemory()
 
   private val myFixture: CodeInsightTestFixture by lazy { projectRule.fixture }
 
@@ -74,16 +72,18 @@
 
       @Composable
       fun FoobarFive(icon: String, onClick: () -> Unit) {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    val expectedLookupItems = listOf(
-      "FoobarOne(required: Int)",
-      "FoobarTwo(required: Int, ...)",
-      "FoobarThree(...) {...}",
-      "FoobarFour {...}",
-      "FoobarFive(icon: String, onClick: () -> Unit)"
-    )
+    val expectedLookupItems =
+      listOf(
+        "FoobarOne(required: Int)",
+        "FoobarTwo(required: Int, ...)",
+        "FoobarThree(...) {...}",
+        "FoobarFour {...}",
+        "FoobarFive(icon: String, onClick: () -> Unit)"
+      )
 
     // Given:
     myFixture.loadNewFile(
@@ -98,14 +98,16 @@
       fun HomeScreen() {
         Foobar${caret}
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // When:
     myFixture.completeBasic()
 
     // Then:
-    // Order doesn't matter here, since we're just validating that the elements are displayed with the correct signature text.
+    // Order doesn't matter here, since we're just validating that the elements are displayed with
+    // the correct signature text.
     assertThat(myFixture.renderedLookupElements).containsExactlyElementsIn(expectedLookupItems)
 
     // Given:
@@ -126,14 +128,16 @@
           }
         }
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // When:
     myFixture.completeBasic()
 
     // Then:
-    // Order doesn't matter here, since we're just validating that the elements are displayed with the correct signature text.
+    // Order doesn't matter here, since we're just validating that the elements are displayed with
+    // the correct signature text.
     assertThat(myFixture.renderedLookupElements).containsExactlyElementsIn(expectedLookupItems)
   }
 
@@ -151,13 +155,15 @@
       @Composable
       fun FoobarOne(first: Int, second: String, third: String? = null) {}
 
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    val file = myFixture.addFileToProject(
-      "src/com/example/Test.kt",
-      // language=kotlin
-      """
+    val file =
+      myFixture.addFileToProject(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -166,8 +172,9 @@
       fun HomeScreen() {
         Foobar${caret}
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     // When:
     myFixture.configureFromExistingVirtualFile(file.virtualFile)
@@ -185,7 +192,8 @@
       fun HomeScreen() {
         FoobarOne(first = , second = )
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -203,13 +211,15 @@
       @Composable
       fun FoobarOne(first: Int, second: String, third: String? = null) {}
 
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    var file = myFixture.addFileToProject(
-      "src/com/example/Test.kt",
-      // language=kotlin
-      """
+    var file =
+      myFixture.addFileToProject(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -218,8 +228,9 @@
       fun HomeScreen() {
         Foobar${caret}()
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     // When:
     myFixture.configureFromExistingVirtualFile(file.virtualFile)
@@ -237,15 +248,16 @@
       fun HomeScreen() {
         FoobarOne()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-
     // Check completion with tab
-    file = myFixture.addFileToProject(
-      "src/com/example/Test2.kt",
-      // language=kotlin
-      """
+    file =
+      myFixture.addFileToProject(
+        "src/com/example/Test2.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -254,8 +266,9 @@
       fun HomeScreen() {
         ${caret}()
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     // When:
     myFixture.configureFromExistingVirtualFile(file.virtualFile)
@@ -274,7 +287,8 @@
       fun HomeScreen() {
         FoobarOne()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -295,13 +309,15 @@
       @Composable
       fun FoobarTwo(children: () -> Unit) {}
 
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    val file = myFixture.addFileToProject(
-      "src/com/example/Test.kt",
-      // language=kotlin
-      """
+    val file =
+      myFixture.addFileToProject(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -310,8 +326,9 @@
       fun HomeScreen() {
         FoobarO${caret}
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     // When:
     myFixture.configureFromExistingVirtualFile(file.virtualFile)
@@ -331,13 +348,16 @@
 
         }
       }
-      """.trimIndent()
-      , true)
-
-    val file2 = myFixture.loadNewFile(
-      "src/com/example/Test2.kt",
-      // language=kotlin
       """
+        .trimIndent(),
+      true
+    )
+
+    val file2 =
+      myFixture.loadNewFile(
+        "src/com/example/Test2.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -346,8 +366,9 @@
       fun HomeScreen() {
         FoobarT${caret}
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     // When:
     myFixture.configureFromExistingVirtualFile(file2.virtualFile)
@@ -367,8 +388,10 @@
           
         }
       }
-      """.trimIndent()
-      , true)
+      """
+        .trimIndent(),
+      true
+    )
   }
 
   @Test
@@ -385,13 +408,15 @@
       @Composable
       fun FoobarOne(children: @Composable() () -> Unit) {}
 
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    var file = myFixture.addFileToProject(
-      "src/com/example/Test.kt",
-      // language=kotlin
-      """
+    var file =
+      myFixture.addFileToProject(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -403,8 +428,9 @@
 
         }
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     // When:
     myFixture.configureFromExistingVirtualFile(file.virtualFile)
@@ -426,14 +452,17 @@
 
         }
       }
-      """.trimIndent()
-      , true)
+      """
+        .trimIndent(),
+      true
+    )
 
     // Given:
-    file = myFixture.addFileToProject(
-      "src/com/example/Test2.kt",
-      // language=kotlin
-      """
+    file =
+      myFixture.addFileToProject(
+        "src/com/example/Test2.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -445,8 +474,9 @@
 
         }
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     // When:
     myFixture.configureFromExistingVirtualFile(file.virtualFile)
@@ -468,8 +498,10 @@
 
         }
       }
-      """.trimIndent()
-      , true)
+      """
+        .trimIndent(),
+      true
+    )
   }
 
   @Test
@@ -486,13 +518,15 @@
       @Composable
       fun FoobarOne(optional: String? = null, children: @Composable() () -> Unit) {}
 
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    val file = myFixture.addFileToProject(
-      "src/com/example/Test.kt",
-      // language=kotlin
-      """
+    val file =
+      myFixture.addFileToProject(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -501,8 +535,9 @@
       fun HomeScreen() {
         Foobar${caret}
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     // When:
     myFixture.configureFromExistingVirtualFile(file.virtualFile)
@@ -522,8 +557,10 @@
 
         }
       }
-      """.trimIndent()
-      , true)
+      """
+        .trimIndent(),
+      true
+    )
   }
 
   @Test
@@ -540,13 +577,15 @@
       @Composable
       fun AppBarIcon(icon: String, onClick: () -> Unit) {}
 
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    val file = myFixture.addFileToProject(
-      "src/com/example/Test.kt",
-      // language=kotlin
-      """
+    val file =
+      myFixture.addFileToProject(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -555,8 +594,9 @@
       fun HomeScreen() {
         AppBarIcon${caret}
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     // When:
     myFixture.configureFromExistingVirtualFile(file.virtualFile)
@@ -576,8 +616,10 @@
           
         }
       }
-      """.trimIndent()
-      , true)
+      """
+        .trimIndent(),
+      true
+    )
   }
 
   @Test
@@ -594,13 +636,15 @@
       @Composable
       fun RadioButton(text: String, onClick: () -> Unit, label: String = "label") {}
 
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    val file = myFixture.addFileToProject(
-      "src/com/example/Test.kt",
-      // language=kotlin
-      """
+    val file =
+      myFixture.addFileToProject(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -609,8 +653,9 @@
       fun HomeScreen() {
         RadioButton${caret}
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     // When:
     myFixture.configureFromExistingVirtualFile(file.virtualFile)
@@ -628,8 +673,10 @@
       fun HomeScreen() {
         RadioButton(text = , onClick = { /*TODO*/ })
       }
-      """.trimIndent()
-      , true)
+      """
+        .trimIndent(),
+      true
+    )
   }
 
   @Test
@@ -646,13 +693,15 @@
       @Composable
       fun FoobarOne(first: Int, second: String, third: String? = null) {}
 
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    val file = myFixture.addFileToProject(
-      "src/com/example/Test.kt",
-      // language=kotlin
-      """
+    val file =
+      myFixture.addFileToProject(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -661,8 +710,9 @@
       fun HomeScreen() {
         Foobar${caret}
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     try {
       // When:
@@ -671,6 +721,7 @@
       myFixture.completeBasic()
 
       // Then:
+      val indentation = if (isK2Plugin()) "  " else ""
       myFixture.checkResult(
         // language=kotlin
         """
@@ -680,9 +731,10 @@
 
       @Composable
       fun HomeScreen() {
-        FoobarOne()
+        ${indentation}FoobarOne()
       }
-      """.trimIndent()
+      """
+          .trimIndent()
       )
     } finally {
       ComposeSettings.getInstance().state.isComposeInsertHandlerEnabled = true
@@ -703,13 +755,15 @@
       @Composable
       fun FoobarOne(first: Int, second: String, third: String? = null) {}
 
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    val file = myFixture.addFileToProject(
-      "src/com/example/Test.kt",
-      // language=kotlin
-      """
+    val file =
+      myFixture.addFileToProject(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -720,8 +774,9 @@
       @Composable
       fun HomeScreen() {
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     // When:
     myFixture.configureFromExistingVirtualFile(file.virtualFile)
@@ -741,14 +796,15 @@
       @Composable
       fun HomeScreen() {
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
   /**
-   * Regression test for b/153769933. The Compose insertion handler adds the parameters automatically when completing the name
-   * of a Composable. This is incorrect if the insertion point is not a call statement. This ensures that the insertion is not triggered
-   * for imports.
+   * Regression test for b/153769933. The Compose insertion handler adds the parameters
+   * automatically when completing the name of a Composable. This is incorrect if the insertion
+   * point is not a call statement. This ensures that the insertion is not triggered for imports.
    */
   @Test
   fun testImportCompletionDoesNotTriggerInsertionHandler() {
@@ -763,8 +819,8 @@
       // This simulates the Canvas composable
       @Composable
       fun Canvas(children: @Composable() () -> Unit) {}
-    """)
-
+    """
+    )
 
     // Given:
     myFixture.loadNewFile(
@@ -779,7 +835,8 @@
       @Composable
       fun Test() {
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // When:
@@ -797,12 +854,15 @@
       @Composable
       fun Test() {
       }
-      """.trimIndent()
-      , true)
+      """
+        .trimIndent(),
+      true
+    )
   }
 
   /**
-   * Regression test for b/209672710. Ensure that completing Composables that are not top-level does not fully qualify them incorrectly.
+   * Regression test for b/209672710. Ensure that completing Composables that are not top-level does
+   * not fully qualify them incorrectly.
    */
   @Test
   fun testCompletingComposablesWithinObjects() {
@@ -819,8 +879,8 @@
         @Composable
         fun TestMethod(children: @Composable() () -> Unit) {}
       }
-    """)
-
+    """
+    )
 
     // Given:
     myFixture.loadNewFile(
@@ -835,16 +895,18 @@
       fun Test() {
         ObjectWithComposables.Test${caret}
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // When:
     myFixture.completeBasic()
 
     // Then:
-    myFixture.checkResult(
-      // language=kotlin
-      """
+    if (!isK2Plugin()) {
+      myFixture.checkResult(
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -855,13 +917,35 @@
 
         }
       }
-      """.trimIndent()
-      , true)
+      """
+          .trimIndent(),
+        true
+      )
+    } else {
+      myFixture.checkResult(
+        // language=kotlin
+        """
+      package com.example
+
+      import androidx.compose.runtime.Composable
+      import com.example.ObjectWithComposables.TestMethod
+
+      @Composable
+      fun Test() {
+          TestMethod {
+
+          }
+      }
+      """
+          .trimIndent(),
+        true
+      )
+    }
   }
 
   /**
-   * Regression test for b/209060418. Autocomplete should not treat required composable method specially if it's not the final argument (ie,
-   * there are optional arguments specified after it.
+   * Regression test for b/209060418. Autocomplete should not treat required composable method
+   * specially if it's not the final argument (ie, there are optional arguments specified after it.
    */
   @Test
   fun testSignaturesWithRequiredComposableBeforeOptionalArgs() {
@@ -890,17 +974,21 @@
 
       @Composable
       fun FoobarSix(optionalArg: Int = 0) {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    val expectedLookupItems = listOf(
-      "FoobarOne(requiredArg: () -> Unit, ...)",
-      "FoobarTwo(...)",
-      "FoobarThree(requiredArg: () -> Unit, optionalArg: Int = ...) (com.example) Unit",
-      "FoobarFour(optionalArg: Int = ...) (com.example) Unit",
-      "FoobarFive(requiredArg: () -> Unit, ...)",
-      "FoobarSix(...)",
-    )
+    val parameterWithComposeAnnotation =
+      if (isK2Plugin()) "@Composable (() -> Unit)" else "() -> Unit"
+    val expectedLookupItems =
+      listOf(
+        "FoobarOne(requiredArg: $parameterWithComposeAnnotation, ...)",
+        "FoobarTwo(...)",
+        "FoobarThree(requiredArg: $parameterWithComposeAnnotation, optionalArg: Int = ...) (com.example) Unit",
+        "FoobarFour(optionalArg: Int = ...) (com.example) Unit",
+        "FoobarFive(requiredArg: () -> Unit, ...)",
+        "FoobarSix(...)",
+      )
 
     // Given:
     myFixture.loadNewFile(
@@ -915,20 +1003,22 @@
       fun HomeScreen() {
         Foobar${caret}
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // When:
     myFixture.completeBasic()
 
     // Then:
-    // Order doesn't matter here, since we're just validating that the elements are displayed with the correct signature text.
+    // Order doesn't matter here, since we're just validating that the elements are displayed with
+    // the correct signature text.
     assertThat(myFixture.renderedLookupElements).containsExactlyElementsIn(expectedLookupItems)
   }
 
   /**
-   * Regression test for b/209060418. Autocomplete should not treat required composable method specially if it's not the final argument (ie,
-   * there are optional arguments specified after it.
+   * Regression test for b/209060418. Autocomplete should not treat required composable method
+   * specially if it's not the final argument (ie, there are optional arguments specified after it.
    */
   @Test
   fun testInsertHandlerWithRequiredComposableBeforeOptionalArgs() {
@@ -944,7 +1034,8 @@
 
       @Composable
       fun FoobarOne(requiredArg: @Composable () -> Unit, optionalArg: Int = 0) {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // Given:
@@ -960,7 +1051,8 @@
       fun HomeScreen() {
         Foobar${caret}
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // When:
@@ -978,13 +1070,13 @@
       fun HomeScreen() {
         FoobarOne(requiredArg = { /*TODO*/ })
       }
-      """.trimIndent()
-      , true)
+      """
+        .trimIndent(),
+      true
+    )
   }
 
-  /**
-   * Regression test for b/182564317. Autocomplete should not treat varargs as required.
-   */
+  /** Regression test for b/182564317. Autocomplete should not treat varargs as required. */
   @Test
   fun testInsertHandlerWithVarArgs() {
     myFixture.addFileToProject(
@@ -999,7 +1091,8 @@
 
       @Composable
       fun FoobarOne(vararg inputs: Any?, children: @Composable () -> Unit) {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // Given:
@@ -1015,7 +1108,8 @@
       fun HomeScreen() {
         Foobar${caret}
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // When:
@@ -1035,13 +1129,13 @@
 
         }
       }
-      """.trimIndent()
-      , true)
+      """
+        .trimIndent(),
+      true
+    )
   }
 
-  /**
-   * Regression test for b/182564317. Autocomplete should not treat varargs as required.
-   */
+  /** Regression test for b/182564317. Autocomplete should not treat varargs as required. */
   @Test
   fun testInsertHandlerWithVarArgsLambda() {
     myFixture.addFileToProject(
@@ -1056,7 +1150,8 @@
 
       @Composable
       fun FoobarOne(vararg children: @Composable () -> Unit) {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // Given:
@@ -1072,7 +1167,8 @@
       fun HomeScreen() {
         Foobar${caret}
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // When:
@@ -1090,20 +1186,24 @@
       fun HomeScreen() {
         FoobarOne()
       }
-      """.trimIndent()
-      , true)
+      """
+        .trimIndent(),
+      true
+    )
   }
 
   /**
-   * Regression test for b/271675885. Autocomplete changes should apply to function invocations, not function definitions.
+   * Regression test for b/271675885. Autocomplete changes should apply to function invocations, not
+   * function definitions.
    */
   @Test
   fun testInsertHandler_functionDefinition() {
     // Given:
-    val file = myFixture.addFileToProject(
-      "src/com/example/Test.kt",
-      // language=kotlin
-      """
+    val file =
+      myFixture.addFileToProject(
+        "src/com/example/Test.kt",
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -1117,8 +1217,9 @@
       class MyComposablesImpl : MyComposables {
           override fun Foo${caret}
       }
-      """.trimIndent()
-    )
+      """
+          .trimIndent()
+      )
 
     // When:
     myFixture.configureFromExistingVirtualFile(file.virtualFile)
@@ -1143,7 +1244,8 @@
               TODO("Not yet implemented")
           }
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -1161,7 +1263,8 @@
       .isEqualTo("images/material/icons/materialiconsoutlined/adb/outline_adb_24.xml")
 
     assertThat("androidx.compose.material.icons.unknown.Adb".resourcePathFromFqName()).isNull()
-    assertThat("androidx.compose.material.icons.filled.extrapackage.Adb".resourcePathFromFqName()).isNull()
+    assertThat("androidx.compose.material.icons.filled.extrapackage.Adb".resourcePathFromFqName())
+      .isNull()
 
     // Ensure numbers in camel case are converted as expected.
     assertThat("androidx.compose.material.icons.filled.Shop2".resourcePathFromFqName())
@@ -1181,7 +1284,8 @@
       package androidx.compose.ui.graphics.vector
 
       class ImageVector
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.addFileToProject(
@@ -1193,7 +1297,8 @@
       object Icons {
         object Filled
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.loadNewFile(
@@ -1207,7 +1312,8 @@
       val androidx.compose.material.icons.Icons.Filled.Accoun<caret>tBox: ImageVector
         get() = ImageVector()
 
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     val accountBox = runReadAction { myFixture.elementAtCaret }
@@ -1225,7 +1331,8 @@
       package androidx.compose.ui.graphics.vector
 
       class ImageVector
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.addFileToProject(
@@ -1237,7 +1344,8 @@
       object Icons {
         object Unknown
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.loadNewFile(
@@ -1251,7 +1359,8 @@
       val androidx.compose.material.icons.Icons.Unknown.Accoun<caret>tBox: ImageVector
         get() = ImageVector()
 
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     val accountBox = runReadAction { myFixture.elementAtCaret }
@@ -1263,10 +1372,14 @@
   @Test
   fun composeMaterialIconLookupElement_getIcon() {
     assertThat(
-      ComposeMaterialIconLookupElement.getIcon("androidx.compose.material.icons.filled.AccountBox"))
+        ComposeMaterialIconLookupElement.getIcon(
+          "androidx.compose.material.icons.filled.AccountBox"
+        )
+      )
       .isNotNull()
     assertThat(
-      ComposeMaterialIconLookupElement.getIcon("androidx.compose.material.icons.filled.Unknown"))
+        ComposeMaterialIconLookupElement.getIcon("androidx.compose.material.icons.filled.Unknown")
+      )
       .isNull()
   }
 
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposeCompletionWeigherTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposeCompletionWeigherTest.kt
index 4c2c0cc..5252dec 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposeCompletionWeigherTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposeCompletionWeigherTest.kt
@@ -34,8 +34,7 @@
 @RunWith(JUnit4::class)
 class ComposeCompletionWeigherTest {
 
-  @get:Rule
-  val projectRule = AndroidProjectRule.inMemory()
+  @get:Rule val projectRule = AndroidProjectRule.inMemory()
 
   private val myFixture: CodeInsightTestFixture by lazy { projectRule.fixture }
 
@@ -72,10 +71,11 @@
 
       // This simulates the MaterialTheme object that should be promoted instead of the MaterialTheme
       object MaterialTheme
-      """)
+      """
+    )
 
-
-    // Add a MaterialTheme that is not part of androidx to ensure is not affected by the promotion/demotion
+    // Add a MaterialTheme that is not part of androidx to ensure is not affected by the
+    // promotion/demotion
     myFixture.addFileToProject(
       "src/com/example/MaterialTheme.kt",
       // language=kotlin
@@ -83,8 +83,8 @@
       package com.example
 
       object MaterialTheme
-      """)
-
+      """
+    )
 
     // Given:
     myFixture.loadNewFile(
@@ -99,18 +99,21 @@
       fun HomeScreen() {
         Material$caret
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // When:
     myFixture.completeBasic()
 
     // Then:
-    Truth.assertThat(myFixture.renderedLookupElements).containsExactly(
-      "MaterialTheme ($materialThemePackage)",
-      "MaterialTheme {...}",
-      "MaterialTheme (com.example)",
-    ).inOrder()
+    Truth.assertThat(myFixture.renderedLookupElements)
+      .containsExactly(
+        "MaterialTheme ($materialThemePackage)",
+        "MaterialTheme {...}",
+        "MaterialTheme (com.example)",
+      )
+      .inOrder()
   }
 
   /** Regression test for b/155314487. */
@@ -140,10 +143,11 @@
 
       // This simulates the MaterialTheme object that should be promoted instead of the MaterialTheme
       object MaterialTheme
-      """)
+      """
+    )
 
-
-    // Add a MaterialTheme that is not part of androidx to ensure is not affected by the promotion/demotion
+    // Add a MaterialTheme that is not part of androidx to ensure is not affected by the
+    // promotion/demotion
     myFixture.addFileToProject(
       "src/com/example/MaterialTheme.kt",
       // language=kotlin
@@ -151,8 +155,8 @@
       package com.example
 
       object MaterialTheme
-      """)
-
+      """
+    )
 
     // Add Color so it can be referenced without causing a missing reference.
     myFixture.addFileToProject(
@@ -162,8 +166,8 @@
       package androidx.compose.ui.graphics
 
       class Color
-      """)
-
+      """
+    )
 
     // Given:
     myFixture.loadNewFile(
@@ -182,24 +186,29 @@
 
       @Composable
       fun HomeScreenElement(color: Color) {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // When:
     myFixture.completeBasic()
 
     // Then:
-    Truth.assertThat(myFixture.renderedLookupElements).containsExactly(
-      "MaterialTheme ($materialThemePackage)",
-      "MaterialTheme (com.example)",
-      "MaterialTheme {...}",
-    ).inOrder()
+    Truth.assertThat(myFixture.renderedLookupElements)
+      .containsExactly(
+        "MaterialTheme ($materialThemePackage)",
+        "MaterialTheme (com.example)",
+        "MaterialTheme {...}",
+      )
+      .inOrder()
   }
 
   @Test
   fun testLookupElementOrder_valueArgumentWithDotExpression() {
-    // This test applies to any value argument being filled in with a dot expression, as in "icon = Icons.<caret>". Using Icons specifically
-    // just because they can fulfill that scenario, and the autocomplete list would be in a different order if the weighing code didn't run.
+    // This test applies to any value argument being filled in with a dot expression, as in "icon =
+    // Icons.<caret>". Using Icons specifically
+    // just because they can fulfill that scenario, and the autocomplete list would be in a
+    // different order if the weighing code didn't run.
     myFixture.addFileToProject(
       "src/androidx/compose/material/icons/Icons.kt",
       // language=kotlin
@@ -214,7 +223,8 @@
         object Sharp
         object TwoTone
       }
-      """)
+      """
+    )
 
     // Given:
     myFixture.loadNewFile(
@@ -233,7 +243,8 @@
 
       @Composable
       fun HomeScreenElement(icon: Any) {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // When:
@@ -242,17 +253,20 @@
     // Then:
     val renderedLookupElements = myFixture.renderedLookupElements
 
-    // There should be at least one more suggestion that's not one of the Icons object, but we don't really care what it is as long as it's
+    // There should be at least one more suggestion that's not one of the Icons object, but we don't
+    // really care what it is as long as it's
     // ranked lower than the Icons entries.
     Truth.assertThat(renderedLookupElements.size).isAtLeast(7)
-    Truth.assertThat(renderedLookupElements.toList().subList(0, 6)).containsExactly(
-      "Defaultnull Icons.Filled",
-      "Filled (androidx.compose.material.icons.Icons)",
-      "Outlined (androidx.compose.material.icons.Icons)",
-      "Rounded (androidx.compose.material.icons.Icons)",
-      "Sharp (androidx.compose.material.icons.Icons)",
-      "TwoTone (androidx.compose.material.icons.Icons)"
-    ).inOrder()
+    Truth.assertThat(renderedLookupElements.toList().subList(0, 6))
+      .containsExactly(
+        "Defaultnull Icons.Filled",
+        "Filled (androidx.compose.material.icons.Icons)",
+        "Outlined (androidx.compose.material.icons.Icons)",
+        "Rounded (androidx.compose.material.icons.Icons)",
+        "Sharp (androidx.compose.material.icons.Icons)",
+        "TwoTone (androidx.compose.material.icons.Icons)"
+      )
+      .inOrder()
   }
 
   @Test
@@ -273,7 +287,8 @@
 
       @Composable
       fun WrappingFunction(foobarArg: Int) {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // Given:
@@ -289,18 +304,21 @@
       fun HomeScreen() {
         WrappingFunction(foobar<caret>)
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // When:
     myFixture.completeBasic()
 
     // Then:
-    Truth.assertThat(myFixture.renderedLookupElements).containsExactly(
-      "foobarArg = Int",
-      "foobarOne(required: Int) (com.example) Int",
-      "foobarTwo(required: Int, optional: Int = ...) (com.example) Int",
-    ).inOrder()
+    Truth.assertThat(myFixture.renderedLookupElements)
+      .containsExactly(
+        "foobarArg = Int",
+        "foobarOne(required: Int) (com.example) Int",
+        "foobarTwo(required: Int, optional: Int = ...) (com.example) Int",
+      )
+      .inOrder()
   }
 
   private val CodeInsightTestFixture.renderedLookupElements: Collection<String>
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposeMaterialIconServiceTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposeMaterialIconServiceTest.kt
index 92a57b1..8cffc6d 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposeMaterialIconServiceTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposeMaterialIconServiceTest.kt
@@ -22,13 +22,13 @@
 import com.android.tools.idea.MaterialVdIconsProvider
 import com.android.tools.idea.material.icons.MaterialVdIcons
 import com.google.common.truth.Truth.assertThat
+import java.awt.image.BufferedImage
 import org.junit.Before
 import org.junit.Test
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.invocation.InvocationOnMock
-import java.awt.image.BufferedImage
 
 class ComposeMaterialIconServiceTest {
 
@@ -43,7 +43,8 @@
   }
 
   private fun storeCallback(invocation: InvocationOnMock) {
-    this.callback = invocation.arguments[0] as (MaterialVdIcons, MaterialVdIconsProvider.Status) -> Unit
+    this.callback =
+      invocation.arguments[0] as (MaterialVdIcons, MaterialVdIconsProvider.Status) -> Unit
   }
 
   @Test
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposeModifierCompletionContributorTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposeModifierCompletionContributorTest.kt
index 0011b57..3ea38ea 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposeModifierCompletionContributorTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposeModifierCompletionContributorTest.kt
@@ -45,13 +45,10 @@
 import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 
-/**
- * Test for [ComposeModifierCompletionContributor].
- */
+/** Test for [ComposeModifierCompletionContributor]. */
 @RunWith(JUnit4::class)
 class ComposeModifierCompletionContributorTest {
-  @get:Rule
-  val projectRule = AndroidProjectRule.inMemory().onEdt()
+  @get:Rule val projectRule = AndroidProjectRule.inMemory().onEdt()
 
   private val myFixture: CodeInsightTestFixture by lazy { projectRule.fixture }
 
@@ -74,7 +71,8 @@
 
     fun Modifier.extensionFunction():Modifier { return this }
     fun Modifier.extensionFunctionReturnsNonModifier():Int { return 1 }
-    """.trimIndent()
+    """
+        .trimIndent()
     )
 
     myFixture.addFileToProject(
@@ -87,7 +85,9 @@
 
       @Composable
       fun myWidgetWithModifier(modifier: Modifier) {}
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
   }
 
   @Test
@@ -104,14 +104,19 @@
       fun HomeScreen() {
         val m = Modifier.$caret
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     myFixture.completeBasic()
 
     var lookupStrings = myFixture.lookupElementStrings!!
-    assertThat(lookupStrings.indexOf("extensionFunction")).isLessThan(lookupStrings.indexOf("function"))
-    assertThat(lookupStrings.indexOf("extensionFunction")).isLessThan(lookupStrings.indexOf("extensionFunctionReturnsNonModifier"))
-    assertThat(lookupStrings.indexOf("extensionFunctionReturnsNonModifier")).isLessThan(lookupStrings.indexOf("function"))
+    assertThat(lookupStrings.indexOf("extensionFunction"))
+      .isLessThan(lookupStrings.indexOf("function"))
+    assertThat(lookupStrings.indexOf("extensionFunction"))
+      .isLessThan(lookupStrings.indexOf("extensionFunctionReturnsNonModifier"))
+    assertThat(lookupStrings.indexOf("extensionFunctionReturnsNonModifier"))
+      .isLessThan(lookupStrings.indexOf("function"))
 
     myFixture.loadNewFile(
       "src/com/example/Test2.kt",
@@ -126,12 +131,15 @@
       fun HomeScreen2() {
         val m = Modifier.extensionFunction().$caret
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     myFixture.completeBasic()
 
     lookupStrings = myFixture.lookupElementStrings!!
-    assertThat(lookupStrings.indexOf("extensionFunction")).isLessThan(lookupStrings.indexOf("function"))
+    assertThat(lookupStrings.indexOf("extensionFunction"))
+      .isLessThan(lookupStrings.indexOf("function"))
 
     myFixture.loadNewFile(
       "src/com/example/Test3.kt",
@@ -145,12 +153,15 @@
       fun HomeScreen3(modifier: Modifier = Modifier) {
         modifier.$caret
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     myFixture.completeBasic()
 
     lookupStrings = myFixture.lookupElementStrings!!
-    assertThat(lookupStrings.indexOf("extensionFunction")).isLessThan(lookupStrings.indexOf("function"))
+    assertThat(lookupStrings.indexOf("extensionFunction"))
+      .isLessThan(lookupStrings.indexOf("function"))
 
     myFixture.loadNewFile(
       "src/com/example/Test4.kt",
@@ -164,19 +175,23 @@
       fun HomeScreen4() {
         Modifier.<caret>
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     myFixture.completeBasic()
 
     lookupStrings = myFixture.lookupElementStrings!!
-    assertThat(lookupStrings.indexOf("extensionFunction")).isLessThan(lookupStrings.indexOf("function"))
+    assertThat(lookupStrings.indexOf("extensionFunction"))
+      .isLessThan(lookupStrings.indexOf("function"))
   }
 
   @RunsInEdt
   @Test
   fun modifierAsArgument() {
     fun checkArgumentCompletion() {
-      myFixture.lookup.currentItem = myFixture.lookupElements.find { it.lookupString.contains("extensionFunction") }
+      myFixture.lookup.currentItem =
+        myFixture.lookupElements.find { it.lookupString.contains("extensionFunction") }
       myFixture.finishLookup('\n')
       myFixture.checkResult(
         """
@@ -190,12 +205,14 @@
       fun myWidget() {
           myWidgetWithModifier(Modifier.extensionFunction()
       }
-      """.trimIndent()
+      """
+          .trimIndent()
       )
     }
 
     fun checkNamedArgumentCompletion() {
-      myFixture.lookup.currentItem = myFixture.lookupElements.find { it.lookupString.contains("extensionFunction") }
+      myFixture.lookup.currentItem =
+        myFixture.lookupElements.find { it.lookupString.contains("extensionFunction") }
       myFixture.finishLookup('\n')
       myFixture.checkResult(
         """
@@ -209,7 +226,8 @@
       fun myWidget() {
           myWidgetWithModifier(modifier = Modifier.extensionFunction()
       }
-      """.trimIndent()
+      """
+          .trimIndent()
       )
     }
 
@@ -225,7 +243,8 @@
       fun myWidget() {
           myWidgetWithModifier(Modifier.<caret>
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.completeBasic()
@@ -248,7 +267,8 @@
       fun myWidget() {
           myWidgetWithModifier(<caret>
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.completeBasic()
@@ -258,7 +278,8 @@
     assertThat(lookupStrings).doesNotContain("Modifier.extensionFunctionReturnsNonModifier")
     assertThat(lookupStrings.indexOf("Modifier.extensionFunction")).isEqualTo(0)
 
-    // to check that we still suggest "Modifier.extensionFunction" when prefix doesn't much with function name and only with "Modifier".
+    // to check that we still suggest "Modifier.extensionFunction" when prefix doesn't much with
+    // function name and only with "Modifier".
     // See [ComposeModifierCompletionContributor.ModifierLookupElement.getAllLookupStrings]
     myFixture.type("M")
 
@@ -275,7 +296,8 @@
       fun myWidget() {
           myWidgetWithModifier(modifier = <caret>
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.completeBasic()
@@ -298,7 +320,8 @@
       fun myWidget() {
           myWidgetWithModifier(modifier = Modifier.<caret>
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.completeBasic()
@@ -326,7 +349,8 @@
       fun myWidget() {
           val myModifier:Modifier = <caret>
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.completeBasic()
@@ -350,7 +374,8 @@
       fun myWidget() {
           val myModifier:Modifier = Modifier.extensionFunction()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.loadNewFile(
@@ -365,7 +390,8 @@
       fun myWidget() {
           val myModifier:Modifier = Modifier.<caret>
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.completeBasic()
@@ -373,7 +399,6 @@
     assertThat(lookupStrings).contains("extensionFunction")
     assertThat(lookupStrings).contains("extensionFunctionReturnsNonModifier")
 
-
     myFixture.loadNewFile(
       "src/com/example/Test.kt",
       """
@@ -387,7 +412,8 @@
       fun myWidget() {
           val myModifier:Modifier = Modifier.extensionFunction().<caret>
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.completeBasic()
@@ -411,7 +437,8 @@
       fun myWidget() {
           myWidgetWithModifier(modifier = Modifier.<caret>
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.completeBasic()
@@ -420,7 +447,8 @@
     assertThat(lookupStrings).contains("extensionFunctionReturnsNonModifier")
     assertThat(lookupStrings.indexOf("extensionFunction")).isEqualTo(0)
 
-    myFixture.lookup.currentItem = myFixture.lookupElements.find { it.lookupString == "extensionFunction" }
+    myFixture.lookup.currentItem =
+      myFixture.lookupElements.find { it.lookupString == "extensionFunction" }
     myFixture.finishLookup('\n')
 
     myFixture.checkResult(
@@ -435,7 +463,8 @@
       fun myWidget() {
           myWidgetWithModifier(modifier = Modifier.extensionFunction()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -452,7 +481,8 @@
 
       fun Modifier.foo() = extensionFunction().<caret>
 
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.completeBasic()
@@ -468,14 +498,16 @@
     val contributor = ComposeModifierCompletionContributor()
     val mockResultSet: CompletionResultSet = mock()
 
-    // This is a super-contrived example to try to regression test b/279049842. I haven't been able to reproduce the real scenario, which
-    // involves internal items coming from other libs/modules and relies on Kotlin plugin bugs which (hopefully) would get fixed at some
+    // This is a super-contrived example to try to regression test b/279049842. I haven't been able
+    // to reproduce the real scenario, which
+    // involves internal items coming from other libs/modules and relies on Kotlin plugin bugs which
+    // (hopefully) would get fixed at some
     // some point.
 
     ApplicationManager.getApplication().invokeAndWait {
       myFixture.loadNewFile(
         "src/com/example/Test.kt",
-        //language=kotlin
+        // language=kotlin
         """
         package com.example
 
@@ -500,23 +532,37 @@
         fun doSomething() {
             functionNeedingModifier(modifier = MyModifier.)
         }
-        """.trimIndent()
+        """
+          .trimIndent()
       )
     }
 
     runReadAction {
-      val functionCompletionCall: KtCallExpression = myFixture.findParentElement("functionNeeding|Modifier(modifier = MyModifier")
+      val functionCompletionCall: KtCallExpression =
+        myFixture.findParentElement("functionNeeding|Modifier(modifier = MyModifier")
 
-      val visibleChildFunctionCompletion = mockCompletionResult(
-        myFixture.findParentElement<KtFunction>("Modifier.visibleChild|Function():"))
+      val visibleChildFunctionCompletion =
+        mockCompletionResult(
+          myFixture.findParentElement<KtFunction>("Modifier.visibleChild|Function():")
+        )
       contributor.consumerCompletionResultFromRemainingContributor(
-        visibleChildFunctionCompletion, emptySet(), functionCompletionCall, mockResultSet)
+        visibleChildFunctionCompletion,
+        emptySet(),
+        functionCompletionCall,
+        mockResultSet
+      )
       verify(mockResultSet).passResult(visibleChildFunctionCompletion)
 
-      val notVisibleChildFunctionCompletion = mockCompletionResult(
-        myFixture.findParentElement<KtFunction>("Modifier.notVisibleChild|Function():"))
+      val notVisibleChildFunctionCompletion =
+        mockCompletionResult(
+          myFixture.findParentElement<KtFunction>("Modifier.notVisibleChild|Function():")
+        )
       contributor.consumerCompletionResultFromRemainingContributor(
-        notVisibleChildFunctionCompletion, emptySet(), functionCompletionCall, mockResultSet)
+        notVisibleChildFunctionCompletion,
+        emptySet(),
+        functionCompletionCall,
+        mockResultSet
+      )
       verify(mockResultSet, never()).passResult(notVisibleChildFunctionCompletion)
     }
   }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposePositioningCompletionContributorTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposePositioningCompletionContributorTest.kt
index b4a93ef..020285a 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposePositioningCompletionContributorTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/ComposePositioningCompletionContributorTest.kt
@@ -30,13 +30,10 @@
 import org.junit.Rule
 import org.junit.Test
 
-/**
- * Test for [ComposePositioningCompletionContributor].
- */
+/** Test for [ComposePositioningCompletionContributor]. */
 class ComposePositioningCompletionContributorTest {
 
-  @get:Rule
-  val projectRule = AndroidProjectRule.inMemory().onEdt()
+  @get:Rule val projectRule = AndroidProjectRule.inMemory().onEdt()
 
   private val myFixture: CodeInsightTestFixture by lazy { projectRule.fixture }
 
@@ -47,7 +44,7 @@
 
     myFixture.addFileToProject(
       "/src/androidx/compose/ui/Alignment.kt",
-      //language=kotlin
+      // language=kotlin
       """
       package androidx.compose.ui
 
@@ -92,12 +89,13 @@
         val Left: Alignment.Horizontal = object : Alignment.Horizontal {}
         val Right: Alignment.Horizontal = object : Alignment.Horizontal {}
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.addFileToProject(
       "/src/androidx/compose/foundation/layout/Arrangement.kt",
-      //language=kotlin
+      // language=kotlin
       """
       package androidx.compose.foundation.layout
 
@@ -124,12 +122,13 @@
           val SpaceAround = object : Horizontal {}
         }
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.addFileToProject(
       "/src/com/example/Rows.kt",
-      //language=kotlin
+      // language=kotlin
       """
       package com.example
 
@@ -152,7 +151,9 @@
           horizontalOrVerticalArrangement: Arrangement.HorizontalOrVertical = Arrangement.Center,
           content: @Composable () -> Unit
       ) {}
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
   }
 
   @RunsInEdt
@@ -161,7 +162,7 @@
 
     myFixture.loadNewFile(
       "src/com/example/Test.kt",
-      //language=kotlin
+      // language=kotlin
       """
       package com.example
 
@@ -171,23 +172,29 @@
       fun HomeScreen() {
         RowWithAlignment(<caret>)
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     myFixture.completeBasic()
 
-    // Ordering: all Horizontal entries on `Alignment` should come first, followed by those on `AbsoluteAlignment`.
+    // Ordering: all Horizontal entries on `Alignment` should come first, followed by those on
+    // `AbsoluteAlignment`.
     val lookupStrings = myFixture.lookupElementStrings!!
-    assertThat(lookupStrings.subList(0, 3)).containsExactly(
-      "Alignment.Start",
-      "Alignment.CenterHorizontally",
-      "Alignment.End",
-    )
-    assertThat(lookupStrings.subList(3, 5)).containsExactly(
-      "AbsoluteAlignment.Left",
-      "AbsoluteAlignment.Right",
-    )
+    assertThat(lookupStrings.subList(0, 3))
+      .containsExactly(
+        "Alignment.Start",
+        "Alignment.CenterHorizontally",
+        "Alignment.End",
+      )
+    assertThat(lookupStrings.subList(3, 5))
+      .containsExactly(
+        "AbsoluteAlignment.Left",
+        "AbsoluteAlignment.Right",
+      )
 
-    val alignmentStartLookupItem = myFixture.lookupElements?.find { it.lookupString == "Alignment.Start" }!!
+    val alignmentStartLookupItem =
+      myFixture.lookupElements?.find { it.lookupString == "Alignment.Start" }!!
 
     val presentation = LookupElementPresentation()
     alignmentStartLookupItem.renderElement(presentation)
@@ -207,7 +214,8 @@
       fun HomeScreen() {
         RowWithAlignment(Alignment.Start)
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -217,7 +225,7 @@
 
     myFixture.loadNewFile(
       "src/com/example/Test.kt",
-      //language=kotlin
+      // language=kotlin
       """
       package com.example
 
@@ -227,23 +235,29 @@
       fun HomeScreen() {
         RowWithAlignment(<caret>)
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     myFixture.completeBasic()
 
-    // Ordering: all Horizontal entries on `Alignment` should come first, followed by those on `AbsoluteAlignment`.
+    // Ordering: all Horizontal entries on `Alignment` should come first, followed by those on
+    // `AbsoluteAlignment`.
     val lookupStrings = myFixture.lookupElementStrings!!
-    assertThat(lookupStrings.subList(0, 3)).containsExactly(
-      "Alignment.Start",
-      "Alignment.CenterHorizontally",
-      "Alignment.End",
-    )
-    assertThat(lookupStrings.subList(3, 5)).containsExactly(
-      "AbsoluteAlignment.Left",
-      "AbsoluteAlignment.Right",
-    )
+    assertThat(lookupStrings.subList(0, 3))
+      .containsExactly(
+        "Alignment.Start",
+        "Alignment.CenterHorizontally",
+        "Alignment.End",
+      )
+    assertThat(lookupStrings.subList(3, 5))
+      .containsExactly(
+        "AbsoluteAlignment.Left",
+        "AbsoluteAlignment.Right",
+      )
 
-    val alignmentStartLookupItem = myFixture.lookupElements?.find { it.lookupString == "AbsoluteAlignment.Left" }!!
+    val alignmentStartLookupItem =
+      myFixture.lookupElements?.find { it.lookupString == "AbsoluteAlignment.Left" }!!
 
     val presentation = LookupElementPresentation()
     alignmentStartLookupItem.renderElement(presentation)
@@ -263,7 +277,8 @@
       fun HomeScreen() {
         RowWithAlignment(AbsoluteAlignment.Left)
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -273,7 +288,7 @@
 
     myFixture.loadNewFile(
       "src/com/example/Test.kt",
-      //language=kotlin
+      // language=kotlin
       """
       package com.example
 
@@ -283,16 +298,20 @@
       fun HomeScreen() {
         RowWithAlignment(Alignment.<caret>)
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     myFixture.completeBasic()
 
-    // Ordering: all Horizontal entries on `Alignment` should come first. No entries from `AbsoluteAlignment` should be present.
+    // Ordering: all Horizontal entries on `Alignment` should come first. No entries from
+    // `AbsoluteAlignment` should be present.
     val lookupStrings = myFixture.lookupElementStrings!!
-    assertThat(lookupStrings.subList(0, 3)).containsExactly(
-      "Start",
-      "CenterHorizontally",
-      "End",
+    assertThat(lookupStrings.subList(0, 3))
+      .containsExactly(
+        "Start",
+        "CenterHorizontally",
+        "End",
       )
 
     assertThat(lookupStrings).doesNotContain("AbsoluteAlignment.Left")
@@ -320,7 +339,8 @@
       fun HomeScreen() {
         RowWithAlignment(Alignment.Start)
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -329,7 +349,7 @@
   fun verticalAlignmentCompletion() {
     myFixture.loadNewFile(
       "src/com/example/Test.kt",
-      //language=kotlin
+      // language=kotlin
       """
       package com.example
 
@@ -339,18 +359,23 @@
       fun HomeScreen() {
         RowWithAlignment(verticalAlignment = <caret>)
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
     myFixture.completeBasic()
 
-    // Ordering: all Vertical alignments on `Alignment` should come at the top. There are no Vertical entries on `AbsoluteAlignment`.
+    // Ordering: all Vertical alignments on `Alignment` should come at the top. There are no
+    // Vertical entries on `AbsoluteAlignment`.
     val lookupStrings = myFixture.lookupElementStrings!!
-    assertThat(lookupStrings.subList(0, 3)).containsExactly(
-      "Alignment.Top",
-      "Alignment.CenterVertically",
-      "Alignment.Bottom",
+    assertThat(lookupStrings.subList(0, 3))
+      .containsExactly(
+        "Alignment.Top",
+        "Alignment.CenterVertically",
+        "Alignment.Bottom",
       )
 
-    val centerVerticallyLookupElement = myFixture.lookupElements?.find { it.lookupString == "Alignment.CenterVertically" }!!
+    val centerVerticallyLookupElement =
+      myFixture.lookupElements?.find { it.lookupString == "Alignment.CenterVertically" }!!
 
     val presentation = LookupElementPresentation()
     centerVerticallyLookupElement.renderElement(presentation)
@@ -370,7 +395,8 @@
       fun HomeScreen() {
         RowWithAlignment(verticalAlignment = Alignment.CenterVertically)
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -379,7 +405,7 @@
   fun twoDimensionalAlignmentCompletion() {
     myFixture.loadNewFile(
       "src/com/example/Test.kt",
-      //language=kotlin
+      // language=kotlin
       """
       package com.example
 
@@ -389,32 +415,38 @@
       fun HomeScreen() {
         RowWithAlignment(twoDimensionalAlignment = <caret>)
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
     myFixture.completeBasic()
 
-    // Ordering: all 2D entries on `Alignment` should come first, followed by those on `AbsoluteAlignment`.
+    // Ordering: all 2D entries on `Alignment` should come first, followed by those on
+    // `AbsoluteAlignment`.
     val lookupStrings = myFixture.lookupElementStrings!!
-    assertThat(lookupStrings.subList(0, 9)).containsExactly(
-      "Alignment.TopStart",
-      "Alignment.TopCenter",
-      "Alignment.TopEnd",
-      "Alignment.CenterStart",
-      "Alignment.Center",
-      "Alignment.CenterEnd",
-      "Alignment.BottomStart",
-      "Alignment.BottomCenter",
-      "Alignment.BottomEnd",
-    )
-    assertThat(lookupStrings.subList(9, 15)).containsExactly(
-      "AbsoluteAlignment.TopLeft",
-      "AbsoluteAlignment.TopRight",
-      "AbsoluteAlignment.CenterLeft",
-      "AbsoluteAlignment.CenterRight",
-      "AbsoluteAlignment.BottomLeft",
-      "AbsoluteAlignment.BottomRight",
-    )
+    assertThat(lookupStrings.subList(0, 9))
+      .containsExactly(
+        "Alignment.TopStart",
+        "Alignment.TopCenter",
+        "Alignment.TopEnd",
+        "Alignment.CenterStart",
+        "Alignment.Center",
+        "Alignment.CenterEnd",
+        "Alignment.BottomStart",
+        "Alignment.BottomCenter",
+        "Alignment.BottomEnd",
+      )
+    assertThat(lookupStrings.subList(9, 15))
+      .containsExactly(
+        "AbsoluteAlignment.TopLeft",
+        "AbsoluteAlignment.TopRight",
+        "AbsoluteAlignment.CenterLeft",
+        "AbsoluteAlignment.CenterRight",
+        "AbsoluteAlignment.BottomLeft",
+        "AbsoluteAlignment.BottomRight",
+      )
 
-    val centerVerticallyLookupElement = myFixture.lookupElements?.find { it.lookupString == "Alignment.CenterStart" }!!
+    val centerVerticallyLookupElement =
+      myFixture.lookupElements?.find { it.lookupString == "Alignment.CenterStart" }!!
 
     val presentation = LookupElementPresentation()
     centerVerticallyLookupElement.renderElement(presentation)
@@ -434,7 +466,8 @@
       fun HomeScreen() {
         RowWithAlignment(twoDimensionalAlignment = Alignment.CenterStart)
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -443,7 +476,7 @@
   fun horizontalArrangementCompletion() {
     myFixture.loadNewFile(
       "src/com/example/Test.kt",
-      //language=kotlin
+      // language=kotlin
       """
       package com.example
 
@@ -453,30 +486,36 @@
       fun HomeScreen() {
         RowWithArrangement(<caret>)
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     myFixture.completeBasic()
 
-    // Ordering: all Horizontal entries on `Arrangement` should come first, followed by those on `Arrangement.Absolute`.
+    // Ordering: all Horizontal entries on `Arrangement` should come first, followed by those on
+    // `Arrangement.Absolute`.
     val lookupStrings = myFixture.lookupElementStrings!!
-    assertThat(lookupStrings.subList(0, 6)).containsExactly(
-      "Arrangement.Start",
-      "Arrangement.End",
-      "Arrangement.Center",
-      "Arrangement.SpaceEvenly",
-      "Arrangement.SpaceBetween",
-      "Arrangement.SpaceAround",
-    )
-    assertThat(lookupStrings.subList(6, 12)).containsExactly(
-      "Arrangement.Absolute.Left",
-      "Arrangement.Absolute.Center",
-      "Arrangement.Absolute.Right",
-      "Arrangement.Absolute.SpaceBetween",
-      "Arrangement.Absolute.SpaceEvenly",
-      "Arrangement.Absolute.SpaceAround",
-    )
+    assertThat(lookupStrings.subList(0, 6))
+      .containsExactly(
+        "Arrangement.Start",
+        "Arrangement.End",
+        "Arrangement.Center",
+        "Arrangement.SpaceEvenly",
+        "Arrangement.SpaceBetween",
+        "Arrangement.SpaceAround",
+      )
+    assertThat(lookupStrings.subList(6, 12))
+      .containsExactly(
+        "Arrangement.Absolute.Left",
+        "Arrangement.Absolute.Center",
+        "Arrangement.Absolute.Right",
+        "Arrangement.Absolute.SpaceBetween",
+        "Arrangement.Absolute.SpaceEvenly",
+        "Arrangement.Absolute.SpaceAround",
+      )
 
-    val startLookupElement = myFixture.lookupElements?.find { it.lookupString == "Arrangement.Center" }!!
+    val startLookupElement =
+      myFixture.lookupElements?.find { it.lookupString == "Arrangement.Center" }!!
 
     val presentation = LookupElementPresentation()
     startLookupElement.renderElement(presentation)
@@ -496,7 +535,8 @@
       fun HomeScreen() {
         RowWithArrangement(Arrangement.Center)
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -505,7 +545,7 @@
   fun horizontalArrangementCompletion_choosesAbsoluteArrangement() {
     myFixture.loadNewFile(
       "src/com/example/Test.kt",
-      //language=kotlin
+      // language=kotlin
       """
       package com.example
 
@@ -515,30 +555,36 @@
       fun HomeScreen() {
         RowWithArrangement(<caret>)
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     myFixture.completeBasic()
 
-    // Ordering: all Horizontal entries on `Arrangement` should come first, followed by those on `Arrangement.Absolute`.
+    // Ordering: all Horizontal entries on `Arrangement` should come first, followed by those on
+    // `Arrangement.Absolute`.
     val lookupStrings = myFixture.lookupElementStrings!!
-    assertThat(lookupStrings.subList(0, 6)).containsExactly(
-      "Arrangement.Start",
-      "Arrangement.End",
-      "Arrangement.Center",
-      "Arrangement.SpaceEvenly",
-      "Arrangement.SpaceBetween",
-      "Arrangement.SpaceAround",
-    )
-    assertThat(lookupStrings.subList(6, 12)).containsExactly(
-      "Arrangement.Absolute.Left",
-      "Arrangement.Absolute.Center",
-      "Arrangement.Absolute.Right",
-      "Arrangement.Absolute.SpaceBetween",
-      "Arrangement.Absolute.SpaceEvenly",
-      "Arrangement.Absolute.SpaceAround",
-    )
+    assertThat(lookupStrings.subList(0, 6))
+      .containsExactly(
+        "Arrangement.Start",
+        "Arrangement.End",
+        "Arrangement.Center",
+        "Arrangement.SpaceEvenly",
+        "Arrangement.SpaceBetween",
+        "Arrangement.SpaceAround",
+      )
+    assertThat(lookupStrings.subList(6, 12))
+      .containsExactly(
+        "Arrangement.Absolute.Left",
+        "Arrangement.Absolute.Center",
+        "Arrangement.Absolute.Right",
+        "Arrangement.Absolute.SpaceBetween",
+        "Arrangement.Absolute.SpaceEvenly",
+        "Arrangement.Absolute.SpaceAround",
+      )
 
-    val startLookupElement = myFixture.lookupElements?.find { it.lookupString == "Arrangement.Absolute.Center" }!!
+    val startLookupElement =
+      myFixture.lookupElements?.find { it.lookupString == "Arrangement.Absolute.Center" }!!
 
     val presentation = LookupElementPresentation()
     startLookupElement.renderElement(presentation)
@@ -558,7 +604,8 @@
       fun HomeScreen() {
         RowWithArrangement(Arrangement.Absolute.Center)
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -567,7 +614,7 @@
   fun horizontalArrangementCompletion_arrangementAlreadyCompleted() {
     myFixture.loadNewFile(
       "src/com/example/Test.kt",
-      //language=kotlin
+      // language=kotlin
       """
       package com.example
 
@@ -577,30 +624,36 @@
       fun HomeScreen() {
         RowWithArrangement(Arrangement.<caret>)
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     myFixture.completeBasic()
 
-    // Ordering: all Horizontal entries on `Arrangement` should come first, followed by those on `Arrangement.Absolute`.
+    // Ordering: all Horizontal entries on `Arrangement` should come first, followed by those on
+    // `Arrangement.Absolute`.
     val lookupStrings = myFixture.lookupElementStrings!!
-    assertThat(lookupStrings.subList(0, 6)).containsExactly(
-      "Start",
-      "End",
-      "Center",
-      "SpaceEvenly",
-      "SpaceBetween",
-      "SpaceAround",
-    )
-    assertThat(lookupStrings.subList(6, 12)).containsExactly(
-      "Absolute.Left",
-      "Absolute.Center",
-      "Absolute.Right",
-      "Absolute.SpaceBetween",
-      "Absolute.SpaceEvenly",
-      "Absolute.SpaceAround",
+    assertThat(lookupStrings.subList(0, 6))
+      .containsExactly(
+        "Start",
+        "End",
+        "Center",
+        "SpaceEvenly",
+        "SpaceBetween",
+        "SpaceAround",
+      )
+    assertThat(lookupStrings.subList(6, 12))
+      .containsExactly(
+        "Absolute.Left",
+        "Absolute.Center",
+        "Absolute.Right",
+        "Absolute.SpaceBetween",
+        "Absolute.SpaceEvenly",
+        "Absolute.SpaceAround",
       )
 
-    val startLookupElement = myFixture.lookupElements?.find { it.lookupString == "Absolute.Center" }!!
+    val startLookupElement =
+      myFixture.lookupElements?.find { it.lookupString == "Absolute.Center" }!!
 
     val presentation = LookupElementPresentation()
     startLookupElement.renderElement(presentation)
@@ -620,7 +673,8 @@
       fun HomeScreen() {
         RowWithArrangement(Arrangement.Absolute.Center)
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -629,7 +683,7 @@
   fun horizontalArrangementCompletion_arrangementAbsoluteAlreadyCompleted() {
     myFixture.loadNewFile(
       "src/com/example/Test.kt",
-      //language=kotlin
+      // language=kotlin
       """
       package com.example
 
@@ -639,19 +693,17 @@
       fun HomeScreen() {
         RowWithArrangement(Arrangement.Absolute.<caret>)
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     myFixture.completeBasic()
 
-    // Ordering: all Horizontal entries on `Arrangement` should come first. No entries from `Arrangement.Absolute` should be present.
+    // Ordering: all Horizontal entries on `Arrangement` should come first. No entries from
+    // `Arrangement.Absolute` should be present.
     val lookupStrings = myFixture.lookupElementStrings!!
-    assertThat(lookupStrings.subList(0, 6)).containsExactly(
-      "Left",
-      "Center",
-      "Right",
-      "SpaceBetween",
-      "SpaceEvenly",
-      "SpaceAround")
+    assertThat(lookupStrings.subList(0, 6))
+      .containsExactly("Left", "Center", "Right", "SpaceBetween", "SpaceEvenly", "SpaceAround")
 
     assertThat(lookupStrings).doesNotContain("Start")
     assertThat(lookupStrings).doesNotContain("End")
@@ -676,7 +728,8 @@
       fun HomeScreen() {
         RowWithArrangement(Arrangement.Absolute.Center)
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -685,7 +738,7 @@
   fun verticalArrangementCompletion() {
     myFixture.loadNewFile(
       "src/com/example/Test.kt",
-      //language=kotlin
+      // language=kotlin
       """
       package com.example
 
@@ -695,19 +748,23 @@
       fun HomeScreen() {
         RowWithArrangement(verticalArrangement = <caret>)
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
     myFixture.completeBasic()
 
-    // Ordering: all Vertical entries on `Arrangement` should come at the top. There are no Vertical entries on `Arrangement.Absolute`.
+    // Ordering: all Vertical entries on `Arrangement` should come at the top. There are no Vertical
+    // entries on `Arrangement.Absolute`.
     val lookupStrings = myFixture.lookupElementStrings!!
-    assertThat(lookupStrings.subList(0, 6)).containsExactly(
-      "Arrangement.Top",
-      "Arrangement.Bottom",
-      "Arrangement.Center",
-      "Arrangement.SpaceEvenly",
-      "Arrangement.SpaceBetween",
-      "Arrangement.SpaceAround",
-    )
+    assertThat(lookupStrings.subList(0, 6))
+      .containsExactly(
+        "Arrangement.Top",
+        "Arrangement.Bottom",
+        "Arrangement.Center",
+        "Arrangement.SpaceEvenly",
+        "Arrangement.SpaceBetween",
+        "Arrangement.SpaceAround",
+      )
 
     val topLookupElement = myFixture.lookupElements?.find { it.lookupString == "Arrangement.Top" }!!
 
@@ -729,7 +786,8 @@
       fun HomeScreen() {
         RowWithArrangement(verticalArrangement = Arrangement.Top)
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -738,7 +796,7 @@
   fun horizontalOrVerticalArrangementCompletion() {
     myFixture.loadNewFile(
       "src/com/example/Test.kt",
-      //language=kotlin
+      // language=kotlin
       """
       package com.example
 
@@ -748,20 +806,25 @@
       fun HomeScreen() {
         RowWithArrangement(horizontalOrVerticalArrangement = <caret>)
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
     myFixture.completeBasic()
 
-    // Ordering: all HorizontalOrVertical entries on `Arrangement` should come at the top. There are no HorizontalOrVertical entries on
+    // Ordering: all HorizontalOrVertical entries on `Arrangement` should come at the top. There are
+    // no HorizontalOrVertical entries on
     // `Arrangement.Absolute`.
     val lookupStrings = myFixture.lookupElementStrings!!
-    assertThat(lookupStrings.subList(0, 4)).containsExactly(
-      "Arrangement.Center",
-      "Arrangement.SpaceEvenly",
-      "Arrangement.SpaceBetween",
-      "Arrangement.SpaceAround",
-    )
+    assertThat(lookupStrings.subList(0, 4))
+      .containsExactly(
+        "Arrangement.Center",
+        "Arrangement.SpaceEvenly",
+        "Arrangement.SpaceBetween",
+        "Arrangement.SpaceAround",
+      )
 
-    val topLookupElement = myFixture.lookupElements?.find { it.lookupString == "Arrangement.SpaceEvenly" }!!
+    val topLookupElement =
+      myFixture.lookupElements?.find { it.lookupString == "Arrangement.SpaceEvenly" }!!
 
     val presentation = LookupElementPresentation()
     topLookupElement.renderElement(presentation)
@@ -781,7 +844,8 @@
       fun HomeScreen() {
         RowWithArrangement(horizontalOrVerticalArrangement = Arrangement.SpaceEvenly)
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -790,7 +854,7 @@
   fun duplicateLookupEntriesFromOtherContributorsHandled() {
     myFixture.loadNewFile(
       "src/com/example/Test.kt",
-      //language=kotlin
+      // language=kotlin
       """
       package com.example
 
@@ -803,11 +867,14 @@
         RowWithArrangement(horizontalArrangement = Arrangement.A)
         RowWithArrangement(horizontalArrangement = Arrangement.Absolute.L)
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     myFixture.moveCaret("(horizontalArrangement = A|)")
     myFixture.completeBasic()
-    assertThat(myFixture.lookupElementStrings!!.filter { it.startsWith("Arrangement") }).containsNoDuplicates()
+    assertThat(myFixture.lookupElementStrings!!.filter { it.startsWith("Arrangement") })
+      .containsNoDuplicates()
 
     myFixture.moveCaret("(horizontalArrangement = Arrangement.A|)")
     myFixture.completeBasic()
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/constraintlayout/ConstraintLayoutJsonCompletionContributorTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/constraintlayout/ConstraintLayoutJsonCompletionContributorTest.kt
index 6cf3ae9..e822340 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/constraintlayout/ConstraintLayoutJsonCompletionContributorTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/code/completion/constraintlayout/ConstraintLayoutJsonCompletionContributorTest.kt
@@ -28,10 +28,10 @@
 import org.junit.Test
 
 internal class ConstraintLayoutJsonCompletionContributorTest {
-  // TODO(b/207030860): Change test class to 'LightPlatformCodeInsightFixture4TestCase' once/if we remove the Compose requirement
+  // TODO(b/207030860): Change test class to 'LightPlatformCodeInsightFixture4TestCase' once/if we
+  // remove the Compose requirement
 
-  @get:Rule
-  val projectRule = AndroidProjectRule.inMemory()
+  @get:Rule val projectRule = AndroidProjectRule.inMemory()
 
   private val myFixture: CodeInsightTestFixture by lazy { projectRule.fixture }
 
@@ -42,7 +42,8 @@
 
   @Test
   fun completeConstraintSetFields() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           start: {
@@ -56,7 +57,9 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     val items = myFixture.lookupElementStrings!!
     assertThat(items).hasSize(2)
     assertThat((items[0])).isEqualTo("id2")
@@ -65,7 +68,8 @@
 
   @Test
   fun completeExtendsValue() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           start: {
@@ -76,14 +80,17 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     assertThat(myFixture.lookupElementStrings!!).hasSize(1)
     assertThat(myFixture.lookupElementStrings!![0]).isEqualTo("start")
   }
 
   @Test
   fun completeConstraintBlockFields() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           start: {
@@ -94,7 +101,9 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     val lookupElements = myFixture.lookupElementStrings!!
     assertThat(lookupElements).hasSize(19)
     assertThat(lookupElements).containsNoDuplicates()
@@ -106,7 +115,8 @@
 
   @Test
   fun completeDimensionBehaviors() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           start: {
@@ -116,7 +126,9 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     val lookupElements = myFixture.lookupElementStrings!!
 
     assertThat(lookupElements).hasSize(4)
@@ -125,7 +137,8 @@
 
   @Test
   fun completeVisibilityModes() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           start: {
@@ -135,7 +148,9 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     val lookupElements = myFixture.lookupElementStrings!!
 
     assertThat(lookupElements).hasSize(3)
@@ -144,7 +159,8 @@
 
   @Test
   fun completeConstraintIdsInArray() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           start: {
@@ -156,7 +172,9 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     val lookupElements = myFixture.lookupElementStrings!!
 
     assertThat(lookupElements).hasSize(3)
@@ -165,7 +183,8 @@
 
   @Test
   fun completeConstraintIdsInSpecialAnchors() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           start: {
@@ -177,7 +196,9 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     val lookupElements = myFixture.lookupElementStrings!!
 
     assertThat(lookupElements).hasSize(3)
@@ -186,7 +207,8 @@
 
   @Test
   fun completeAnchorsInConstraintArray() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           start: {
@@ -196,12 +218,15 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     val lookupElements1 = myFixture.lookupElementStrings!!
     assertThat(lookupElements1).hasSize(4)
     assertThat(lookupElements1).containsExactly("end", "left", "right", "start")
 
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           start: {
@@ -211,7 +236,9 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     val lookupElements2 = myFixture.lookupElementStrings!!
     assertThat(lookupElements2).hasSize(3)
     assertThat(lookupElements2).containsExactly("top", "bottom", "baseline")
@@ -219,7 +246,8 @@
 
   @Test
   fun constraintAnchorHandlerResult() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           start: {
@@ -229,7 +257,9 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     myFixture.checkResult(
       // language=JSON5
       """
@@ -242,13 +272,15 @@
           }
         }
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
   @Test
   fun completionHandlerResult() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           start: {
@@ -259,9 +291,11 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     myFixture.checkResult(
-      //language=JSON5
+      // language=JSON5
       """{
   ConstraintSets: {
     start: {
@@ -273,9 +307,11 @@
       }
     }
   }
-}""")
+}"""
+    )
 
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           start: {
@@ -283,7 +319,9 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     myFixture.checkResult(
       // language=JSON5
       """{
@@ -292,12 +330,14 @@
       Extends: '$caret',
     }
   }
-}""")
+}"""
+    )
   }
 
   @Test
   fun completeTransitionFields() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         Transitions: {
           default: {
@@ -306,7 +346,9 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
 
     val lookupElements = myFixture.lookupElementStrings!!
     assertThat(lookupElements).containsExactly("to", "KeyFrames", "pathMotionArc", "onSwipe")
@@ -314,7 +356,8 @@
 
   @Test
   fun completeTransitionFromAndTo() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           a: {},
@@ -329,10 +372,13 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     assertThat(myFixture.lookupElementStrings!!).containsExactly("a", "b", "c", "d")
 
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           e: {},
@@ -347,13 +393,16 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     assertThat(myFixture.lookupElementStrings!!).containsExactly("e", "f", "g", "h")
   }
 
   @Test
   fun completeClearField() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           a: {},
@@ -365,14 +414,17 @@
           },
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     // The repeated clear is to autocomplete with all options populated
     assertThat(myFixture.lookupElementStrings!!).containsExactly("clear", "clear")
   }
 
   @Test
   fun completeClearOptions() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           a: {},
@@ -384,10 +436,14 @@
           },
         }
       }
-    """.trimIndent())
-    assertThat(myFixture.lookupElementStrings!!).containsExactly("constraints", "dimensions", "transforms")
+    """
+        .trimIndent()
+    )
+    assertThat(myFixture.lookupElementStrings!!)
+      .containsExactly("constraints", "dimensions", "transforms")
 
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           a: {},
@@ -399,14 +455,17 @@
           },
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     // 'constraints' options is already populated
     assertThat(myFixture.lookupElementStrings!!).containsExactly("dimensions", "transforms")
   }
 
   @Test
   fun completeOnSwipeFieldsAndValues() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         Transitions: {
           default: {
@@ -417,10 +476,13 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     assertThat(myFixture.lookupElementStrings!!).containsExactly("side", "direction", "mode")
 
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         Transitions: {
           default: {
@@ -430,8 +492,11 @@
           }
         }
       }
-    """.trimIndent())
-    myFixture.checkResult("""
+    """
+        .trimIndent()
+    )
+    myFixture.checkResult(
+      """
       {
         Transitions: {
           default: {
@@ -441,9 +506,12 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
 
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         Transitions: {
           default: {
@@ -453,8 +521,11 @@
           }
         }
       }
-    """.trimIndent())
-    myFixture.checkResult("""
+    """
+        .trimIndent()
+    )
+    myFixture.checkResult(
+      """
       {
         Transitions: {
           default: {
@@ -464,9 +535,12 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
 
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         Transitions: {
           default: {
@@ -476,8 +550,11 @@
           }
         }
       }
-    """.trimIndent())
-    myFixture.checkResult("""
+    """
+        .trimIndent()
+    )
+    myFixture.checkResult(
+      """
       {
         Transitions: {
           default: {
@@ -487,9 +564,12 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
 
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         ConstraintSets: {
           start: {
@@ -511,13 +591,16 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     assertThat(myFixture.lookupElementStrings!!).containsExactly("parent", "a", "b", "c", "d", "e")
   }
 
   @Test
   fun completeKeyFramesFields() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         Transitions: {
           default: {
@@ -527,13 +610,17 @@
           }
         }
       }
-    """.trimIndent())
-    assertThat(myFixture.lookupElementStrings!!).containsExactly("KeyAttributes", "KeyPositions", "KeyCycles")
+    """
+        .trimIndent()
+    )
+    assertThat(myFixture.lookupElementStrings!!)
+      .containsExactly("KeyAttributes", "KeyPositions", "KeyCycles")
   }
 
   @Test
   fun completeKeyAttributesFields() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         Transitions: {
           default: {
@@ -545,28 +632,32 @@
           }
         }
       }
-    """.trimIndent())
-    assertThat(myFixture.lookupElementStrings!!).containsExactly(
-      "target",
-      "frames",
-      "transitionEasing",
-      "curveFit",
-      // Attributes specific:
-      "alpha",
-      "scaleX",
-      "scaleY",
-      "rotationX",
-      "rotationY",
-      "rotationZ",
-      "translationX",
-      "translationY",
-      "translationZ",
+    """
+        .trimIndent()
     )
+    assertThat(myFixture.lookupElementStrings!!)
+      .containsExactly(
+        "target",
+        "frames",
+        "transitionEasing",
+        "curveFit",
+        // Attributes specific:
+        "alpha",
+        "scaleX",
+        "scaleY",
+        "rotationX",
+        "rotationY",
+        "rotationZ",
+        "translationX",
+        "translationY",
+        "translationZ",
+      )
   }
 
   @Test
   fun completeKeyPositionsFields() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         Transitions: {
           default: {
@@ -578,25 +669,29 @@
           }
         }
       }
-    """.trimIndent())
-    assertThat(myFixture.lookupElementStrings!!).containsExactly(
-      "target",
-      "frames",
-      "transitionEasing",
-      "curveFit",
-      // Position specific:
-      "percentX",
-      "percentY",
-      "percentWidth",
-      "percentHeight",
-      "pathMotionArc",
-      "type"
+    """
+        .trimIndent()
     )
+    assertThat(myFixture.lookupElementStrings!!)
+      .containsExactly(
+        "target",
+        "frames",
+        "transitionEasing",
+        "curveFit",
+        // Position specific:
+        "percentX",
+        "percentY",
+        "percentWidth",
+        "percentHeight",
+        "pathMotionArc",
+        "type"
+      )
   }
 
   @Test
   fun completeKeyCyclesFields() {
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         Transitions: {
           default: {
@@ -608,33 +703,37 @@
           }
         }
       }
-    """.trimIndent())
-    assertThat(myFixture.lookupElementStrings!!).containsExactly(
-      "target",
-      "frames",
-      "transitionEasing",
-      "curveFit",
-      // Cycles specific:
-      "period",
-      "offset",
-      "phase",
-      // Shared with KeyAttributes:
-      "alpha",
-      "scaleX",
-      "scaleY",
-      "rotationX",
-      "rotationY",
-      "rotationZ",
-      "translationX",
-      "translationY",
-      "translationZ",
+    """
+        .trimIndent()
     )
+    assertThat(myFixture.lookupElementStrings!!)
+      .containsExactly(
+        "target",
+        "frames",
+        "transitionEasing",
+        "curveFit",
+        // Cycles specific:
+        "period",
+        "offset",
+        "phase",
+        // Shared with KeyAttributes:
+        "alpha",
+        "scaleX",
+        "scaleY",
+        "rotationX",
+        "rotationY",
+        "rotationZ",
+        "translationX",
+        "translationY",
+        "translationZ",
+      )
   }
 
   @Test
   fun completeKeyFrameChildPropertyWithAtLeastOneElement() {
     // `frames` with empty array
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         Transitions: {
           default: {
@@ -647,8 +746,11 @@
           }
         }
       }
-    """.trimIndent())
-    myFixture.checkResult("""
+    """
+        .trimIndent()
+    )
+    myFixture.checkResult(
+      """
       {
         Transitions: {
           default: {
@@ -661,10 +763,13 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
 
     // No `frames` property
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         Transitions: {
           default: {
@@ -676,8 +781,11 @@
           }
         }
       }
-    """.trimIndent())
-    myFixture.checkResult("""
+    """
+        .trimIndent()
+    )
+    myFixture.checkResult(
+      """
       {
         Transitions: {
           default: {
@@ -689,10 +797,13 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
 
     // Completing `frames` for first time
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         Transitions: {
           default: {
@@ -704,8 +815,11 @@
           }
         }
       }
-    """.trimIndent())
-    myFixture.checkResult("""
+    """
+        .trimIndent()
+    )
+    myFixture.checkResult(
+      """
       {
         Transitions: {
           default: {
@@ -717,13 +831,17 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
   }
 
   @Test
   fun completeKeyFrameChildPropertyWithArray() {
-    // A completed number based property should be initialized with an array matching the same number of items as the `frames` property
-    myFixture.completeJson5Text("""
+    // A completed number based property should be initialized with an array matching the same
+    // number of items as the `frames` property
+    myFixture.completeJson5Text(
+      """
       {
         Transitions: {
           default: {
@@ -736,8 +854,11 @@
           }
         }
       }
-    """.trimIndent())
-    myFixture.checkResult("""
+    """
+        .trimIndent()
+    )
+    myFixture.checkResult(
+      """
       {
         Transitions: {
           default: {
@@ -750,10 +871,14 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
 
-    // Completed parameter should match `frames` size array regardless of the size of other parameters
-    myFixture.completeJson5Text("""
+    // Completed parameter should match `frames` size array regardless of the size of other
+    // parameters
+    myFixture.completeJson5Text(
+      """
       {
         Transitions: {
           default: {
@@ -767,8 +892,11 @@
           }
         }
       }
-    """.trimIndent())
-    myFixture.checkResult("""
+    """
+        .trimIndent()
+    )
+    myFixture.checkResult(
+      """
       {
         Transitions: {
           default: {
@@ -782,10 +910,13 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
 
     // Text based properties should not be initialized with an array
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         Transitions: {
           default: {
@@ -798,8 +929,11 @@
           }
         }
       }
-    """.trimIndent())
-    myFixture.checkResult("""
+    """
+        .trimIndent()
+    )
+    myFixture.checkResult(
+      """
       {
         Transitions: {
           default: {
@@ -812,13 +946,16 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
   }
 
   @Test
   fun completionIsCaseSensitive() {
     // Using wrong casing
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         Transitions: {
           default: {
@@ -826,9 +963,12 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     // Not changes in result
-    myFixture.checkResult("""
+    myFixture.checkResult(
+      """
       {
         Transitions: {
           default: {
@@ -836,10 +976,13 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
 
     // With correct casing
-    myFixture.completeJson5Text("""
+    myFixture.completeJson5Text(
+      """
       {
         Transitions: {
           default: {
@@ -847,9 +990,12 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
     // Expression completed properly
-    myFixture.checkResult("""
+    myFixture.checkResult(
+      """
       {
         Transitions: {
           default: {
@@ -859,11 +1005,13 @@
           }
         }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
   }
 }
 
 private fun CodeInsightTestFixture.completeJson5Text(@Language("JSON5") text: String) {
   configureByText(Json5FileType.INSTANCE, text)
   completeBasic()
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/ComposeDebuggerTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/ComposeDebuggerTest.kt
index 467bb28..760c235 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/ComposeDebuggerTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/ComposeDebuggerTest.kt
@@ -23,13 +23,12 @@
 import com.intellij.ui.classFilter.DebuggerClassFilterProvider
 import com.intellij.xdebugger.impl.settings.XDebuggerSettingManagerImpl
 import com.intellij.xdebugger.settings.DebuggerSettingsCategory
+import javax.swing.JCheckBox
 import org.junit.Rule
 import org.junit.Test
-import javax.swing.JCheckBox
 
 class ComposeDebuggerTest {
-  @get:Rule
-  val projectRule = AndroidProjectRule.inMemory()
+  @get:Rule val projectRule = AndroidProjectRule.inMemory()
 
   private fun getClassFilterPatterns(): List<String> =
     DebuggerClassFilterProvider.EP_NAME.extensionList.flatMap { it.filters }.map { it.pattern }
@@ -55,7 +54,9 @@
 
     val element = serialize(settingsManager.state!!)
     settings.filterComposeRuntimeClasses = true
-    settingsManager.loadState(element!!.deserialize(XDebuggerSettingManagerImpl.SettingsState::class.java))
+    settingsManager.loadState(
+      element!!.deserialize(XDebuggerSettingManagerImpl.SettingsState::class.java)
+    )
     assert(!settings.filterComposeRuntimeClasses)
   }
 
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/ComposePositionManagerTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/ComposePositionManagerTest.kt
index edab98a..ef046ed 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/ComposePositionManagerTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/ComposePositionManagerTest.kt
@@ -24,15 +24,15 @@
 import org.junit.Test
 
 class ComposePositionManagerTest {
-  @get:Rule
-  val projectRule = AndroidProjectRule.inMemory()
+  @get:Rule val projectRule = AndroidProjectRule.inMemory()
 
   private val project: Project
     get() = projectRule.project
 
   @Test
   fun testComposeSingletonClasses() {
-    val source = """
+    val source =
+      """
       package a;
       import androidx.compose.runtime.Composable
 
@@ -45,21 +45,23 @@
 
         fun g(@Composable () -> Unit) {}
       }
-    """.trimIndent()
+    """
+        .trimIndent()
     val file = projectRule.fixture.addFileToProject("src/a/test.kt", source)
 
-    val debugProcess = mockDebugProcess(project, projectRule.testRootDisposable) {
-      classType("a.A") {
-        method("f", lines = listOf(4, 5, 6, 7, 8))
-        method("g", lines = listOf(10))
-      }
+    val debugProcess =
+      mockDebugProcess(project, projectRule.testRootDisposable) {
+        classType("a.A") {
+          method("f", lines = listOf(4, 5, 6, 7, 8))
+          method("g", lines = listOf(10))
+        }
 
-      classType("a.ComposableSingletons\$TestKt")
+        classType("a.ComposableSingletons\$TestKt")
 
-      classType("a.ComposableSingletons\$TestKt\$lambda-1") {
-        method("invoke", lines = listOf(5, 6, 7))
+        classType("a.ComposableSingletons\$TestKt\$lambda-1") {
+          method("invoke", lines = listOf(5, 6, 7))
+        }
       }
-    }
     val composePositionManager =
       ComposePositionManagerFactory().createPositionManager(debugProcess) as ComposePositionManager
 
@@ -75,7 +77,8 @@
 
   @Test
   fun testComposeSingletonClassesJvmName() {
-    val source = """
+    val source =
+      """
       @file:JvmName("FileClass")
       package a;
       import androidx.compose.runtime.Composable
@@ -87,21 +90,23 @@
       }
 
       fun g(@Composable () -> Unit) {}
-    """.trimIndent()
+    """
+        .trimIndent()
     val file = projectRule.fixture.addFileToProject("src/a/test2.kt", source)
 
-    val debugProcess = mockDebugProcess(project, projectRule.testRootDisposable) {
-      classType("a.FileClass") {
-        method("f", lines = listOf(4, 5, 6, 7, 8))
-        method("g", lines = listOf(10))
-      }
+    val debugProcess =
+      mockDebugProcess(project, projectRule.testRootDisposable) {
+        classType("a.FileClass") {
+          method("f", lines = listOf(4, 5, 6, 7, 8))
+          method("g", lines = listOf(10))
+        }
 
-      classType("a.ComposableSingletons\$Test2Kt")
+        classType("a.ComposableSingletons\$Test2Kt")
 
-      classType("a.ComposableSingletons\$Test2Kt\$lambda-1") {
-        method("invoke", lines = listOf(5, 6, 7))
+        classType("a.ComposableSingletons\$Test2Kt\$lambda-1") {
+          method("invoke", lines = listOf(5, 6, 7))
+        }
       }
-    }
     val composePositionManager =
       ComposePositionManagerFactory().createPositionManager(debugProcess) as ComposePositionManager
 
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/recomposition/ParamStateTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/recomposition/ParamStateTest.kt
index 1f3ac43..7cb33c3 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/recomposition/ParamStateTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/recomposition/ParamStateTest.kt
@@ -18,67 +18,72 @@
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 
-/**
- * Tests for [ParamState]
- */
+/** Tests for [ParamState] */
 class ParamStateTest {
   @Test
   fun oneFullValue() {
     val states = ParamState.decode(listOf(0b1111101011000110100010000010101))
 
-    assertThat(states.map { it.getDisplayName() }).containsExactly(
-      "Changed",
-      "Unchanged",
-      "Evaluating",
-      "Unchanged",
-      "Changed",
-      "Static",
-      "Unknown",
-      "Unknown",
-      "Unknown",
-      "Unknown",
-    ).inOrder()
+    assertThat(states.map { it.getDisplayName() })
+      .containsExactly(
+        "Changed",
+        "Unchanged",
+        "Evaluating",
+        "Unchanged",
+        "Changed",
+        "Static",
+        "Unknown",
+        "Unknown",
+        "Unknown",
+        "Unknown",
+      )
+      .inOrder()
   }
 
   @Test
   fun multipleValuea() {
-    val states = ParamState.decode(listOf(
-      0b1111101011000110100010000010101,
-      0b1111101011000110100010000010100,
-      0b0010,
-    ))
+    val states =
+      ParamState.decode(
+        listOf(
+          0b1111101011000110100010000010101,
+          0b1111101011000110100010000010100,
+          0b0010,
+        )
+      )
 
-    assertThat(states.map { it.getDisplayName() }).containsExactly(
-      "Changed",
-      "Unchanged",
-      "Evaluating",
-      "Unchanged",
-      "Changed",
-      "Static",
-      "Unknown",
-      "Unknown",
-      "Unknown",
-      "Unknown",
-      "Changed",
-      "Unchanged",
-      "Evaluating",
-      "Unchanged",
-      "Changed",
-      "Static",
-      "Unknown",
-      "Unknown",
-      "Unknown",
-      "Unknown",
-      "Unchanged",
-      "Evaluating",
-      "Evaluating",
-      "Evaluating",
-      "Evaluating",
-      "Evaluating",
-      "Evaluating",
-      "Evaluating",
-      "Evaluating",
-      "Evaluating",
-      ).inOrder()
+    assertThat(states.map { it.getDisplayName() })
+      .containsExactly(
+        "Changed",
+        "Unchanged",
+        "Evaluating",
+        "Unchanged",
+        "Changed",
+        "Static",
+        "Unknown",
+        "Unknown",
+        "Unknown",
+        "Unknown",
+        "Changed",
+        "Unchanged",
+        "Evaluating",
+        "Unchanged",
+        "Changed",
+        "Static",
+        "Unknown",
+        "Unknown",
+        "Unknown",
+        "Unknown",
+        "Unchanged",
+        "Evaluating",
+        "Evaluating",
+        "Evaluating",
+        "Evaluating",
+        "Evaluating",
+        "Evaluating",
+        "Evaluating",
+        "Evaluating",
+        "Evaluating",
+      )
+      .inOrder()
   }
 }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/render/ComposeStateObjectRendererTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/render/ComposeStateObjectRendererTest.kt
index 0e6fbe4..9a45e5b 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/render/ComposeStateObjectRendererTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/render/ComposeStateObjectRendererTest.kt
@@ -23,7 +23,6 @@
 import com.android.tools.compose.debug.utils.invokeOnDebuggerManagerThread
 import com.android.tools.compose.debug.utils.mockDebugProcess
 import com.android.tools.compose.debug.utils.mockEvaluationContext
-
 import com.android.tools.idea.testing.AndroidProjectRule
 import com.google.common.truth.Truth.assertThat
 import com.intellij.debugger.engine.DebugProcessImpl
@@ -35,50 +34,58 @@
 import org.junit.Test
 
 class ComposeStateObjectRendererTest {
-  @get:Rule
-  val projectRule = AndroidProjectRule.inMemory()
+  @get:Rule val projectRule = AndroidProjectRule.inMemory()
 
   private val project
     get() = projectRule.project
 
   @Test
   fun renderList() {
-    val source = """
+    val source =
+      """
       package androidx.compose.runtime.snapshots
 
       class SnapshotStateList<T> {}
-    """.trimIndent()
-    projectRule.fixture.addFileToProject("src/androidx/compose/runtime/snapshots/SnapshotStateList.kt", source)
+    """
+        .trimIndent()
+    projectRule.fixture.addFileToProject(
+      "src/androidx/compose/runtime/snapshots/SnapshotStateList.kt",
+      source
+    )
 
     // prepare
-    val debugProcess: DebugProcessImpl = mockDebugProcess(project, projectRule.testRootDisposable) {
-      val vm = this@mockDebugProcess.virtualMachineProxy.virtualMachine
+    val debugProcess: DebugProcessImpl =
+      mockDebugProcess(project, projectRule.testRootDisposable) {
+        val vm = this@mockDebugProcess.virtualMachineProxy.virtualMachine
 
-      val listType = classType("java.util.List") {
-        method("size", "()I") {
-          value(MockIntegerValue(7, vm))
+        val listType =
+          classType("java.util.List") { method("size", "()I") { value(MockIntegerValue(7, vm)) } }
+
+        classType("androidx.compose.runtime.snapshots.SnapshotStateList") {
+          method("getDebuggerDisplayValue", "()Ljava/util/List;") {
+            value(MockClassObjectReference(listType, vm))
+          }
         }
       }
 
-      classType("androidx.compose.runtime.snapshots.SnapshotStateList") {
-        method("getDebuggerDisplayValue", "()Ljava/util/List;") {
-          value(MockClassObjectReference(listType, vm))
-        }
-      }
-    }
-
-    val thisObjectType: ReferenceType = debugProcess.virtualMachineProxy
-      .classesByName("androidx.compose.runtime.snapshots.SnapshotStateList")
-      .first()
+    val thisObjectType: ReferenceType =
+      debugProcess.virtualMachineProxy
+        .classesByName("androidx.compose.runtime.snapshots.SnapshotStateList")
+        .first()
 
     debugProcess.invokeOnDebuggerManagerThread {
       // 1. check `Compose SnapshotStateList` is the first selected renderer by default.
-      val renderer = NodeRendererSettings.getInstance().getAllRenderers(projectRule.project)
-        .filter { it.isEnabled }
-        .first { (it as? CompoundReferenceRenderer)?.isApplicableAsync(thisObjectType)?.get() == true }
+      val renderer =
+        NodeRendererSettings.getInstance()
+          .getAllRenderers(projectRule.project)
+          .filter { it.isEnabled }
+          .first {
+            (it as? CompoundReferenceRenderer)?.isApplicableAsync(thisObjectType)?.get() == true
+          }
       assertThat(renderer.name).isEqualTo("Compose State Object")
 
-      val thisObjectValue = MockClassObjectReference(thisObjectType, debugProcess.virtualMachineProxy.virtualMachine)
+      val thisObjectValue =
+        MockClassObjectReference(thisObjectType, debugProcess.virtualMachineProxy.virtualMachine)
       val evaluationContext = mockEvaluationContext(debugProcess, thisObjectValue)
       val thisValueDescriptor = MockValueDescriptor(project, thisObjectValue)
 
@@ -89,48 +96,56 @@
 
       // 3. check if the children renderer is the same as the label renderer.
       val childrenRenderer = (renderer as CompoundReferenceRenderer).childrenRenderer
-      assertThat(childrenRenderer.uniqueId).isEqualTo("androidx.compose.runtime.snapshots.SnapshotStateList")
+      assertThat(childrenRenderer.uniqueId)
+        .isEqualTo("androidx.compose.runtime.snapshots.SnapshotStateList")
     }
   }
 
   @Test
   fun renderMap() {
-    val source = """
+    val source =
+      """
       package androidx.compose.runtime.snapshots
 
       class SnapshotStateMap<K, V> {}
-    """.trimIndent()
-    projectRule.fixture.addFileToProject("src/androidx/compose/runtime/snapshots/SnapshotStateMap.kt", source)
+    """
+        .trimIndent()
+    projectRule.fixture.addFileToProject(
+      "src/androidx/compose/runtime/snapshots/SnapshotStateMap.kt",
+      source
+    )
 
     // prepare
-    val debugProcess: DebugProcessImpl = mockDebugProcess(project, projectRule.testRootDisposable) {
-      val vm = this@mockDebugProcess.virtualMachineProxy.virtualMachine
+    val debugProcess: DebugProcessImpl =
+      mockDebugProcess(project, projectRule.testRootDisposable) {
+        val vm = this@mockDebugProcess.virtualMachineProxy.virtualMachine
 
-      val mapType = classType("java.util.Map") {
-        method("size", "()I") {
-          value(MockIntegerValue(5, vm))
+        val mapType =
+          classType("java.util.Map") { method("size", "()I") { value(MockIntegerValue(5, vm)) } }
+
+        classType("androidx.compose.runtime.snapshots.SnapshotStateMap") {
+          method("getDebuggerDisplayValue") { value(MockClassObjectReference(mapType, vm)) }
         }
       }
 
-      classType("androidx.compose.runtime.snapshots.SnapshotStateMap") {
-        method("getDebuggerDisplayValue") {
-          value(MockClassObjectReference(mapType, vm))
-        }
-      }
-    }
-
-    val thisObjectType: ReferenceType = debugProcess.virtualMachineProxy
-      .classesByName("androidx.compose.runtime.snapshots.SnapshotStateMap")
-      .first()
+    val thisObjectType: ReferenceType =
+      debugProcess.virtualMachineProxy
+        .classesByName("androidx.compose.runtime.snapshots.SnapshotStateMap")
+        .first()
 
     debugProcess.invokeOnDebuggerManagerThread {
       // 1. check `"Compose SnapshotStateList"` is the first selected renderer by default.
-      val renderer = NodeRendererSettings.getInstance().getAllRenderers(projectRule.project)
-        .filter { it.isEnabled }
-        .first { (it as? CompoundReferenceRenderer)?.isApplicableAsync(thisObjectType)?.get() == true }
+      val renderer =
+        NodeRendererSettings.getInstance()
+          .getAllRenderers(projectRule.project)
+          .filter { it.isEnabled }
+          .first {
+            (it as? CompoundReferenceRenderer)?.isApplicableAsync(thisObjectType)?.get() == true
+          }
       assertThat(renderer.name).isEqualTo("Compose State Object")
 
-      val thisObjectValue = MockClassObjectReference(thisObjectType, debugProcess.virtualMachineProxy.virtualMachine)
+      val thisObjectValue =
+        MockClassObjectReference(thisObjectType, debugProcess.virtualMachineProxy.virtualMachine)
       val evaluationContext = mockEvaluationContext(debugProcess, thisObjectValue)
       val thisValueDescriptor = MockValueDescriptor(project, thisObjectValue)
 
@@ -141,151 +156,190 @@
 
       // 3. check if the children renderer is the same as the label renderer.
       val childrenRenderer = (renderer as CompoundReferenceRenderer).childrenRenderer
-      assertThat(childrenRenderer.uniqueId).isEqualTo("androidx.compose.runtime.snapshots.SnapshotStateMap")
+      assertThat(childrenRenderer.uniqueId)
+        .isEqualTo("androidx.compose.runtime.snapshots.SnapshotStateMap")
     }
   }
 
   @Test
   fun renderInteger() {
-    val source = """
+    val source =
+      """
       package androidx.compose.runtime
 
       open class SnapshotMutableStateImpl<T> {}
 
       class ParcelableSnapshotMutableState : SnapshotMutableStateImpl<T>
-    """.trimIndent()
-    projectRule.fixture.addFileToProject("src/androidx/compose/runtime/SnapshotMutableStateImpl.kt", source)
+    """
+        .trimIndent()
+    projectRule.fixture.addFileToProject(
+      "src/androidx/compose/runtime/SnapshotMutableStateImpl.kt",
+      source
+    )
 
-    val debugProcess: DebugProcessImpl = mockDebugProcess(project, projectRule.testRootDisposable) {
-      val vm = this@mockDebugProcess.virtualMachineProxy.virtualMachine
+    val debugProcess: DebugProcessImpl =
+      mockDebugProcess(project, projectRule.testRootDisposable) {
+        val vm = this@mockDebugProcess.virtualMachineProxy.virtualMachine
 
-      val snapshotMutableStateImplType = classType("androidx.compose.runtime.SnapshotMutableStateImpl") {
-        method("getDebuggerDisplayValue") {
-          value(MockIntegerValue(1, vm))
+        val snapshotMutableStateImplType =
+          classType("androidx.compose.runtime.SnapshotMutableStateImpl") {
+            method("getDebuggerDisplayValue") { value(MockIntegerValue(1, vm)) }
+          }
+
+        classType(
+          "androidx.compose.runtime.ParcelableSnapshotMutableState",
+          snapshotMutableStateImplType as ClassType
+        ) {
+          method("getDebuggerDisplayValue") { value(MockIntegerValue(2, vm)) }
         }
       }
 
-      classType("androidx.compose.runtime.ParcelableSnapshotMutableState", snapshotMutableStateImplType as ClassType) {
-        method("getDebuggerDisplayValue") {
-          value(MockIntegerValue(2, vm))
-        }
-      }
-    }
-
-    val thisObjectType: ReferenceType = debugProcess.virtualMachineProxy
-      .classesByName("androidx.compose.runtime.ParcelableSnapshotMutableState")
-      .first()
+    val thisObjectType: ReferenceType =
+      debugProcess.virtualMachineProxy
+        .classesByName("androidx.compose.runtime.ParcelableSnapshotMutableState")
+        .first()
 
     debugProcess.invokeOnDebuggerManagerThread {
       // check `Compose SnapshotState` is the first selected renderer by default.
-      val renderer = NodeRendererSettings.getInstance().getAllRenderers(project)
-        .filter { it.isEnabled }
-        .first { (it as? CompoundReferenceRenderer)?.isApplicableAsync(thisObjectType)?.get() == true }
+      val renderer =
+        NodeRendererSettings.getInstance()
+          .getAllRenderers(project)
+          .filter { it.isEnabled }
+          .first {
+            (it as? CompoundReferenceRenderer)?.isApplicableAsync(thisObjectType)?.get() == true
+          }
 
       assertThat(renderer.name).isEqualTo("Compose State Object")
 
-      val thisObjectValue = MockClassObjectReference(thisObjectType, debugProcess.virtualMachineProxy.virtualMachine)
+      val thisObjectValue =
+        MockClassObjectReference(thisObjectType, debugProcess.virtualMachineProxy.virtualMachine)
       val thisValueDescriptor = MockValueDescriptor(project, thisObjectValue)
       val evaluationContext = mockEvaluationContext(debugProcess, thisObjectValue)
 
-      // check if the label is eventually properly rendered - it should be the label calculated for the underlying value.
+      // check if the label is eventually properly rendered - it should be the label calculated for
+      // the underlying value.
       renderer.calcLabel(thisValueDescriptor, evaluationContext, MockitoKt.mock())
       debugProcess.managerThread.processRemaining()
       assertThat(thisValueDescriptor.valueText).isEqualTo("2")
 
       // check if the children renderer is the same as the label renderer.
       val childrenRenderer = (renderer as CompoundReferenceRenderer).childrenRenderer
-      assertThat(childrenRenderer.uniqueId).isEqualTo("androidx.compose.runtime.SnapshotMutableStateImpl")
+      assertThat(childrenRenderer.uniqueId)
+        .isEqualTo("androidx.compose.runtime.SnapshotMutableStateImpl")
     }
   }
 
   @Test
   fun renderString() {
-    val source = """
+    val source =
+      """
       package androidx.compose.runtime
 
       private class DerivedSnapshotState<T> {}
-    """.trimIndent()
-    projectRule.fixture.addFileToProject("src/androidx/compose/runtime/DerivedSnapshotState.kt", source)
+    """
+        .trimIndent()
+    projectRule.fixture.addFileToProject(
+      "src/androidx/compose/runtime/DerivedSnapshotState.kt",
+      source
+    )
 
-    val debugProcess: DebugProcessImpl = mockDebugProcess(project, projectRule.testRootDisposable) {
-      val vm = this@mockDebugProcess.virtualMachineProxy.virtualMachine
+    val debugProcess: DebugProcessImpl =
+      mockDebugProcess(project, projectRule.testRootDisposable) {
+        val vm = this@mockDebugProcess.virtualMachineProxy.virtualMachine
 
-      val stringType = classType("java.lang.String")
+        val stringType = classType("java.lang.String")
 
-      classType("androidx.compose.runtime.DerivedSnapshotState") {
-        method("getDebuggerDisplayValue") {
-          value(MockStringReference("This is fake string value.", stringType, vm))
+        classType("androidx.compose.runtime.DerivedSnapshotState") {
+          method("getDebuggerDisplayValue") {
+            value(MockStringReference("This is fake string value.", stringType, vm))
+          }
         }
       }
-    }
 
-    val thisObjectType: ReferenceType = debugProcess.virtualMachineProxy
-      .classesByName("androidx.compose.runtime.DerivedSnapshotState")
-      .first()
+    val thisObjectType: ReferenceType =
+      debugProcess.virtualMachineProxy
+        .classesByName("androidx.compose.runtime.DerivedSnapshotState")
+        .first()
 
     debugProcess.invokeOnDebuggerManagerThread {
       // check `Compose SnapshotState` is the first selected renderer by default.
-      val renderer = NodeRendererSettings.getInstance().getAllRenderers(projectRule.project)
-        .filter { it.isEnabled }
-        .first { (it as? CompoundReferenceRenderer)?.isApplicableAsync(thisObjectType)?.get() == true }
+      val renderer =
+        NodeRendererSettings.getInstance()
+          .getAllRenderers(projectRule.project)
+          .filter { it.isEnabled }
+          .first {
+            (it as? CompoundReferenceRenderer)?.isApplicableAsync(thisObjectType)?.get() == true
+          }
       assertThat(renderer.name).isEqualTo("Compose State Object")
 
-      val thisObjectValue = MockClassObjectReference(thisObjectType, debugProcess.virtualMachineProxy.virtualMachine)
+      val thisObjectValue =
+        MockClassObjectReference(thisObjectType, debugProcess.virtualMachineProxy.virtualMachine)
       val evaluationContext = mockEvaluationContext(debugProcess, thisObjectValue)
       val thisValueDescriptor = MockValueDescriptor(project, thisObjectValue)
 
-      // check if the label is eventually properly rendered - it should be the label calculated for the underlying value.
+      // check if the label is eventually properly rendered - it should be the label calculated for
+      // the underlying value.
       renderer.calcLabel(thisValueDescriptor, evaluationContext, MockitoKt.mock())
       debugProcess.managerThread.processRemaining()
       assertThat(thisValueDescriptor.valueText).isEqualTo("This is fake string value.")
 
       // check if the children renderer is the same as the label renderer.
       val childrenRenderer = (renderer as CompoundReferenceRenderer).childrenRenderer
-      assertThat(childrenRenderer.uniqueId).isEqualTo("androidx.compose.runtime.DerivedSnapshotState")
+      assertThat(childrenRenderer.uniqueId)
+        .isEqualTo("androidx.compose.runtime.DerivedSnapshotState")
     }
   }
 
   @Test
   fun checkApplicable_NoValidMethod() {
-    val source = """
+    val source =
+      """
       package androidx.compose.runtime.snapshots
 
       class SnapshotStateList<T> {}
-    """.trimIndent()
-    projectRule.fixture.addFileToProject("src/androidx/compose/runtime/snapshots/SnapshotStateList.kt", source)
+    """
+        .trimIndent()
+    projectRule.fixture.addFileToProject(
+      "src/androidx/compose/runtime/snapshots/SnapshotStateList.kt",
+      source
+    )
 
     // prepare
-    val debugProcess: DebugProcessImpl = mockDebugProcess(project, projectRule.testRootDisposable) {
-      val vm = this@mockDebugProcess.virtualMachineProxy.virtualMachine
-      classType("java.lang.Object") {
-        method("toString", "()Ljava/lang/String;")
-      }
+    val debugProcess: DebugProcessImpl =
+      mockDebugProcess(project, projectRule.testRootDisposable) {
+        val vm = this@mockDebugProcess.virtualMachineProxy.virtualMachine
+        classType("java.lang.Object") { method("toString", "()Ljava/lang/String;") }
 
-      val stringType = classType("java.lang.String")
+        val stringType = classType("java.lang.String")
 
-      classType("androidx.compose.runtime.snapshots.SnapshotStateList") {
-        // Please note: method `getDebuggerDisplayValue` is not declared.
+        classType("androidx.compose.runtime.snapshots.SnapshotStateList") {
+          // Please note: method `getDebuggerDisplayValue` is not declared.
 
-        method("toString", "()Ljava/lang/String;") {
-          value(MockStringReference("SnapshotStateList@1234", stringType, vm))
+          method("toString", "()Ljava/lang/String;") {
+            value(MockStringReference("SnapshotStateList@1234", stringType, vm))
+          }
         }
       }
-    }
 
-    val thisObjectType: ReferenceType = debugProcess.virtualMachineProxy
-      .classesByName("androidx.compose.runtime.snapshots.SnapshotStateList")
-      .first()
+    val thisObjectType: ReferenceType =
+      debugProcess.virtualMachineProxy
+        .classesByName("androidx.compose.runtime.snapshots.SnapshotStateList")
+        .first()
 
     debugProcess.invokeOnDebuggerManagerThread {
       // 1. Check if `Compose State Object` is the first selected renderer by default since
       // `getDebuggerDisplayValue` method is not found.
-      val renderer = NodeRendererSettings.getInstance().getAllRenderers(projectRule.project)
-        .filter { it.isEnabled }
-        .first { (it as? CompoundReferenceRenderer)?.isApplicableAsync(thisObjectType)?.get() == true }
+      val renderer =
+        NodeRendererSettings.getInstance()
+          .getAllRenderers(projectRule.project)
+          .filter { it.isEnabled }
+          .first {
+            (it as? CompoundReferenceRenderer)?.isApplicableAsync(thisObjectType)?.get() == true
+          }
       assertThat(renderer.name).isEqualTo("Compose State Object")
 
-      val thisObjectValue = MockClassObjectReference(thisObjectType, debugProcess.virtualMachineProxy.virtualMachine)
+      val thisObjectValue =
+        MockClassObjectReference(thisObjectType, debugProcess.virtualMachineProxy.virtualMachine)
       val evaluationContext = mockEvaluationContext(debugProcess, thisObjectValue)
       val thisValueDescriptor = MockValueDescriptor(project, thisObjectValue)
 
@@ -296,4 +350,4 @@
       assertThat(thisValueDescriptor.valueText).isEqualTo("SnapshotStateList@1234")
     }
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/render/KotlinMapEntryRendererTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/render/KotlinMapEntryRendererTest.kt
index 689508f..113af09 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/render/KotlinMapEntryRendererTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/render/KotlinMapEntryRendererTest.kt
@@ -33,8 +33,7 @@
 import org.junit.Test
 
 class KotlinMapEntryRendererTest {
-  @get:Rule
-  val projectRule = AndroidProjectRule.inMemory()
+  @get:Rule val projectRule = AndroidProjectRule.inMemory()
 
   private val project
     get() = projectRule.project
@@ -42,34 +41,39 @@
   @Test
   fun checkRenderer() {
     // prepare
-    val debugProcess: DebugProcessImpl = mockDebugProcess(project, projectRule.testRootDisposable) {
-      val vm = this@mockDebugProcess.virtualMachineProxy.virtualMachine
+    val debugProcess: DebugProcessImpl =
+      mockDebugProcess(project, projectRule.testRootDisposable) {
+        val vm = this@mockDebugProcess.virtualMachineProxy.virtualMachine
 
-      val stringType = classType("java.lang.String")
+        val stringType = classType("java.lang.String")
 
-      classType("java.util.Map\$Entry") {
-        method("getKey", "()Ljava/lang/Object;") {
-          value(MockStringReference("key1", stringType, vm))
-        }
+        classType("java.util.Map\$Entry") {
+          method("getKey", "()Ljava/lang/Object;") {
+            value(MockStringReference("key1", stringType, vm))
+          }
 
-        method("getValue", "()Ljava/lang/Object;") {
-          value(MockStringReference("value1", stringType, vm))
+          method("getValue", "()Ljava/lang/Object;") {
+            value(MockStringReference("value1", stringType, vm))
+          }
         }
       }
-    }
 
-    val thisObjectType: ReferenceType = debugProcess.virtualMachineProxy
-      .classesByName("java.util.Map\$Entry")
-      .first()
+    val thisObjectType: ReferenceType =
+      debugProcess.virtualMachineProxy.classesByName("java.util.Map\$Entry").first()
 
     debugProcess.invokeOnDebuggerManagerThread {
       // 1. check `Kotlin MapEntry` is the first selected renderer by default.
-      val renderer = NodeRendererSettings.getInstance().getAllRenderers(projectRule.project)
-        .filter { it.isEnabled }
-        .first { (it as? CompoundReferenceRenderer)?.isApplicableAsync(thisObjectType)?.get() == true }
+      val renderer =
+        NodeRendererSettings.getInstance()
+          .getAllRenderers(projectRule.project)
+          .filter { it.isEnabled }
+          .first {
+            (it as? CompoundReferenceRenderer)?.isApplicableAsync(thisObjectType)?.get() == true
+          }
       assertThat(renderer.name).isEqualTo("Kotlin MapEntry")
 
-      val thisObjectValue = MockClassObjectReference(thisObjectType, debugProcess.virtualMachineProxy.virtualMachine)
+      val thisObjectValue =
+        MockClassObjectReference(thisObjectType, debugProcess.virtualMachineProxy.virtualMachine)
       val evaluationContext = mockEvaluationContext(debugProcess, thisObjectValue)
       val thisValueDescriptor = MockValueDescriptor(project, thisObjectValue)
 
@@ -78,8 +82,9 @@
       assertThat(label).isEqualTo("key1 -> value1")
 
       // 3. check if `EnumerationChildrenRenderer` is the children renderer.
-      val childrenRenderer = (renderer as CompoundReferenceRenderer).childrenRenderer as EnumerationChildrenRenderer
+      val childrenRenderer =
+        (renderer as CompoundReferenceRenderer).childrenRenderer as EnumerationChildrenRenderer
       assertThat(childrenRenderer.children.map { it.myName }).containsExactly("key", "value")
     }
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/DebugProcessTestUtils.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/DebugProcessTestUtils.kt
index dfb4059..414c549 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/DebugProcessTestUtils.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/DebugProcessTestUtils.kt
@@ -28,8 +28,7 @@
       override fun action() {
         try {
           future.complete(f())
-        }
-        catch (t: Throwable) {
+        } catch (t: Throwable) {
           future.completeExceptionally(t)
         }
       }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockDebugProcessUtils.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockDebugProcessUtils.kt
index 711fe1e..eacca10 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockDebugProcessUtils.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockDebugProcessUtils.kt
@@ -58,7 +58,11 @@
   fun value(value: Value)
 }
 
-fun mockDebugProcess(project: Project, disposable: Disposable, block: MockDebugProcessScope.() -> Unit): MockDebugProcessImpl {
+fun mockDebugProcess(
+  project: Project,
+  disposable: Disposable,
+  block: MockDebugProcessScope.() -> Unit
+): MockDebugProcessImpl {
   val debugProcess = MockDebugProcessImpl(project)
   Disposer.register(disposable) {
     // Stop and dispose the debugger process in order to avoid leaking the project via
@@ -68,38 +72,43 @@
     debugProcess.dispose()
   }
   object : MockDebugProcessScope {
-    override val virtualMachineProxy: VirtualMachineProxyImpl
-      get() = debugProcess.virtualMachineProxy
+      override val virtualMachineProxy: VirtualMachineProxyImpl
+        get() = debugProcess.virtualMachineProxy
 
-    override fun classType(
-      signature: String,
-      superClass: ClassType?,
-      interfaces: List<InterfaceType>,
-      block: MockReferenceTypeScope.() -> Unit
-    ): ClassType {
-      val classType = debugProcess.addClassType(signature, superClass, interfaces) as MockClassType
-      object : MockReferenceTypeScope {
-        override fun method(
-          name: String,
-          signature: String?,
-          argumentTypeNames: List<String>,
-          lines: List<Int>,
-          block: MockValueScope.() -> Unit
-        ) {
-          val method = MockMethod(name, signature, argumentTypeNames, lines, classType, debugProcess)
-          classType.addMethod(method)
+      override fun classType(
+        signature: String,
+        superClass: ClassType?,
+        interfaces: List<InterfaceType>,
+        block: MockReferenceTypeScope.() -> Unit
+      ): ClassType {
+        val classType =
+          debugProcess.addClassType(signature, superClass, interfaces) as MockClassType
+        object : MockReferenceTypeScope {
+            override fun method(
+              name: String,
+              signature: String?,
+              argumentTypeNames: List<String>,
+              lines: List<Int>,
+              block: MockValueScope.() -> Unit
+            ) {
+              val method =
+                MockMethod(name, signature, argumentTypeNames, lines, classType, debugProcess)
+              classType.addMethod(method)
 
-          object : MockValueScope {
-            override fun value(value: Value) {
-              classType.setValue(value, method)
+              object : MockValueScope {
+                  override fun value(value: Value) {
+                    classType.setValue(value, method)
+                  }
+                }
+                .block()
             }
-          }.block()
-        }
-      }.block()
+          }
+          .block()
 
-      return classType
+        return classType
+      }
     }
-  }.block()
+    .block()
   return debugProcess
 }
 
@@ -108,12 +117,16 @@
   private val mockVirtualMachineProxy = MockVirtualMachineProxy(this, referencesByName)
 
   val prepareRequestPatterns = mutableListOf<String>()
-  private val mockRequestManager = object : RequestManagerImpl(this) {
-    override fun createClassPrepareRequest(requestor: ClassPrepareRequestor, pattern: String): ClassPrepareRequest? {
-      prepareRequestPatterns.add(pattern)
-      return MockitoKt.mock()
+  private val mockRequestManager =
+    object : RequestManagerImpl(this) {
+      override fun createClassPrepareRequest(
+        requestor: ClassPrepareRequestor,
+        pattern: String
+      ): ClassPrepareRequest? {
+        prepareRequestPatterns.add(pattern)
+        return MockitoKt.mock()
+      }
     }
-  }
 
   override fun getVirtualMachineProxy(): VirtualMachineProxyImpl = mockVirtualMachineProxy
   override fun getSearchScope(): GlobalSearchScope = GlobalSearchScope.allScope(project)
@@ -125,8 +138,9 @@
     method: Method,
     args: List<Value>
   ): Value {
-    val referenceType: ReferenceType = referencesByName[objRef.type().name()]
-                                       ?: error("Reference type \"${objRef.type()}\" is not available when asked.")
+    val referenceType: ReferenceType =
+      referencesByName[objRef.type().name()]
+        ?: error("Reference type \"${objRef.type()}\" is not available when asked.")
 
     return when (referenceType) {
       is ClassType -> referenceType.invokeMethod(objRef.owningThread(), method, args, 0)
@@ -149,8 +163,6 @@
     superClass: ClassType?,
     interfaces: List<InterfaceType>
   ): ClassType {
-    return MockClassType(this, name, superClass, interfaces).apply {
-      referencesByName[name] = this
-    }
+    return MockClassType(this, name, superClass, interfaces).apply { referencesByName[name] = this }
   }
 }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockEvaluationContextUtils.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockEvaluationContextUtils.kt
index 0db63e4..01461cf 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockEvaluationContextUtils.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockEvaluationContextUtils.kt
@@ -23,7 +23,10 @@
 import com.intellij.debugger.jdi.StackFrameProxyImpl
 import com.sun.jdi.ObjectReference
 
-internal fun mockEvaluationContext(debugProcess: DebugProcessImpl, objectReference: ObjectReference): EvaluationContextImpl {
+internal fun mockEvaluationContext(
+  debugProcess: DebugProcessImpl,
+  objectReference: ObjectReference
+): EvaluationContextImpl {
   val mockSuspendContext = MockitoKt.mock<SuspendContextImpl>()
   whenever(mockSuspendContext.debugProcess).thenReturn(debugProcess)
 
@@ -31,4 +34,4 @@
   whenever(mockFrameProxyImpl.thisObject()).thenReturn(objectReference)
 
   return EvaluationContextImpl(mockSuspendContext, mockFrameProxyImpl)
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockIntegerValue.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockIntegerValue.kt
index a50ec45..f5bb2bb 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockIntegerValue.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockIntegerValue.kt
@@ -21,11 +21,12 @@
 import com.sun.jdi.Type
 import com.sun.jdi.VirtualMachine
 
-class MockIntegerValue(private val value: Int, private val virtualMachine: VirtualMachine) : IntegerValue by MockitoKt.mock() {
+class MockIntegerValue(private val value: Int, private val virtualMachine: VirtualMachine) :
+  IntegerValue by MockitoKt.mock() {
   override fun toString(): String = value.toString()
   override fun virtualMachine(): VirtualMachine = virtualMachine
   override fun type(): Type = MockitoKt.mock<IntegerType>()
   override fun intValue(): Int = value
   override fun longValue(): Long = value.toLong()
   override fun value(): Int = value
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockMethod.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockMethod.kt
index 92d093e..afcce5b 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockMethod.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockMethod.kt
@@ -32,7 +32,8 @@
 ) : Method by MockitoKt.mock() {
   override fun name() = name
   override fun declaringType(): ReferenceType = declaringType
-  override fun allLineLocations(): List<Location> = lines.map { GeneratedLocation(declaringType, name, it) }
+  override fun allLineLocations(): List<Location> =
+    lines.map { GeneratedLocation(declaringType, name, it) }
   override fun argumentTypeNames(): List<String> = argumentTypeNames
   override fun signature(): String? = signature
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockObjectReference.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockObjectReference.kt
index 121bad9..2d6d1bd 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockObjectReference.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockObjectReference.kt
@@ -43,8 +43,14 @@
   override fun reflectedType(): ReferenceType = referenceType
 
   override fun toString(): String {
-    return "instance of " + referenceType().name() +
-           "(reflected class=" + reflectedType().name() + ", " + "id=" + "@fakeUniqueId" + ")"
+    return "instance of " +
+      referenceType().name() +
+      "(reflected class=" +
+      reflectedType().name() +
+      ", " +
+      "id=" +
+      "@fakeUniqueId" +
+      ")"
   }
 }
 
@@ -55,4 +61,4 @@
 ) : StringReference, MockObjectReference(referenceType, vm) {
   override fun value(): String = value
   override fun toString(): String = "\"$value\""
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockReferenceType.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockReferenceType.kt
index 21ffd7d..d1f15b6 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockReferenceType.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockReferenceType.kt
@@ -38,9 +38,8 @@
   override fun name() = name
   override fun signature(): String = "L$name;"
   override fun isPrepared(): Boolean = true
-  override fun nestedTypes(): List<ReferenceType> = debugProcess.virtualMachineProxy.allClasses().filter {
-    it.name().startsWith("${name()}\$")
-  }
+  override fun nestedTypes(): List<ReferenceType> =
+    debugProcess.virtualMachineProxy.allClasses().filter { it.name().startsWith("${name()}\$") }
 
   override fun allLineLocations(): List<Location> = methods().flatMap { it.allLineLocations() }
   override fun allMethods(): List<Method> = methods()
@@ -68,7 +67,12 @@
     methodToValue[name] = value
   }
 
-  override fun invokeMethod(thread: ThreadReference?, method: Method, arguments: List<Value>, options: Int): Value {
+  override fun invokeMethod(
+    thread: ThreadReference?,
+    method: Method,
+    arguments: List<Value>,
+    options: Int
+  ): Value {
     val name = method.name() ?: error("Name of method \"$method\" is null.")
     return methodToValue[name] ?: error("Fake value is not set for method \"$name\" when asked.")
   }
@@ -79,9 +83,14 @@
   override fun subclasses(): List<ClassType> = emptyList()
   override fun isEnum() = false
   override fun setValue(field: Field?, value: Value?) {}
-  override fun newInstance(thread: ThreadReference?, method: Method, arguments: List<Value>, options: Int): ObjectReference {
+  override fun newInstance(
+    thread: ThreadReference?,
+    method: Method,
+    arguments: List<Value>,
+    options: Int
+  ): ObjectReference {
     throw UnsupportedOperationException()
   }
 
   override fun concreteMethodByName(name: String, signature: String?): Method? = null
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockValueDescriptor.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockValueDescriptor.kt
index 0502344..e26cd52 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockValueDescriptor.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockValueDescriptor.kt
@@ -34,4 +34,4 @@
   override fun setValueLabel(label: String) {
     myValueText = label
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockVirtualMachineProxy.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockVirtualMachineProxy.kt
index ced2eee..249555a 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockVirtualMachineProxy.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/debug/utils/MockVirtualMachineProxy.kt
@@ -30,11 +30,10 @@
   override fun classesByName(s: String): List<ReferenceType> = virtualMachine.classesByName(s)
 }
 
-private class MockVirtualMachine(
-  private val referencesByName: Map<String, ReferenceType>
-) : VirtualMachine by MockitoKt.mock() {
+private class MockVirtualMachine(private val referencesByName: Map<String, ReferenceType>) :
+  VirtualMachine by MockitoKt.mock() {
   override fun name(): String = "MockDalvik"
   override fun allClasses(): List<ReferenceType> = referencesByName.values.toList()
   override fun classesByName(s: String): List<ReferenceType> = listOfNotNull(referencesByName[s])
   override fun topLevelThreadGroups(): List<ThreadGroupReference> = emptyList()
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/formatting/ComposePostFormatProcessorTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/formatting/ComposePostFormatProcessorTest.kt
index b8918a0..e49608e 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/formatting/ComposePostFormatProcessorTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/formatting/ComposePostFormatProcessorTest.kt
@@ -31,12 +31,9 @@
 import org.junit.Rule
 import org.junit.Test
 
-/**
- * Test for [ComposePostFormatProcessor].
- */
+/** Test for [ComposePostFormatProcessor]. */
 class ComposePostFormatProcessorTest {
-  @get:Rule
-  val projectRule = AndroidProjectRule.inMemory()
+  @get:Rule val projectRule = AndroidProjectRule.inMemory()
 
   private val myFixture: CodeInsightTestFixture by lazy { projectRule.fixture }
 
@@ -58,10 +55,12 @@
         fun adjust():Modifier {}
       }
     }
-    """.trimIndent()
+    """
+        .trimIndent()
     )
 
-    val settings = CodeStyle.getSettings(project).getCustomSettings(KotlinCodeStyleSettings::class.java)
+    val settings =
+      CodeStyle.getSettings(project).getCustomSettings(KotlinCodeStyleSettings::class.java)
     settings.CONTINUATION_INDENT_FOR_CHAINED_CALLS = false
   }
 
@@ -79,11 +78,13 @@
       fun HomeScreen() {
           val m = Modifier.adjust().adjust()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     WriteCommandAction.writeCommandAction(project).run<RuntimeException> {
-      CodeStyleManager.getInstance(project).reformatText(myFixture.file, listOf(myFixture.file.textRange))
+      CodeStyleManager.getInstance(project)
+        .reformatText(myFixture.file, listOf(myFixture.file.textRange))
     }
 
     myFixture.checkResult(
@@ -99,7 +100,8 @@
               .adjust()
               .adjust()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -117,11 +119,13 @@
       fun HomeScreen() {
           val m = Modifier.adjust()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     WriteCommandAction.writeCommandAction(project).run<RuntimeException> {
-      CodeStyleManager.getInstance(project).reformatText(myFixture.file, listOf(myFixture.file.textRange))
+      CodeStyleManager.getInstance(project)
+        .reformatText(myFixture.file, listOf(myFixture.file.textRange))
     }
 
     myFixture.checkResult(
@@ -135,8 +139,8 @@
       fun HomeScreen() {
           val m = Modifier.adjust()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
-
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/AddComposableToFunctionQuickFixTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/AddComposableToFunctionQuickFixTest.kt
index 672c78b..3aba4f3 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/AddComposableToFunctionQuickFixTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/AddComposableToFunctionQuickFixTest.kt
@@ -15,6 +15,7 @@
  */
 package com.android.tools.compose.intentions
 
+import com.android.tools.compose.analysis.setUpCompilerArgumentsForComposeCompilerPlugin
 import com.android.tools.idea.testing.AndroidProjectRule
 import com.android.tools.idea.testing.loadNewFile
 import com.android.tools.idea.testing.moveCaret
@@ -32,8 +33,7 @@
 
 @RunWith(JUnit4::class)
 class AddComposableToFunctionQuickFixTest {
-  @get:Rule
-  val projectRule = AndroidProjectRule.inMemory()
+  @get:Rule val projectRule = AndroidProjectRule.inMemory()
 
   private val myFixture by lazy { projectRule.fixture }
   private val myProject by lazy { projectRule.project }
@@ -41,6 +41,7 @@
   @Before
   fun setUp() {
     myFixture.stubComposableAnnotation()
+    setUpCompilerArgumentsForComposeCompilerPlugin(myProject)
   }
 
   @Test
@@ -59,7 +60,8 @@
       fun NonComposable<caret>Function() {
           ComposableFunction()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     invokeQuickFix()
@@ -77,7 +79,9 @@
       fun NonComposableFunction() {
           ComposableFunction()
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
   }
 
   @Test
@@ -96,7 +100,8 @@
       fun NonComposableFunction() {
           Composable<caret>Function()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     invokeQuickFix()
@@ -114,7 +119,9 @@
       fun NonComposableFunction() {
           ComposableFunction()
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
   }
 
   @Test
@@ -129,7 +136,8 @@
 
       @Composable
       fun ComposableFunction() {}
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.loadNewFile(
@@ -141,7 +149,8 @@
       fun NonComposable<caret>Function() {
           ComposableFunction()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     invokeQuickFix()
@@ -156,7 +165,9 @@
       fun NonComposableFunction() {
           ComposableFunction()
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
   }
 
   @Test
@@ -181,12 +192,15 @@
               ComposableFunction()  // invocation
           }
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     assertQuickFixNotAvailable("Composable|Function()  // invocation")
 
-    ApplicationManager.getApplication().invokeAndWait { myFixture.moveCaret("fun NonComposable|Function") }
+    ApplicationManager.getApplication().invokeAndWait {
+      myFixture.moveCaret("fun NonComposable|Function")
+    }
     invokeQuickFix()
 
     myFixture.checkResult(
@@ -208,7 +222,9 @@
               ComposableFunction()  // invocation
           }
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
   }
 
   @Test
@@ -231,11 +247,14 @@
               ComposableFunction()  // invocation
           }
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    // Adding @Composable to `NonComposableFunction` isn't correct here. To fix the build error, @Composable should be added to the
-    // `content` parameter of `functionThatTakesALambda`. That's currently out of scope for this quick fix (although could be added in the
+    // Adding @Composable to `NonComposableFunction` isn't correct here. To fix the build error,
+    // @Composable should be added to the
+    // `content` parameter of `functionThatTakesALambda`. That's currently out of scope for this
+    // quick fix (although could be added in the
     // future), so for now we just assert that the quick fix isn't available.
     assertQuickFixNotAvailable("fun NonComposable|Function() {")
     assertQuickFixNotAvailable("functionThatTake|sALambda {")
@@ -263,7 +282,8 @@
           }
           return MyClass()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     assertQuickFixNotAvailable("fun getMy|Class(): Any")
@@ -293,13 +313,18 @@
           }
           return MyClass()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    // The compiler reports this error on the property, even though it's the getter function that needs to have @Composable added.
-    // Furthermore, it does the same when the setter function calls a @Composable function, but that scenario can't be handled because
-    // @Composable doesn't apply to setters. It's not trivial to determine from the compiler error on the property which accessor it should
-    // apply to, so we just don't show the fix. There will be a separate error on the getter() in this case that shows the fix anyway, which
+    // The compiler reports this error on the property, even though it's the getter function that
+    // needs to have @Composable added.
+    // Furthermore, it does the same when the setter function calls a @Composable function, but that
+    // scenario can't be handled because
+    // @Composable doesn't apply to setters. It's not trivial to determine from the compiler error
+    // on the property which accessor it should
+    // apply to, so we just don't show the fix. There will be a separate error on the getter() in
+    // this case that shows the fix anyway, which
     // suffices for the user to be able to quickly fix the error.
     assertQuickFixNotAvailable("val pro|perty: String")
 
@@ -328,7 +353,9 @@
           }
           return MyClass()
       }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
   }
 
   @Test
@@ -356,7 +383,8 @@
           }
           return MyClass()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     // @Composable is not allowed on setters, so we shouldn't suggest adding it.
@@ -388,7 +416,8 @@
           }
           return MyClass()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     assertQuickFixNotAvailable("fun getMy|Class(): Any")
@@ -400,17 +429,16 @@
     val fixFilter: (IntentionAction) -> Boolean =
       if (expectedFunctionName != null) {
         { action -> action.text == "Add '@Composable' to function '$expectedFunctionName'" }
-      }
-      else {
+      } else {
         { action -> action.text.startsWith("Add '@Composable' to function '") }
       }
 
     val action = myFixture.availableIntentions.singleOrNull(fixFilter)
     if (action == null) {
-      val intentionTexts = myFixture.availableIntentions.joinToString(transform = IntentionAction::getText)
+      val intentionTexts =
+        myFixture.availableIntentions.joinToString(transform = IntentionAction::getText)
       fail("Could not find expected quick fix. Available intentions: $intentionTexts")
-    }
-    else {
+    } else {
       WriteCommandAction.runWriteCommandAction(myProject) {
         action.invoke(myProject, myFixture.editor, myFixture.file)
       }
@@ -418,7 +446,12 @@
   }
 
   private fun assertQuickFixNotAvailable(window: String) {
-    ApplicationManager.getApplication().invokeAndWait { myFixture.moveCaret (window) }
-    assertThat(myFixture.availableIntentions.filter { it.text.startsWith("Add '@Composable' to function '") }).isEmpty()
+    ApplicationManager.getApplication().invokeAndWait { myFixture.moveCaret(window) }
+    assertThat(
+        myFixture.availableIntentions.filter {
+          it.text.startsWith("Add '@Composable' to function '")
+        }
+      )
+      .isEmpty()
   }
 }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeCreatePreviewActionTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeCreatePreviewActionTest.kt
index fffa4c3..48a6c61 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeCreatePreviewActionTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeCreatePreviewActionTest.kt
@@ -24,9 +24,7 @@
 import org.jetbrains.android.compose.stubComposableAnnotation
 import org.jetbrains.android.compose.stubPreviewAnnotation
 
-/**
- * Test for [ComposeCreatePreviewAction]
- */
+/** Test for [ComposeCreatePreviewAction] */
 class ComposeCreatePreviewActionTest : JavaCodeInsightFixtureAdtTestCase() {
   override fun setUp() {
     super.setUp()
@@ -49,17 +47,22 @@
           Text("Davenport, California")
           Text("December 2018")
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     val action = myFixture.availableIntentions.find { it.text == "Create Preview" }
     assertThat(action).isNotNull()
 
-    WriteCommandAction.runWriteCommandAction(myFixture.project, Runnable {
-      // Within unit tests ListPopupImpl.showInBestPositionFor doesn't open popup and acts like fist item was selected.
-      // In our case wrap in Container will be selected.
-      action!!.invoke(myFixture.project, myFixture.editor, myFixture.file)
-    })
+    WriteCommandAction.runWriteCommandAction(
+      myFixture.project,
+      Runnable {
+        // Within unit tests ListPopupImpl.showInBestPositionFor doesn't open popup and acts like
+        // fist item was selected.
+        // In our case wrap in Container will be selected.
+        action!!.invoke(myFixture.project, myFixture.editor, myFixture.file)
+      }
+    )
 
     myFixture.checkResult(
       // language=kotlin
@@ -76,7 +79,8 @@
           Text("Davenport, California")
           Text("December 2018")
       }
-    """.trimIndent()
+    """
+        .trimIndent()
     )
   }
 
@@ -97,17 +101,22 @@
       }
 
       </selection>
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     var action = myFixture.availableIntentions.find { it.text == "Create Preview" }
     assertThat(action).isNotNull()
 
-    WriteCommandAction.runWriteCommandAction(myFixture.project, Runnable {
-      // Within unit tests ListPopupImpl.showInBestPositionFor doesn't open popup and acts like fist item was selected.
-      // In our case wrap in Container will be selected.
-      action!!.invoke(myFixture.project, myFixture.editor, myFixture.file)
-    })
+    WriteCommandAction.runWriteCommandAction(
+      myFixture.project,
+      Runnable {
+        // Within unit tests ListPopupImpl.showInBestPositionFor doesn't open popup and acts like
+        // fist item was selected.
+        // In our case wrap in Container will be selected.
+        action!!.invoke(myFixture.project, myFixture.editor, myFixture.file)
+      }
+    )
 
     myFixture.checkResult(
       // language=kotlin
@@ -126,10 +135,10 @@
       }
 
 
-    """.trimIndent()
+    """
+        .trimIndent()
     )
 
-
     myFixture.loadNewFile(
       "src/com/example/Test2.kt",
       // language=kotlin
@@ -148,17 +157,22 @@
       }
 
       </selection>
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     action = myFixture.availableIntentions.find { it.text == "Create Preview" }
     assertThat(action).isNotNull()
 
-    WriteCommandAction.runWriteCommandAction(myFixture.project, Runnable {
-      // Within unit tests ListPopupImpl.showInBestPositionFor doesn't open popup and acts like fist item was selected.
-      // In our case wrap in Container will be selected.
-      action!!.invoke(myFixture.project, myFixture.editor, myFixture.file)
-    })
+    WriteCommandAction.runWriteCommandAction(
+      myFixture.project,
+      Runnable {
+        // Within unit tests ListPopupImpl.showInBestPositionFor doesn't open popup and acts like
+        // fist item was selected.
+        // In our case wrap in Container will be selected.
+        action!!.invoke(myFixture.project, myFixture.editor, myFixture.file)
+      }
+    )
 
     myFixture.checkResult(
       // language=kotlin
@@ -178,7 +192,8 @@
       }
 
 
-    """.trimIndent()
+    """
+        .trimIndent()
     )
   }
 }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeSurroundWithWidgetActionTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeSurroundWithWidgetActionTest.kt
index 6f1c3b6..b370073 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeSurroundWithWidgetActionTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeSurroundWithWidgetActionTest.kt
@@ -24,9 +24,7 @@
 import org.jetbrains.android.JavaCodeInsightFixtureAdtTestCase
 import org.jetbrains.android.compose.stubComposableAnnotation
 
-/**
- * Test for [ComposeSurroundWithWidgetActionGroup] and [ComposeSurroundWithWidgetAction]
- */
+/** Test for [ComposeSurroundWithWidgetActionGroup] and [ComposeSurroundWithWidgetAction] */
 class ComposeSurroundWithWidgetActionTest : JavaCodeInsightFixtureAdtTestCase() {
   public override fun setUp() {
     super.setUp()
@@ -43,7 +41,8 @@
     inline fun Row(content: @Composable () -> Unit) {}
     inline fun Column(content: @Composable () -> Unit) {}
     inline fun Box(content: @Composable () -> Unit) {}
-    """.trimIndent()
+    """
+        .trimIndent()
     )
   }
 
@@ -55,7 +54,8 @@
     myFixture.loadNewFile("src/com/example/Test.kt", inputFileContent)
     val action = actionProvider()
     WriteCommandAction.runWriteCommandAction(myFixture.project) {
-      // Within unit tests ListPopupImpl.showInBestPositionFor doesn't open popup and acts like fist item was selected.
+      // Within unit tests ListPopupImpl.showInBestPositionFor doesn't open popup and acts like fist
+      // item was selected.
       // In our case wrap in Box will be selected.
       action.invoke(myFixture.project, myFixture.editor, myFixture.file)
     }
@@ -68,11 +68,15 @@
     inputFileContent: String,
     expectedResult: String
   ) {
-    invokeActionAndAssertResult({
-                                  val action = myFixture.availableIntentions.find { it.text == actionName }
-                                  assertThat(action).isNotNull()
-                                  action!!
-                                }, inputFileContent, expectedResult)
+    invokeActionAndAssertResult(
+      {
+        val action = myFixture.availableIntentions.find { it.text == actionName }
+        assertThat(action).isNotNull()
+        action!!
+      },
+      inputFileContent,
+      expectedResult
+    )
   }
 
   private fun invokeActionAndAssertResult(
@@ -102,7 +106,8 @@
 
           </selection><caret>
       }
-      """.trimIndent(),
+      """
+        .trimIndent(),
       // language=kotlin
       """
       package com.example
@@ -122,7 +127,8 @@
 
           
       }
-    """.trimIndent()
+    """
+        .trimIndent()
     )
   }
 
@@ -141,7 +147,8 @@
           Text("Davenport, California")
           Text("December 2018")
       }
-      """.trimIndent(),
+      """
+        .trimIndent(),
       // language=kotlin
       """
       package com.example
@@ -157,7 +164,9 @@
           Text("Davenport, California")
           Text("December 2018")
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
 
     invokeActionAndAssertResult(
       "Surround with widget",
@@ -173,7 +182,8 @@
           <caret>Text("Davenport, California")
           Text("December 2018")
       }
-      """.trimIndent(),
+      """
+        .trimIndent(),
       // language=kotlin
       """
       package com.example
@@ -189,7 +199,9 @@
           }
           Text("December 2018")
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
 
     invokeActionAndAssertResult(
       "Surround with widget",
@@ -205,7 +217,8 @@
           Text("Davenport, California")
           Text("December 2018")<caret>
       }
-      """.trimIndent(),
+      """
+        .trimIndent(),
       // language=kotlin
       """
       package com.example
@@ -221,7 +234,9 @@
               Text("December 2018")
           }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
 
     invokeActionAndAssertResult(
       "Surround with widget",
@@ -237,7 +252,8 @@
               Text("Davenport, California")
           }
       }
-      """.trimIndent(),
+      """
+        .trimIndent(),
       // language=kotlin
       """
       package com.example
@@ -253,16 +269,17 @@
               }
           }
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
   }
 
-  /**
-   * Checks the cases where the intention should not be available.
-   */
+  /** Checks the cases where the intention should not be available. */
   fun testSurroundWithWidgetWithoutSelectionNotAvailable() {
-    val cases = listOf(
-      // language=kotlin
-      """
+    val cases =
+      listOf(
+        // language=kotlin
+        """
       package com.example
 
       import androidx.compose.runtime.Composable
@@ -276,9 +293,10 @@
               Text("December 2018")
           }
       }
-    """.trimIndent(),
-      // language=kotlin
-      """
+    """
+          .trimIndent(),
+        // language=kotlin
+        """
     package com.example
 
     import $COMPOSABLE_ANNOTATION_FQ_NAME
@@ -292,9 +310,10 @@
             Text("December 2018")
         }
     }
-    """.trimIndent(),
-      // language=kotlin
-      """
+    """
+          .trimIndent(),
+        // language=kotlin
+        """
     package com.example
 
     import $COMPOSABLE_ANNOTATION_FQ_NAME
@@ -310,9 +329,10 @@
             Text("December 2018")
         }
     }
-    """.trimIndent(),
-      // language=kotlin
-      """
+    """
+          .trimIndent(),
+        // language=kotlin
+        """
     package com.example
 
     import $COMPOSABLE_ANNOTATION_FQ_NAME
@@ -322,8 +342,9 @@
     fun NewsStory() {<caret>
         Text("A day in Shark Fin Cove")
     }
-    """.trimIndent()
-    )
+    """
+          .trimIndent()
+      )
 
     cases.forEachIndexed { index, content ->
       myFixture.loadNewFile("src/com/example/Test${index}.kt", content)
@@ -333,8 +354,8 @@
   }
 
   /**
-   * Checks surround with widget when the selection starts and/or stops in the middle or an element and not
-   * in empty space.
+   * Checks surround with widget when the selection starts and/or stops in the middle or an element
+   * and not in empty space.
    */
   fun testSurroundWithWidgetWithPartialSelection() {
     invokeActionAndAssertResult(
@@ -351,7 +372,8 @@
           Text("Davenport, Cali</selection>fornia")
           Text("December 2018")
       }
-      """.trimIndent(),
+      """
+        .trimIndent(),
       // language=kotlin
       """
       package com.example
@@ -367,7 +389,9 @@
           }
           Text("December 2018")
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
 
     invokeActionAndAssertResult(
       "Surround with widget",
@@ -385,7 +409,8 @@
           // A comment
           </selection>
       }
-      """.trimIndent(),
+      """
+        .trimIndent(),
       // language=kotlin
       """
       package com.example
@@ -403,7 +428,9 @@
           }
           
       }
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
 
     invokeActionAndAssertResult(
       "Surround with widget",
@@ -423,7 +450,8 @@
             Text("December 2018")</selection>
         }
     }
-    """.trimIndent(),
+    """
+        .trimIndent(),
       // language=kotlin
       """
         package com.example
@@ -442,7 +470,8 @@
                 }
             }
         }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     invokeActionAndAssertResult(
@@ -464,7 +493,8 @@
             Text("December 2018")
         }</selection>
     }
-    """.trimIndent(),
+    """
+        .trimIndent(),
       // language=kotlin
       """
         package com.example
@@ -484,17 +514,17 @@
                 }
             }
         }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
-  /**
-   * Checks the cases where the intention should not be available.
-   */
+  /** Checks the cases where the intention should not be available. */
   fun testSurroundWithWidgetWithPartialSelectionNotAvailable() {
-    val cases = listOf(
-      // language=kotlin
-      """
+    val cases =
+      listOf(
+        // language=kotlin
+        """
     package com.example
 
     import $COMPOSABLE_ANNOTATION_FQ_NAME
@@ -508,9 +538,10 @@
             Text("December 2018")
         }
     }
-    """.trimIndent(),
-      // language=kotlin
-      """
+    """
+          .trimIndent(),
+        // language=kotlin
+        """
     package com.example
 
     import $COMPOSABLE_ANNOTATION_FQ_NAME
@@ -533,9 +564,10 @@
             Text("December 2018")
         }
     }
-    """.trimIndent(),
-      // language=kotlin
-      """
+    """
+          .trimIndent(),
+        // language=kotlin
+        """
     package com.example
 
     import $COMPOSABLE_ANNOTATION_FQ_NAME
@@ -560,9 +592,10 @@
         }
     }
     </selection>
-    """.trimIndent(),
-      // language=kotlin
-      """
+    """
+          .trimIndent(),
+        // language=kotlin
+        """
     package com.example
 
     import $COMPOSABLE_ANNOTATION_FQ_NAME
@@ -578,8 +611,9 @@
             Text("December 2018")
         }
     }
-    """.trimIndent()
-    )
+    """
+          .trimIndent()
+      )
 
     cases.forEachIndexed { index, content ->
       myFixture.loadNewFile("src/com/example/Test${index}.kt", content)
@@ -604,7 +638,8 @@
           Text("Davenport, California")
           Text("December 2018")</selection><caret>
       }
-      """.trimIndent(),
+      """
+        .trimIndent(),
       // language=kotlin
       """
       package com.example
@@ -620,7 +655,8 @@
               Text("December 2018")
           }
       }
-    """.trimIndent()
+    """
+        .trimIndent()
     )
   }
 
@@ -639,7 +675,8 @@
           Text("Davenport, California")
           Text("December 2018")</selection><caret>
       }
-      """.trimIndent(),
+      """
+        .trimIndent(),
       // language=kotlin
       """
       package com.example
@@ -655,7 +692,8 @@
               Text("December 2018")
           }
       }
-    """.trimIndent()
+    """
+        .trimIndent()
     )
   }
 
@@ -674,7 +712,8 @@
           Text("Davenport, California")
           Text("December 2018")</selection><caret>
       }
-      """.trimIndent(),
+      """
+        .trimIndent(),
       // language=kotlin
       """
       package com.example
@@ -690,7 +729,8 @@
               Text("December 2018")
           }
       }
-    """.trimIndent()
+    """
+        .trimIndent()
     )
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeUnresolvedFunctionFixContributorTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeUnresolvedFunctionFixContributorTest.kt
index 75c5f5a..49bbe45 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeUnresolvedFunctionFixContributorTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeUnresolvedFunctionFixContributorTest.kt
@@ -32,8 +32,7 @@
 @RunWith(JUnit4::class)
 class ComposeUnresolvedFunctionFixContributorTest {
 
-  @get:Rule
-  val projectRule = AndroidProjectRule.onDisk()
+  @get:Rule val projectRule = AndroidProjectRule.onDisk()
 
   private lateinit var myFixture: CodeInsightTestFixture
 
@@ -57,10 +56,14 @@
       fun NewsStory() {
           <caret>UnresolvedFunction()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    val action = myFixture.availableIntentions.find { it.text == "Create @Composable function 'UnresolvedFunction'" }
+    val action =
+      myFixture.availableIntentions.find {
+        it.text == "Create @Composable function 'UnresolvedFunction'"
+      }
     assertThat(action).isNotNull()
 
     WriteCommandAction.runWriteCommandAction(myFixture.project) {
@@ -68,7 +71,8 @@
     }
 
     // language=kotlin
-    val expectedText = """
+    val expectedText =
+      """
       package com.example
 
       import $COMPOSABLE_ANNOTATION_FQ_NAME
@@ -104,10 +108,14 @@
       fun NewsStory() {
           <caret>UnresolvedFunction<Int>(45, f = { 43 }, "OK".length)
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    val action = myFixture.availableIntentions.find { it.text == "Create @Composable function 'UnresolvedFunction'" }
+    val action =
+      myFixture.availableIntentions.find {
+        it.text == "Create @Composable function 'UnresolvedFunction'"
+      }
     assertThat(action).isNotNull()
 
     WriteCommandAction.runWriteCommandAction(myFixture.project) {
@@ -132,7 +140,8 @@
       fun <T0> UnresolvedFunction(x0: Int, f: () -> Int, x2: Int) {
           TODO("Not yet implemented")
       }
-    """.trimIndent()
+    """
+          .trimIndent()
       )
     } else {
       myFixture.checkResult(
@@ -152,7 +161,8 @@
           TODO("Not yet implemented")
       }
 
-    """.trimIndent()
+    """
+          .trimIndent()
       )
     }
   }
@@ -171,10 +181,14 @@
       fun NewsStory() {
           val k:Int = <caret>unresolvedFunction()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    val action = myFixture.availableIntentions.find { it.text == "Create @Composable function 'unresolvedFunction'" }
+    val action =
+      myFixture.availableIntentions.find {
+        it.text == "Create @Composable function 'unresolvedFunction'"
+      }
     assertThat(action).isNull()
   }
 
@@ -192,10 +206,14 @@
       fun NewsStory() {
           <caret>unresolvedFunction()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    val action = myFixture.availableIntentions.find { it.text == "Create @Composable function 'unresolvedFunction'" }
+    val action =
+      myFixture.availableIntentions.find {
+        it.text == "Create @Composable function 'unresolvedFunction'"
+      }
     assertThat(action).isNull()
   }
 
@@ -213,10 +231,14 @@
       fun NewsStory() {
           <caret>UnresolvedFunction {}
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
-    val action = myFixture.availableIntentions.find { it.text == "Create @Composable function 'UnresolvedFunction'" }
+    val action =
+      myFixture.availableIntentions.find {
+        it.text == "Create @Composable function 'UnresolvedFunction'"
+      }
     assertThat(action).isNotNull()
 
     WriteCommandAction.runWriteCommandAction(myFixture.project) {
@@ -241,7 +263,8 @@
       fun UnresolvedFunction(x0: () -> Unit) {
           TODO("Not yet implemented")
       }
-    """.trimIndent()
+    """
+          .trimIndent()
       )
     } else {
       myFixture.checkResult(
@@ -261,7 +284,8 @@
           TODO("Not yet implemented")
       }
 
-    """.trimIndent()
+    """
+          .trimIndent()
       )
     }
   }
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeUnwrapActionTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeUnwrapActionTest.kt
index 8f5b7e1..c4fbc8d 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeUnwrapActionTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeUnwrapActionTest.kt
@@ -15,15 +15,12 @@
  */
 package com.android.tools.compose.intentions
 
-
 import com.google.common.truth.Truth
 import com.intellij.openapi.command.WriteCommandAction
 import org.jetbrains.android.JavaCodeInsightFixtureAdtTestCase
 import org.jetbrains.android.compose.stubComposableAnnotation
 
-/**
- * Test for [ComposeUnwrapAction].
- */
+/** Test for [ComposeUnwrapAction]. */
 internal class ComposeUnwrapActionTest : JavaCodeInsightFixtureAdtTestCase() {
 
   public override fun setUp() {
@@ -41,7 +38,8 @@
     inline fun Row(content: @Composable () -> Unit) {}
     inline fun Column(content: @Composable () -> Unit) {}
     inline fun Box(content: @Composable () -> Unit) {}
-    """.trimIndent()
+    """
+        .trimIndent()
     )
   }
 
@@ -63,7 +61,8 @@
               Text("December 2018")
           }
       }
-    """.trimIndent()
+    """
+        .trimIndent()
     )
 
     val action = myFixture.availableIntentions.find { it.text == "Remove wrapper" }
@@ -87,7 +86,8 @@
           Text("Davenport, California")
           Text("December 2018")
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeWrapModifiersActionTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeWrapModifiersActionTest.kt
index 5182352..44f2cbb1 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeWrapModifiersActionTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/intentions/ComposeWrapModifiersActionTest.kt
@@ -25,9 +25,7 @@
 import org.jetbrains.kotlin.idea.KotlinFileType
 import org.jetbrains.kotlin.idea.core.formatter.KotlinCodeStyleSettings
 
-/**
- * Test for [ComposeWrapModifiersAction].
- */
+/** Test for [ComposeWrapModifiersAction]. */
 class ComposeWrapModifiersActionTest : JavaCodeInsightFixtureAdtTestCase() {
   override fun setUp() {
     super.setUp()
@@ -46,10 +44,12 @@
     }
 
     fun Modifier.extentionFunction():Modifier { return this}
-    """.trimIndent()
+    """
+        .trimIndent()
     )
 
-    val settings = CodeStyle.getSettings(project).getCustomSettings(KotlinCodeStyleSettings::class.java)
+    val settings =
+      CodeStyle.getSettings(project).getCustomSettings(KotlinCodeStyleSettings::class.java)
     settings.CONTINUATION_INDENT_FOR_CHAINED_CALLS = false
   }
 
@@ -68,7 +68,8 @@
           val m2 = Modifier.adjust().adjust()
           val m3 = Modifier.adjust().adjust()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     var action = myFixture.availableIntentions.find { it.text == "Wrap modifiers" }
@@ -92,7 +93,8 @@
           val m2 = Modifier.adjust().adjust()
           val m3 = Modifier.adjust().adjust()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.moveCaret("val m2 = Modifier.adj|ust().adjust()")
@@ -109,7 +111,6 @@
       action!!.invoke(project, myFixture.editor, myFixture.file)
     }
 
-
     myFixture.checkResult(
       """
       package com.example
@@ -129,7 +130,8 @@
               .adjust()
               .adjust()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -148,10 +150,11 @@
               .ad<caret>just()
               .adjust()
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     val action = myFixture.availableIntentions.find { it.text == "Wrap modifiers" }
     Truth.assertThat(action).isNull()
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/compose/templates/AndroidComposeTest.kt b/compose-ide-plugin/testSrc/com/android/tools/compose/templates/AndroidComposeTest.kt
index 478d207..1dcd8d6 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/compose/templates/AndroidComposeTest.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/compose/templates/AndroidComposeTest.kt
@@ -36,7 +36,8 @@
     class Row
     class Column
     class Box
-    """.trimIndent()
+    """
+        .trimIndent()
     )
     LiveTemplateCompletionContributor.setShowTemplatesInTests(true, myFixture.testRootDisposable)
     TemplateManagerImpl.setTemplateTesting(myFixture.testRootDisposable)
@@ -55,7 +56,8 @@
       fun NewsStory() {
           W<caret>
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     myFixture.type("\t")
@@ -73,7 +75,8 @@
               
           }
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -92,7 +95,8 @@
           Text("Davenport, California")
           Text("December 2018")</selection><caret>
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     val template = TemplateSettings.getInstance().getTemplate("WR", "AndroidCompose")
@@ -113,7 +117,8 @@
               Text("December 2018")
           }
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -132,7 +137,8 @@
           Text("Davenport, California")
           Text("December 2018")</selection><caret>
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     val template = TemplateSettings.getInstance().getTemplate("WC", "AndroidCompose")
@@ -153,7 +159,8 @@
               Text("December 2018")
           }
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -173,7 +180,8 @@
             "A day in Shark Fin Cove")
           Text("Davenport, California")
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     val template = TemplateSettings.getInstance().getTemplate("paddp", "AndroidCompose")
@@ -193,7 +201,8 @@
             "A day in Shark Fin Cove")
           Text("Davenport, California")
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
 
@@ -213,7 +222,8 @@
             "A day in Shark Fin Cove")
           Text("Davenport, California")
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
 
     val template = TemplateSettings.getInstance().getTemplate("weight", "AndroidCompose")
@@ -233,7 +243,8 @@
             "A day in Shark Fin Cove")
           Text("Davenport, California")
       }
-      """.trimIndent()
+      """
+        .trimIndent()
     )
   }
-}
\ No newline at end of file
+}
diff --git a/compose-ide-plugin/testSrc/com/android/tools/tests/ComposeTestSuite.kt b/compose-ide-plugin/testSrc/com/android/tools/tests/ComposeTestSuite.kt
index ef59597..90706c8 100644
--- a/compose-ide-plugin/testSrc/com/android/tools/tests/ComposeTestSuite.kt
+++ b/compose-ide-plugin/testSrc/com/android/tools/tests/ComposeTestSuite.kt
@@ -23,8 +23,12 @@
   companion object {
     init {
       unzipIntoOfflineMavenRepo("tools/base/build-system/android_gradle_plugin.zip")
-      linkIntoOfflineMavenRepo("tools/base/build-system/android_gradle_plugin_runtime_dependencies.manifest")
-      linkIntoOfflineMavenRepo("tools/base/build-system/integration-test/kotlin_gradle_plugin_prebuilts.manifest")
+      linkIntoOfflineMavenRepo(
+        "tools/base/build-system/android_gradle_plugin_runtime_dependencies.manifest"
+      )
+      linkIntoOfflineMavenRepo(
+        "tools/base/build-system/integration-test/kotlin_gradle_plugin_prebuilts.manifest"
+      )
     }
   }
-}
\ No newline at end of file
+}
diff --git a/connection-assistant/src/com/android/tools/idea/connection/assistant/OpenConnectionAssistantSidePanelAction.java b/connection-assistant/src/com/android/tools/idea/connection/assistant/OpenConnectionAssistantSidePanelAction.java
index 05662e0..21cd7b1 100644
--- a/connection-assistant/src/com/android/tools/idea/connection/assistant/OpenConnectionAssistantSidePanelAction.java
+++ b/connection-assistant/src/com/android/tools/idea/connection/assistant/OpenConnectionAssistantSidePanelAction.java
@@ -19,6 +19,7 @@
 import com.android.tools.idea.assistant.OpenAssistSidePanelAction;
 import com.google.wireless.android.sdk.stats.AndroidStudioEvent;
 import com.google.wireless.android.sdk.stats.ConnectionAssistantEvent;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import org.jetbrains.annotations.NotNull;
 
@@ -29,6 +30,11 @@
   }
 
   @Override
+  public @NotNull ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
+  @Override
   public void actionPerformed(@NotNull AnActionEvent event) {
     super.actionPerformed(event);
 
diff --git a/databinding/src/com/android/tools/idea/databinding/analytics/LayoutBindingTracker.kt b/databinding/src/com/android/tools/idea/databinding/analytics/LayoutBindingTracker.kt
index f0ce57d..cd6cd81 100644
--- a/databinding/src/com/android/tools/idea/databinding/analytics/LayoutBindingTracker.kt
+++ b/databinding/src/com/android/tools/idea/databinding/analytics/LayoutBindingTracker.kt
@@ -95,7 +95,6 @@
 
         FileTypeIndex
           .getFiles(XmlFileType.INSTANCE, GlobalSearchScope.projectScope(project))
-          .filter { BindingXmlIndex.acceptsFile(it) }
           .mapNotNull { BindingXmlIndex.getDataForFile(project, it) }
           .forEach { layoutInfo ->
             if (layoutInfo.layoutType == DATA_BINDING_LAYOUT) {
diff --git a/databinding/testData/projects/projectWithSamePackageModules/lib1/src/main/res/layout/activity_lib.xml b/databinding/testData/projects/projectWithSamePackageModules/lib1/src/main/res/layout/activity_lib.xml
index dc8b103..c4e7ac8 100644
--- a/databinding/testData/projects/projectWithSamePackageModules/lib1/src/main/res/layout/activity_lib.xml
+++ b/databinding/testData/projects/projectWithSamePackageModules/lib1/src/main/res/layout/activity_lib.xml
@@ -1,2 +1,2 @@
 <?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout />
\ No newline at end of file
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" />
\ No newline at end of file
diff --git a/databinding/testData/projects/projectWithSamePackageModules/lib2/src/main/res/layout/activity_lib.xml b/databinding/testData/projects/projectWithSamePackageModules/lib2/src/main/res/layout/activity_lib.xml
index dc8b103..c4e7ac8 100644
--- a/databinding/testData/projects/projectWithSamePackageModules/lib2/src/main/res/layout/activity_lib.xml
+++ b/databinding/testData/projects/projectWithSamePackageModules/lib2/src/main/res/layout/activity_lib.xml
@@ -1,2 +1,2 @@
 <?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout />
\ No newline at end of file
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" />
\ No newline at end of file
diff --git a/databinding/testSrc/com/android/tools/idea/databinding/DataBindingNavigationTests.kt b/databinding/testSrc/com/android/tools/idea/databinding/DataBindingNavigationTests.kt
index d11a3b2..857b067 100644
--- a/databinding/testSrc/com/android/tools/idea/databinding/DataBindingNavigationTests.kt
+++ b/databinding/testSrc/com/android/tools/idea/databinding/DataBindingNavigationTests.kt
@@ -150,7 +150,7 @@
       // language=XML
       """
       <?xml version="1.0" encoding="utf-8"?>
-      <layout>
+      <layout xmlns:android="http://schemas.android.com/apk/res/android">
         <data>
           <import type='java.util.Map' alias='MyMap'/>
           <variable name='sample' type='MyMap.En${caret}try'/>
@@ -169,7 +169,7 @@
       // language=XML
       """
       <?xml version="1.0" encoding="utf-8"?>
-      <layout>
+      <layout xmlns:android="http://schemas.android.com/apk/res/android">
         <data>
           <import type='java.util.M${caret}ap' />
         </data>
@@ -187,7 +187,7 @@
       // language=XML
       """
       <?xml version="1.0" encoding="utf-8"?>
-      <layout>
+      <layout xmlns:android="http://schemas.android.com/apk/res/android">
         <data>
           <variable name='sample' type='Int${caret}eger'/>
         </data>
@@ -212,7 +212,7 @@
       // language=XML
       """
       <?xml version="1.0" encoding="utf-8"?>
-      <layout>
+      <layout xmlns:android="http://schemas.android.com/apk/res/android">
         <data>
           <variable name='sample' type='a.b.c.Samp${caret}le'/>
         </data>
diff --git a/databinding/testSrc/com/android/tools/idea/databinding/viewbinding/LightViewBindingClassTest.kt b/databinding/testSrc/com/android/tools/idea/databinding/viewbinding/LightViewBindingClassTest.kt
index d02118a..42d8db5 100644
--- a/databinding/testSrc/com/android/tools/idea/databinding/viewbinding/LightViewBindingClassTest.kt
+++ b/databinding/testSrc/com/android/tools/idea/databinding/viewbinding/LightViewBindingClassTest.kt
@@ -19,7 +19,6 @@
 import com.android.tools.idea.databinding.DataBindingMode
 import com.android.tools.idea.databinding.module.LayoutBindingModuleCache
 import com.android.tools.idea.databinding.psiclass.LightBindingClass
-import com.android.tools.idea.databinding.util.isViewBindingEnabled
 import com.android.tools.idea.databinding.utils.assertExpected
 import com.android.tools.idea.gradle.model.impl.IdeViewBindingOptionsImpl
 import com.android.tools.idea.testing.AndroidProjectBuilder
@@ -34,7 +33,6 @@
 import com.intellij.testFramework.RunsInEdt
 import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
 import org.jetbrains.android.facet.AndroidFacet
-import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.rules.RuleChain
@@ -351,7 +349,7 @@
   fun methodsAreAnnotatedNonNullAndNullableCorrectly_regularLayouts() {
     fixture.addFileToProject("src/main/res/layout/activity_main.xml", """
       <?xml version="1.0" encoding="utf-8"?>
-      <LinearLayout />
+      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" />
     """.trimIndent())
 
     val project = fixture.project
@@ -386,7 +384,7 @@
   fun methodsAreAnnotatedNonNullAndNullableCorrectly_mergeLayouts() {
     fixture.addFileToProject("src/main/res/layout/activity_main.xml", """
       <?xml version="1.0" encoding="utf-8"?>
-      <merge />
+      <merge xmlns:android="http://schemas.android.com/apk/res/android" />
     """.trimIndent())
 
     val project = fixture.project
diff --git a/deploy/src/com/android/tools/idea/run/ui/DeployAction.java b/deploy/src/com/android/tools/idea/run/ui/DeployAction.java
index 8da8079..0c7a9af 100644
--- a/deploy/src/com/android/tools/idea/run/ui/DeployAction.java
+++ b/deploy/src/com/android/tools/idea/run/ui/DeployAction.java
@@ -29,6 +29,7 @@
 import com.intellij.execution.configurations.RunConfiguration;
 import com.intellij.execution.runners.ExecutionEnvironment;
 import com.intellij.execution.runners.ExecutionEnvironmentBuilder;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.DataContext;
@@ -51,6 +52,12 @@
     myEnabledDescription = description;
   }
 
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
   @Override
   public void update(@NotNull AnActionEvent e) {
     Presentation presentation = e.getPresentation();
diff --git a/designer/lint_baseline.xml b/designer/lint_baseline.xml
index 364f27c..6e8b8c7 100644
--- a/designer/lint_baseline.xml
+++ b/designer/lint_baseline.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 8.2.0-dev">
+<issues format="5" by="lint 8.3.0-dev">
 
     <issue
         id="DefaultLocale"
@@ -30,7 +30,7 @@
         message="Avoid `by lazy` for simple lazy initialization">
         <location
             file="src/com/android/tools/idea/common/scene/target/CommonDragTarget.kt"
-            line="304"/>
+            line="302"/>
     </issue>
 
     <issue
@@ -38,7 +38,7 @@
         message="Avoid `by lazy` for simple lazy initialization">
         <location
             file="src/com/android/tools/idea/common/scene/target/CommonDragTarget.kt"
-            line="305"/>
+            line="303"/>
     </issue>
 
     <issue
@@ -118,7 +118,7 @@
         message="Avoid `by lazy` for simple lazy initialization">
         <location
             file="src/com/android/tools/idea/uibuilder/visual/VisualizationToolWindowFactory.kt"
-            line="171"/>
+            line="173"/>
     </issue>
 
     <issue
@@ -398,7 +398,7 @@
         message="Do not store `JBUI.scale` scaled results in fields; this will not work correctly on dynamic theme or font size changes">
         <location
             file="src/com/android/tools/idea/uibuilder/handlers/constraint/WidgetConstraintPanel.java"
-            line="277"/>
+            line="282"/>
     </issue>
 
     <issue
@@ -406,7 +406,7 @@
         message="Do not store `JBUI.scale` scaled results in fields; this will not work correctly on dynamic theme or font size changes">
         <location
             file="src/com/android/tools/idea/uibuilder/handlers/constraint/WidgetConstraintPanel.java"
-            line="278"/>
+            line="283"/>
     </issue>
 
     <issue
@@ -414,7 +414,15 @@
         message="Do not store `JBUI.scale` scaled results in fields; this will not work correctly on dynamic theme or font size changes">
         <location
             file="src/com/android/tools/idea/uibuilder/handlers/constraint/WidgetConstraintPanel.java"
-            line="279"/>
+            line="284"/>
+    </issue>
+
+    <issue
+        id="VisibleForTests"
+        message="This class should only be accessed from tests or within private scope">
+        <location
+            file="src/com/android/tools/idea/common/analytics/CommonUsageTracker.kt"
+            line="84"/>
     </issue>
 
     <issue
@@ -422,7 +430,7 @@
         message="This method should only be accessed from tests or within package private scope">
         <location
             file="src/com/android/tools/idea/uibuilder/editor/DesignFilesPreviewEditor.kt"
-            line="109"/>
+            line="108"/>
     </issue>
 
     <issue
@@ -430,7 +438,7 @@
         message="This method should only be accessed from tests or within package private scope">
         <location
             file="src/com/android/tools/idea/uibuilder/editor/DesignFilesPreviewEditor.kt"
-            line="109"/>
+            line="108"/>
     </issue>
 
     <issue
@@ -438,7 +446,7 @@
         message="This method should only be accessed from tests or within package private scope">
         <location
             file="src/com/android/tools/idea/uibuilder/editor/DesignFilesPreviewEditor.kt"
-            line="112"/>
+            line="111"/>
     </issue>
 
     <issue
@@ -446,7 +454,7 @@
         message="This method should only be accessed from tests or within package private scope">
         <location
             file="src/com/android/tools/idea/uibuilder/editor/DesignFilesPreviewEditor.kt"
-            line="112"/>
+            line="111"/>
     </issue>
 
     <issue
@@ -454,7 +462,7 @@
         message="This method should only be accessed from tests or within protected scope">
         <location
             file="src/com/android/tools/idea/common/surface/notifications/DesignSurfaceNotificationProvider.kt"
-            line="40"/>
+            line="39"/>
     </issue>
 
     <issue
@@ -462,7 +470,7 @@
         message="This method should only be accessed from tests or within protected scope">
         <location
             file="src/com/android/tools/idea/common/surface/notifications/DesignSurfaceNotificationProvider.kt"
-            line="40"/>
+            line="39"/>
     </issue>
 
     <issue
@@ -526,7 +534,7 @@
         message="This method should only be accessed from tests or within protected scope">
         <location
             file="src/com/android/tools/idea/uibuilder/surface/NlDesignSurface.java"
-            line="724"/>
+            line="725"/>
     </issue>
 
     <issue
@@ -550,7 +558,7 @@
         message="This method should only be accessed from tests or within protected scope">
         <location
             file="src/com/android/tools/idea/uibuilder/visual/VisualizationForm.kt"
-            line="613"/>
+            line="580"/>
     </issue>
 
     <issue
@@ -558,7 +566,7 @@
         message="This method should only be accessed from tests or within protected scope">
         <location
             file="src/com/android/tools/idea/uibuilder/visual/VisualizationForm.kt"
-            line="613"/>
+            line="580"/>
     </issue>
 
     <issue
diff --git a/designer/resources/layout_editor_help_assistance_bundle.xml b/designer/resources/layout_editor_help_assistance_bundle.xml
index fc51ec2..41a37cc 100644
--- a/designer/resources/layout_editor_help_assistance_bundle.xml
+++ b/designer/resources/layout_editor_help_assistance_bundle.xml
@@ -114,23 +114,23 @@
           </td>
           <td>Ctrl –
           </td>
-          <td>Command–
+          <td>Command –
           </td>
         </tr>
         <tr>
           <td>Zoom to 100%
           </td>
-          <td>Ctrl /
+          <td>Ctrl .
           </td>
-          <td>Command /
+          <td>Command .
           </td>
         </tr>
         <tr>
           <td>Zoom to fit
           </td>
-          <td>Ctrl 0
+          <td>Ctrl /
           </td>
-          <td>Command 0
+          <td>Command /
           </td>
         </tr>
         <tr>
@@ -228,17 +228,17 @@
         <tr>
           <td>Zoom to 100%
           </td>
-          <td>Ctrl /
+          <td>Ctrl .
           </td>
-          <td>Command /
+          <td>Command .
           </td>
         </tr>
         <tr>
           <td>Zoom to fit
           </td>
-          <td>Ctrl 0
+          <td>Ctrl /
           </td>
-          <td>Command 0
+          <td>Command /
           </td>
         </tr>
         <tr>
diff --git a/designer/src/com/android/tools/idea/common/actions/RestoreDefaultWindowLayoutAction.java b/designer/src/com/android/tools/idea/common/actions/RestoreDefaultWindowLayoutAction.java
index 63f2b21..f8e2a44 100644
--- a/designer/src/com/android/tools/idea/common/actions/RestoreDefaultWindowLayoutAction.java
+++ b/designer/src/com/android/tools/idea/common/actions/RestoreDefaultWindowLayoutAction.java
@@ -18,6 +18,7 @@
 import com.android.tools.adtui.workbench.DetachedToolWindowManager;
 import com.android.tools.adtui.workbench.WorkBenchManager;
 import com.intellij.ide.actions.RestoreDefaultLayoutAction;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.project.DumbAware;
@@ -50,6 +51,12 @@
     floatingToolWindowManager.restoreDefaultLayout();
   }
 
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
   @Override
   public void update(@NotNull AnActionEvent event){
     myDelegate.update(event);
diff --git a/designer/src/com/android/tools/idea/common/actions/StoreDefaultWindowLayoutAction.java b/designer/src/com/android/tools/idea/common/actions/StoreDefaultWindowLayoutAction.java
index 746a2c6..caf69b8 100644
--- a/designer/src/com/android/tools/idea/common/actions/StoreDefaultWindowLayoutAction.java
+++ b/designer/src/com/android/tools/idea/common/actions/StoreDefaultWindowLayoutAction.java
@@ -17,6 +17,7 @@
 
 import com.android.tools.adtui.workbench.WorkBenchManager;
 import com.intellij.ide.actions.StoreDefaultLayoutAction;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.project.DumbAware;
@@ -41,6 +42,12 @@
     workBenchManager.storeDefaultLayout();
   }
 
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
   @Override
   public void update(@NotNull AnActionEvent event){
     myDelegate.update(event);
diff --git a/designer/src/com/android/tools/idea/common/editor/ActionManager.java b/designer/src/com/android/tools/idea/common/editor/ActionManager.java
index 3c5e17d..b47a6f2 100644
--- a/designer/src/com/android/tools/idea/common/editor/ActionManager.java
+++ b/designer/src/com/android/tools/idea/common/editor/ActionManager.java
@@ -18,6 +18,8 @@
 import com.android.tools.adtui.stdui.KeyBindingKt;
 import com.android.tools.idea.common.model.NlComponent;
 import com.android.tools.idea.common.surface.DesignSurface;
+import com.android.tools.idea.common.surface.LabelPanel;
+import com.android.tools.idea.common.surface.LayoutData;
 import com.android.tools.idea.common.surface.SceneView;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.DefaultActionGroup;
@@ -127,6 +129,14 @@
   }
 
   /**
+   * Creates a {@link LabelPanel} with a label for a {@link SceneView}.
+   */
+  @NotNull
+  public LabelPanel createSceneViewLabel(@NotNull SceneView sceneView) {
+    return new LabelPanel(LayoutData.Companion.fromSceneView(sceneView));
+  }
+
+  /**
    * Returns the bottom bar for a {@link SceneView}. This is similar to {@link #getSceneViewContextToolbar(SceneView)} but this bar is at
    * the bottom of the {@link SceneView} while context toolbar is at the top.
    */
diff --git a/designer/src/com/android/tools/idea/common/error/CopyIssueDescriptionAction.kt b/designer/src/com/android/tools/idea/common/error/CopyIssueDescriptionAction.kt
index a27b87d..069decd 100644
--- a/designer/src/com/android/tools/idea/common/error/CopyIssueDescriptionAction.kt
+++ b/designer/src/com/android/tools/idea/common/error/CopyIssueDescriptionAction.kt
@@ -15,6 +15,7 @@
  */
 package com.android.tools.idea.common.error
 
+import com.intellij.openapi.actionSystem.ActionUpdateThread
 import com.intellij.openapi.actionSystem.AnActionEvent
 import com.intellij.openapi.actionSystem.PlatformCoreDataKeys
 import com.intellij.openapi.ide.CopyPasteManager
@@ -28,6 +29,8 @@
     event.presentation.isEnabledAndVisible = description != null
   }
 
+  override fun getActionUpdateThread() = ActionUpdateThread.EDT
+
   override fun actionPerformed(event: AnActionEvent) {
     val description = getSelectedNode(event)?.getDescription() ?: return
     CopyPasteManager.getInstance().setContents(StringSelection(description))
diff --git a/designer/src/com/android/tools/idea/common/error/DesignerCommonIssuePanel.kt b/designer/src/com/android/tools/idea/common/error/DesignerCommonIssuePanel.kt
index 1d76e5e..87ef985 100644
--- a/designer/src/com/android/tools/idea/common/error/DesignerCommonIssuePanel.kt
+++ b/designer/src/com/android/tools/idea/common/error/DesignerCommonIssuePanel.kt
@@ -63,14 +63,20 @@
 private const val POPUP_HANDLER_ACTION_ID = "Android.Designer.IssuePanel.TreePopup"
 private val KEY_DETAIL_VISIBLE = DesignerCommonIssuePanel::class.java.name + "_detail_visibility"
 
-/** The issue panel to load the issues from Layout Editor and Layout Validation Tool. */
+/**
+ * The issue panel to load the issues from Layout Editor and Layout Validation Tool.
+ *
+ * @param additionalDataProvider A [DataProvider] used to pass information from the creator of this
+ *   panel, that will allow to link the panel with the previews from which it displays the errors.
+ */
 class DesignerCommonIssuePanel(
   parentDisposable: Disposable,
   private val project: Project,
   private val treeModel: DesignerCommonIssueModel,
   nodeFactoryProvider: () -> NodeFactory,
   val issueProvider: DesignerCommonIssueProvider<Any>,
-  private val emptyMessageProvider: () -> String
+  private val emptyMessageProvider: () -> String,
+  private val additionalDataProvider: DataProvider? = null
 ) : Disposable {
 
   var sidePanelVisible =
@@ -90,7 +96,7 @@
         }
 
       override fun getData(dataId: String): Any? {
-        val node = getSelectedNode() ?: return null
+        val node = getSelectedNode() ?: return additionalDataProvider?.getData(dataId)
         if (PlatformCoreDataKeys.BGT_DATA_PROVIDER.`is`(dataId)) {
           return DataProvider { getDataInBackground(it, node) }
         }
@@ -109,7 +115,7 @@
             else -> emptyList()
           }
         }
-        return null
+        return additionalDataProvider?.getData(dataId)
       }
     }
 
diff --git a/designer/src/com/android/tools/idea/common/error/IssuePanelService.kt b/designer/src/com/android/tools/idea/common/error/IssuePanelService.kt
index 427eac4..0537924 100644
--- a/designer/src/com/android/tools/idea/common/error/IssuePanelService.kt
+++ b/designer/src/com/android/tools/idea/common/error/IssuePanelService.kt
@@ -35,6 +35,7 @@
 import com.intellij.ide.DataManager
 import com.intellij.openapi.Disposable
 import com.intellij.openapi.actionSystem.DataKey
+import com.intellij.openapi.actionSystem.DataProvider
 import com.intellij.openapi.application.ApplicationManager
 import com.intellij.openapi.application.runInEdt
 import com.intellij.openapi.components.Service
@@ -547,7 +548,9 @@
     parentDisposable: Disposable,
     name: String,
     displayName: String,
-    surface: NlDesignSurface
+    surface: NlDesignSurface,
+    postIssueUpdateListener: () -> Unit,
+    additionalDataProvider: DataProvider
   ) {
     val contentManager =
       ToolWindowManager.getInstance(project).getToolWindow(ProblemsView.ID)?.contentManager
@@ -555,16 +558,19 @@
 
     var uiCheckIssuePanel = nameToTabMap[name]?.first
     if (uiCheckIssuePanel == null) {
+      val issueProvider =
+        DesignToolsIssueProvider(parentDisposable, project, NotSuppressedFilter, name)
       uiCheckIssuePanel =
         DesignerCommonIssuePanel(
           parentDisposable,
           project,
           DesignerCommonIssuePanelModelProvider.getInstance(project).createModel(),
           { UICheckNodeFactory },
-          DesignToolsIssueProvider(parentDisposable, project, NotSuppressedFilter, name)
-        ) {
-          "UI Check did not find any issues to report"
-        }
+          issueProvider,
+          { "UI Check did not find any issues to report" },
+          additionalDataProvider
+        )
+      issueProvider.registerUpdateListener(postIssueUpdateListener)
 
       val tab =
         contentManager.factory
@@ -659,7 +665,7 @@
  * @param show whether to show or hide the issue panel.
  * @param runnable optional task to execute after the visibility of issue panel is changed.
  *
- * TODO(b/298229332): Revisit this function to see if we can remove the DesignSurface dependency.
+ * TODO(b/300646581): Revisit this function to see if we can remove the DesignSurface dependency.
  */
 fun DesignSurface<*>.setIssuePanelVisibility(show: Boolean, runnable: Runnable? = null) {
   analyticsManager.trackShowIssuePanel()
diff --git a/designer/src/com/android/tools/idea/common/surface/InteractiveLabelPanel.kt b/designer/src/com/android/tools/idea/common/surface/InteractiveLabelPanel.kt
new file mode 100644
index 0000000..bb5e01f
--- /dev/null
+++ b/designer/src/com/android/tools/idea/common/surface/InteractiveLabelPanel.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.common.surface
+
+import com.android.tools.idea.concurrency.AndroidCoroutineScope
+import com.intellij.openapi.Disposable
+import com.intellij.ui.JBColor
+import java.awt.event.MouseAdapter
+import java.awt.event.MouseEvent
+import kotlinx.coroutines.launch
+
+/** This label displays the [SceneView] model label. */
+class InteractiveLabelPanel(
+  layoutData: LayoutData,
+  disposable: Disposable,
+  private val onLabelClicked: (suspend () -> Boolean)
+) : LabelPanel(layoutData) {
+
+  private val scope = AndroidCoroutineScope(disposable)
+
+  init {
+    addMouseListener(
+      object : MouseAdapter() {
+        override fun mouseEntered(e: MouseEvent?) {
+          foreground = labelHoverColor
+        }
+
+        override fun mouseExited(e: MouseEvent?) {
+          foreground = labelDefaultColor
+        }
+
+        override fun mouseClicked(e: MouseEvent?) {
+          scope.launch { onLabelClicked() }
+        }
+      },
+    )
+  }
+
+  companion object {
+    val labelHoverColor = JBColor(0x5a5d6b, 0xf0f1f2)
+  }
+}
diff --git a/designer/src/com/android/tools/idea/common/surface/LabelPanel.kt b/designer/src/com/android/tools/idea/common/surface/LabelPanel.kt
new file mode 100644
index 0000000..c920fb0
--- /dev/null
+++ b/designer/src/com/android/tools/idea/common/surface/LabelPanel.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.common.surface
+
+import com.intellij.ui.JBColor
+import com.intellij.ui.components.JBLabel
+import java.awt.Dimension
+
+/** This label displays the [SceneView] model label. */
+open class LabelPanel(var layoutData: LayoutData) : JBLabel() {
+  init {
+    maximumSize = Dimension(Int.MAX_VALUE, Int.MAX_VALUE)
+    foreground = labelDefaultColor
+  }
+
+  final override fun doLayout() {
+    super.doLayout()
+    // If there is a model name, we manually assign the content of the modelNameLabel and position
+    // it here.
+    // Once this panel gets more functionality, we will need the use of a layout manager. For now,
+    // we just lay out the component manually.
+    if (layoutData.modelName == null) {
+      text = ""
+      toolTipText = ""
+      isVisible = false
+    } else {
+      text = layoutData.modelName
+      // Use modelName for tooltip if none has been specified.
+      toolTipText = layoutData.modelTooltip ?: layoutData.modelName
+      isVisible = true
+    }
+  }
+
+  companion object {
+    val labelDefaultColor = JBColor(0x6c707e, 0xdfe1e5)
+  }
+}
diff --git a/designer/src/com/android/tools/idea/common/surface/SceneViewPanel.kt b/designer/src/com/android/tools/idea/common/surface/SceneViewPanel.kt
index a1b370d..c142b29 100644
--- a/designer/src/com/android/tools/idea/common/surface/SceneViewPanel.kt
+++ b/designer/src/com/android/tools/idea/common/surface/SceneViewPanel.kt
@@ -85,9 +85,6 @@
     invalidate()
   }
 
-  /** Invoked when label in [SceneViewPeerPanel] is clicked. */
-  var onLabelClicked: (suspend (SceneView, Boolean) -> Boolean) = { _, _ -> true }
-
   @UiThread
   private fun revalidateSceneViews() {
     // Check if the SceneViews are still valid
@@ -112,17 +109,18 @@
         if (shouldRenderErrorsPanel()) SceneViewErrorsPanel { sceneView.hasRenderErrors() }
         else null
 
+      val labelPanel = actionManagerProvider().createSceneViewLabel(sceneView)
+
       add(
         SceneViewPeerPanel(
             sceneView,
-            disposable,
+            labelPanel,
             statusIcon,
             toolbar,
             bottomBar,
             leftBar,
             rightBar,
             errorsPanel,
-            onLabelClicked
           )
           .also { it.alignmentX = sceneViewAlignment }
       )
diff --git a/designer/src/com/android/tools/idea/common/surface/SceneViewPeerPanel.kt b/designer/src/com/android/tools/idea/common/surface/SceneViewPeerPanel.kt
index e003464..df7ce35 100644
--- a/designer/src/com/android/tools/idea/common/surface/SceneViewPeerPanel.kt
+++ b/designer/src/com/android/tools/idea/common/surface/SceneViewPeerPanel.kt
@@ -17,7 +17,6 @@
 
 import com.android.tools.adtui.common.SwingCoordinate
 import com.android.tools.idea.common.model.scaleBy
-import com.android.tools.idea.concurrency.AndroidCoroutineScope
 import com.android.tools.idea.uibuilder.scene.hasRenderErrors
 import com.android.tools.idea.uibuilder.surface.layout.PositionableContent
 import com.android.tools.idea.uibuilder.surface.layout.getScaledContentSize
@@ -25,9 +24,6 @@
 import com.android.tools.idea.uibuilder.surface.layout.margin
 import com.android.tools.idea.uibuilder.surface.layout.scaledContentSize
 import com.google.common.annotations.VisibleForTesting
-import com.intellij.openapi.Disposable
-import com.intellij.ui.JBColor
-import com.intellij.ui.components.JBLabel
 import com.intellij.util.ui.JBUI
 import com.intellij.util.ui.UIUtil
 import java.awt.BorderLayout
@@ -39,7 +35,6 @@
 import javax.swing.JComponent
 import javax.swing.JPanel
 import javax.swing.SwingUtilities
-import kotlinx.coroutines.launch
 
 /** Distance between the bottom bound of model name and top bound of SceneView. */
 @SwingCoordinate private const val TOP_BAR_BOTTOM_MARGIN = 3
@@ -53,8 +48,7 @@
 /** Minimum allowed width for the model name label. */
 @SwingCoordinate private const val MODEL_NAME_LABEL_MIN_WIDTH = 20
 
-private data class LayoutData
-private constructor(
+data class LayoutData(
   val scale: Double,
   val modelName: String?,
   val modelTooltip: String?,
@@ -89,9 +83,6 @@
   }
 }
 
-private val nameLabelDefaultColor = JBColor(0x6c707e, 0xdfe1e5)
-private val nameLabelHoverColor = JBColor(0x5a5d6b, 0xf0f1f2)
-
 /**
  * A Swing component associated to the given [SceneView]. There will be one of this components in
  * the [DesignSurface] per every [SceneView] available. This panel will be positioned on the
@@ -99,18 +90,15 @@
  */
 class SceneViewPeerPanel(
   val sceneView: SceneView,
-  disposable: Disposable,
+  private val labelPanel: LabelPanel,
   private val sceneViewStatusIcon: JComponent?,
   private val sceneViewToolbar: JComponent?,
   private val sceneViewBottomBar: JComponent?,
   private val sceneViewLeftBar: JComponent?,
   private val sceneViewRightBar: JComponent?,
   private val sceneViewErrorsPanel: JComponent?,
-  private val onLabelClicked: (suspend (SceneView, Boolean) -> Boolean)
 ) : JPanel() {
 
-  private val scope = AndroidCoroutineScope(disposable)
-
   /**
    * Contains cached layout data that can be used by this panel to verify when it's been invalidated
    * without having to explicitly call [revalidate]
@@ -121,28 +109,6 @@
   private val cachedScaledContentSize = Dimension()
   private val cachedPreferredSize = Dimension()
 
-  /** This label displays the [SceneView] model if there is any */
-  private val modelNameLabel =
-    JBLabel().apply {
-      maximumSize = Dimension(Int.MAX_VALUE, Int.MAX_VALUE)
-      foreground = nameLabelDefaultColor
-      addMouseListener(
-        object : MouseAdapter() {
-          override fun mouseEntered(e: MouseEvent?) {
-            foreground = nameLabelHoverColor
-          }
-
-          override fun mouseExited(e: MouseEvent?) {
-            foreground = nameLabelDefaultColor
-          }
-
-          override fun mouseClicked(e: MouseEvent?) {
-            scope.launch { onLabelClicked(sceneView, false) }
-          }
-        }
-      )
-    }
-
   val positionableAdapter =
     object : PositionableContent {
       override val groupId: String?
@@ -240,7 +206,7 @@
         add(sceneViewStatusIcon, BorderLayout.LINE_START)
         sceneViewStatusIcon.isVisible = true
       }
-      add(modelNameLabel, BorderLayout.CENTER)
+      add(labelPanel, BorderLayout.CENTER)
       if (sceneViewToolbar != null) {
         add(sceneViewToolbar, BorderLayout.LINE_END)
         // Initialize the toolbar as invisible. Its visibility will be controlled by hovering the
@@ -348,7 +314,7 @@
       }
 
     addMouseListener(hoverTopPanelMouseListener)
-    modelNameLabel.addMouseListener(hoverTopPanelMouseListener)
+    labelPanel.addMouseListener(hoverTopPanelMouseListener)
   }
 
   private val sceneViewBottomPanel =
@@ -387,6 +353,7 @@
 
   override fun doLayout() {
     layoutData = LayoutData.fromSceneView(sceneView)
+    labelPanel.layoutData = layoutData
 
     //      SceneViewPeerPanel layout:
     //
@@ -405,28 +372,14 @@
     //       ←-------→                         ←--------→
     //       preferredWidth                    preferredWidth
 
-    // If there is a model name, we manually assign the content of the modelNameLabel and position
-    // it here.
-    // Once this panel gets more functionality, we will need the use of a layout manager. For now,
-    // we just lay out the component manually.
-    if (layoutData.modelName == null) {
-      modelNameLabel.text = ""
-      modelNameLabel.toolTipText = ""
-      sceneViewTopPanel.isVisible = false
-    } else {
-      modelNameLabel.text = layoutData.modelName
-      // Use modelName for tooltip if none has been specified.
-      modelNameLabel.toolTipText = layoutData.modelTooltip ?: layoutData.modelName
-      // We layout the top panel. We make the width to match the SceneViewPanel width and we let it
-      // choose its own
-      // height.
+    sceneViewTopPanel.isVisible = labelPanel.isVisible
+    if (labelPanel.isVisible) {
       sceneViewTopPanel.setBounds(
         0,
         0,
         width + insets.horizontal,
         sceneViewTopPanel.preferredSize.height
       )
-      sceneViewTopPanel.isVisible = true
     }
     val leftSectionWidth = sceneViewLeftPanel.preferredSize.width
     val centerPanelHeight =
diff --git a/designer/src/com/android/tools/idea/uibuilder/actions/GenerateLayoutTestSkeletonAction.java b/designer/src/com/android/tools/idea/uibuilder/actions/GenerateLayoutTestSkeletonAction.java
index ce2a272..6d8a788 100644
--- a/designer/src/com/android/tools/idea/uibuilder/actions/GenerateLayoutTestSkeletonAction.java
+++ b/designer/src/com/android/tools/idea/uibuilder/actions/GenerateLayoutTestSkeletonAction.java
@@ -36,8 +36,10 @@
 import com.google.common.base.CaseFormat;
 import com.google.common.base.Splitter;
 import com.google.common.collect.ImmutableList;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.fileEditor.FileEditor;
 import com.intellij.openapi.fileEditor.FileEditorManager;
@@ -64,6 +66,11 @@
   }
 
   @Override
+  public @NotNull ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.EDT;
+  }
+
+  @Override
   public void update(@NotNull AnActionEvent event) {
     event.getPresentation().setEnabled(getModel(event.getProject()) != null);
   }
diff --git a/designer/src/com/android/tools/idea/uibuilder/surface/NlDesignSurface.java b/designer/src/com/android/tools/idea/uibuilder/surface/NlDesignSurface.java
index 830b999..aa7a6de 100644
--- a/designer/src/com/android/tools/idea/uibuilder/surface/NlDesignSurface.java
+++ b/designer/src/com/android/tools/idea/uibuilder/surface/NlDesignSurface.java
@@ -132,7 +132,6 @@
     private BiFunction<NlDesignSurface, NlModel, LayoutlibSceneManager> mySceneManagerProvider =
       NlDesignSurface::defaultSceneManagerProvider;
     private SurfaceLayoutManager myLayoutManager;
-    private NavigationHandler myNavigationHandler;
     @SurfaceScale private double myMinScale = DEFAULT_MIN_SCALE;
     @SurfaceScale private double myMaxScale = DEFAULT_MAX_SCALE;
     /**
@@ -231,15 +230,6 @@
       return this;
     }
 
-    /**
-     * When the surface is clicked, it can delegate navigation related task to the given handler.
-     * @param navigationHandler handles the navigation when the surface is clicked.
-     */
-    @NotNull
-    public Builder setNavigationHandler(NavigationHandler navigationHandler) {
-      myNavigationHandler = navigationHandler;
-      return this;
-    }
 
     /**
      * Restrict the minimum zoom level to the given value. The default value is {@link #DEFAULT_MIN_SCALE}.
@@ -357,7 +347,6 @@
         myActionManagerProvider,
         myInteractableProvider,
         myInteractionHandlerProvider,
-        myNavigationHandler,
         myMinScale,
         myMaxScale,
         myActionHandlerProvider,
@@ -388,9 +377,6 @@
   private final BiFunction<NlDesignSurface, NlModel, LayoutlibSceneManager> mySceneManagerProvider;
 
   @NotNull private SurfaceLayoutManager myLayoutManager;
-
-  @Nullable private final NavigationHandler myNavigationHandler;
-
   @SurfaceScale private final double myMinScale;
   @SurfaceScale private final double myMaxScale;
 
@@ -417,7 +403,6 @@
                           @NotNull Function<DesignSurface<LayoutlibSceneManager>, ActionManager<? extends DesignSurface<LayoutlibSceneManager>>> actionManagerProvider,
                           @NotNull Function<DesignSurface<LayoutlibSceneManager>, Interactable> interactableProvider,
                           @NotNull Function<DesignSurface<LayoutlibSceneManager>, InteractionHandler> interactionHandlerProvider,
-                          @Nullable NavigationHandler navigationHandler,
                           @SurfaceScale double minScale,
                           @SurfaceScale double maxScale,
                           @NotNull Function<DesignSurface<LayoutlibSceneManager>, DesignSurfaceActionHandler> actionHandlerProvider,
@@ -437,16 +422,9 @@
     myAccessoryPanel.setSurface(this);
     myLayoutManager = defaultLayoutManager;
     mySceneManagerProvider = sceneManagerProvider;
-    myNavigationHandler = navigationHandler;
     mySupportedActions = supportedActions;
     myShouldRenderErrorsPanel = shouldRenderErrorsPanel;
     myVisualLintIssueProvider = new VisualLintIssueProvider(this);
-
-    if (myNavigationHandler != null) {
-      Disposer.register(this, myNavigationHandler);
-      mySceneViewPanel.setOnLabelClicked(myNavigationHandler::handleNavigate);
-    }
-
     myMinScale = minScale;
     myMaxScale = maxScale;
 
@@ -595,11 +573,6 @@
     revalidateScrollArea();
   }
 
-  @Nullable
-  public NavigationHandler getNavigationHandler() {
-    return myNavigationHandler;
-  }
-
   @Override
   public boolean shouldRenderErrorsPanel() {
     return myShouldRenderErrorsPanel;
diff --git a/designer/src/com/android/tools/idea/uibuilder/surface/NlLayoutScannerMetricTracker.kt b/designer/src/com/android/tools/idea/uibuilder/surface/NlLayoutScannerMetricTracker.kt
index b4fa3a1..b0871e3 100644
--- a/designer/src/com/android/tools/idea/uibuilder/surface/NlLayoutScannerMetricTracker.kt
+++ b/designer/src/com/android/tools/idea/uibuilder/surface/NlLayoutScannerMetricTracker.kt
@@ -25,7 +25,6 @@
 import com.google.wireless.android.sdk.stats.AtfResultDetail
 import com.google.wireless.android.sdk.stats.IgnoreAtfResultEvent
 import com.google.wireless.android.sdk.stats.LayoutEditorEvent
-import com.intellij.lang.annotation.HighlightSeverity
 
 /** Metric tracker for results from accessibility testing framework */
 class NlLayoutScannerMetricTracker(private val surface: NlDesignSurface) {
@@ -33,55 +32,6 @@
   /** Track expanded issues so we don't log them multiple times */
   @VisibleForTesting val expanded = HashSet<Issue>()
 
-  /**
-   * Tracks all issues created by atf.
-   *
-   * TODO(b/298229332): Remove this, or call it somewhere other than tests.
-   */
-  fun trackIssues(issues: Set<Issue>, renderMetric: RenderResultMetricData) {
-    val atfIssues =
-      issues.filterIsInstance<NlAtfIssue>().filter {
-        it.severity == HighlightSeverity.ERROR || it.severity == HighlightSeverity.WARNING
-      }
-    if (atfIssues.isEmpty()) {
-      return
-    }
-
-    CommonUsageTracker.getInstance(surface).logStudioEvent(
-      LayoutEditorEvent.LayoutEditorEventType.ATF_AUDIT_RESULT
-    ) { event ->
-      val atfResultBuilder = AtfAuditResult.newBuilder()
-      atfIssues.forEach { issue -> atfResultBuilder.addCounts(atfResultCountBuilder(issue)) }
-      atfResultBuilder
-        .setAuditDurationMs(renderMetric.scanMs)
-        .setTotalRenderTimeMs(renderMetric.renderMs)
-        .setComponentCount(renderMetric.componentCount)
-        .setRenderResult(renderMetric.isRenderResultSuccess)
-      event.setAtfAuditResult(atfResultBuilder)
-    }
-  }
-
-  /**
-   * Track the first time the issue is expanded by user.
-   *
-   * TODO(b/298229332): Remove this, or call it somewhere other than tests.
-   */
-  fun trackFirstExpanded(issue: Issue) {
-    if (issue !is NlAtfIssue || expanded.contains(issue)) {
-      return
-    }
-
-    expanded.add(issue)
-
-    CommonUsageTracker.getInstance(surface).logStudioEvent(
-      LayoutEditorEvent.LayoutEditorEventType.ATF_AUDIT_RESULT
-    ) { event ->
-      val atfResultBuilder = AtfAuditResult.newBuilder()
-      atfResultBuilder.addCounts(atfResultCountBuilder(issue).setErrorExpanded(true))
-      event.setAtfAuditResult(atfResultBuilder)
-    }
-  }
-
   /** Track the ignore button is clicked by user. */
   fun trackIgnoreButtonClicked(issue: ValidatorData.Issue) {
     CommonUsageTracker.getInstance(surface).logStudioEvent(
@@ -132,21 +82,6 @@
       else -> AtfFixDetail.AtfFixType.UNKNOWN
     }
   }
-
-  private fun atfResultCountBuilder(issue: NlAtfIssue): AtfAuditResult.AtfResultCount.Builder {
-    val atfResultCountBuilder =
-      AtfAuditResult.AtfResultCount.newBuilder().setCheckName(issue.srcClass)
-    issue.result.mFix?.let { atfResultCountBuilder.addFixes(atfFixDetailBuilder(it)) }
-    atfResultCountBuilder.setResultType(
-      when (issue.result.mLevel) {
-        ValidatorData.Level.ERROR -> AtfAuditResult.AtfResultCount.CheckResultType.ERROR
-        ValidatorData.Level.WARNING -> AtfAuditResult.AtfResultCount.CheckResultType.WARNING
-        ValidatorData.Level.INFO -> AtfAuditResult.AtfResultCount.CheckResultType.INFO
-        else -> AtfAuditResult.AtfResultCount.CheckResultType.UNKNOWN // Should not be triggered.
-      }
-    )
-    return atfResultCountBuilder
-  }
 }
 
 /** Metric metadata related to render results. */
diff --git a/designer/src/com/android/tools/idea/uibuilder/surface/layout/GroupedGridSurfaceLayoutManager.kt b/designer/src/com/android/tools/idea/uibuilder/surface/layout/GroupedGridSurfaceLayoutManager.kt
index 23c25ac..55597c2 100644
--- a/designer/src/com/android/tools/idea/uibuilder/surface/layout/GroupedGridSurfaceLayoutManager.kt
+++ b/designer/src/com/android/tools/idea/uibuilder/surface/layout/GroupedGridSurfaceLayoutManager.kt
@@ -264,7 +264,7 @@
 
     val visibleContents = content.filter { it.isVisible }
     if (visibleContents.size == 1) {
-      val singleContent = content.single()
+      val singleContent = visibleContents.single()
       // When there is only one visible preview, centralize it as a special case.
       val point = getSingleContentPosition(singleContent, availableWidth, availableHeight)
 
diff --git a/designer/testSrc/com/android/tools/idea/common/error/DesignerCommonIssuePanelTest.kt b/designer/testSrc/com/android/tools/idea/common/error/DesignerCommonIssuePanelTest.kt
index 3ef230e..f67a511 100644
--- a/designer/testSrc/com/android/tools/idea/common/error/DesignerCommonIssuePanelTest.kt
+++ b/designer/testSrc/com/android/tools/idea/common/error/DesignerCommonIssuePanelTest.kt
@@ -63,10 +63,9 @@
         rule.project,
         model,
         { LayoutValidationNodeFactory },
-        provider
-      ) {
-        ""
-      }
+        provider,
+        { "" }
+      )
     // Make sure the Tree is added into DesignerCommonIssuePanel.
     IdeEventQueue.getInstance().flushQueue()
     val tree = UIUtil.findComponentOfType(panel.getComponent(), Tree::class.java)!!
@@ -132,10 +131,9 @@
         rule.project,
         model,
         { LayoutValidationNodeFactory },
-        provider
-      ) {
-        ""
-      }
+        provider,
+        { "" }
+      )
     // Make sure the Tree is added into DesignerCommonIssuePanel.
     IdeEventQueue.getInstance().flushQueue()
     val tree = UIUtil.findComponentOfType(panel.getComponent(), Tree::class.java)!!
@@ -198,10 +196,9 @@
         rule.project,
         model,
         { LayoutValidationNodeFactory },
-        provider
-      ) {
-        ""
-      }
+        provider,
+        { "" }
+      )
     // Make sure the Tree is added into DesignerCommonIssuePanel.
     IdeEventQueue.getInstance().flushQueue()
     val tree = UIUtil.findComponentOfType(panel.getComponent(), Tree::class.java)!!
diff --git a/designer/testSrc/com/android/tools/idea/common/error/IssueNodeVisitorTest.kt b/designer/testSrc/com/android/tools/idea/common/error/IssueNodeVisitorTest.kt
index 96d4e03..ee9f738 100644
--- a/designer/testSrc/com/android/tools/idea/common/error/IssueNodeVisitorTest.kt
+++ b/designer/testSrc/com/android/tools/idea/common/error/IssueNodeVisitorTest.kt
@@ -46,10 +46,9 @@
         rule.project,
         model,
         { LayoutValidationNodeFactory },
-        provider
-      ) {
-        ""
-      }
+        provider,
+        { "" }
+      )
     IdeEventQueue.getInstance().flushQueue()
     val tree = UIUtil.findComponentOfType(panel.getComponent(), Tree::class.java)!!
 
diff --git a/designer/testSrc/com/android/tools/idea/common/error/SceneViewIssueNodeVisitorTest.kt b/designer/testSrc/com/android/tools/idea/common/error/SceneViewIssueNodeVisitorTest.kt
index 5c1136b..e2034617 100644
--- a/designer/testSrc/com/android/tools/idea/common/error/SceneViewIssueNodeVisitorTest.kt
+++ b/designer/testSrc/com/android/tools/idea/common/error/SceneViewIssueNodeVisitorTest.kt
@@ -64,10 +64,9 @@
         rule.project,
         model,
         { LayoutValidationNodeFactory },
-        provider
-      ) {
-        ""
-      }
+        provider,
+        { "" }
+      )
     IdeEventQueue.getInstance().flushQueue()
     val tree = UIUtil.findComponentOfType(panel.getComponent(), Tree::class.java)!!
 
@@ -105,10 +104,9 @@
         rule.project,
         model,
         { LayoutValidationNodeFactory },
-        provider
-      ) {
-        ""
-      }
+        provider,
+        { "" }
+      )
     IdeEventQueue.getInstance().flushQueue()
     val tree = UIUtil.findComponentOfType(panel.getComponent(), Tree::class.java)!!
 
@@ -146,10 +144,9 @@
         rule.project,
         model,
         { LayoutValidationNodeFactory },
-        provider
-      ) {
-        ""
-      }
+        provider,
+        { "" }
+      )
     IdeEventQueue.getInstance().flushQueue()
     val tree = UIUtil.findComponentOfType(panel.getComponent(), Tree::class.java)!!
 
@@ -188,10 +185,9 @@
         rule.project,
         model,
         { LayoutValidationNodeFactory },
-        provider
-      ) {
-        ""
-      }
+        provider,
+        { "" }
+      )
     IdeEventQueue.getInstance().flushQueue()
     val tree = UIUtil.findComponentOfType(panel.getComponent(), Tree::class.java)!!
 
diff --git a/designer/testSrc/com/android/tools/idea/common/surface/InteractiveLabelPanelTest.kt b/designer/testSrc/com/android/tools/idea/common/surface/InteractiveLabelPanelTest.kt
new file mode 100644
index 0000000..fc3bfcf
--- /dev/null
+++ b/designer/testSrc/com/android/tools/idea/common/surface/InteractiveLabelPanelTest.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.common.surface
+
+import com.android.tools.adtui.swing.FakeUi
+import com.android.tools.idea.testing.AndroidProjectRule
+import com.intellij.openapi.Disposable
+import com.intellij.openapi.util.Disposer
+import java.awt.Dimension
+import java.util.concurrent.TimeUnit
+import kotlin.test.assertEquals
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withTimeout
+import org.junit.After
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+class InteractiveLabelPanelTest {
+
+  @get:Rule val projectRule = AndroidProjectRule.inMemory()
+  private lateinit var parentDisposable: Disposable
+
+  @Before
+  fun setUp() {
+    parentDisposable = Disposer.newDisposable()
+  }
+
+  @After
+  fun tearDown() {
+    Disposer.dispose(parentDisposable)
+  }
+
+  @Test
+  @Ignore("b/289994157")
+  fun `click label`() {
+    runBlocking {
+      var clickCount = 0
+      fun labelClicked(): Boolean {
+        clickCount++
+        return false
+      }
+
+      val layoutData = LayoutData(1.0, "Name", "Tooltip", 0, 0, Dimension(10, 10))
+      val label =
+        InteractiveLabelPanel(layoutData, parentDisposable, ::labelClicked).apply {
+          size = Dimension(250, 50)
+        }
+      FakeUi(label).also { it.clickOn(label) }
+      withTimeout(TimeUnit.SECONDS.toMillis(1)) { assertEquals(1, clickCount) }
+    }
+  }
+}
diff --git a/designer/testSrc/com/android/tools/idea/common/surface/LabelPanelTest.kt b/designer/testSrc/com/android/tools/idea/common/surface/LabelPanelTest.kt
new file mode 100644
index 0000000..33b23b5
--- /dev/null
+++ b/designer/testSrc/com/android/tools/idea/common/surface/LabelPanelTest.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.common.surface
+
+import com.android.tools.adtui.swing.FakeUi
+import java.awt.Dimension
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Test
+
+class LabelPanelTest {
+
+  @Test
+  fun `label is visible`() {
+    val layoutData = LayoutData(1.0, "Name", "Tooltip", 0, 0, Dimension(10, 10))
+    val label = LabelPanel(layoutData).apply { size = Dimension(250, 50) }
+    FakeUi(label).also { it.layout() }
+    assertTrue(label.isVisible)
+  }
+
+  @Test
+  fun `label is not visible`() {
+    val layoutData = LayoutData(1.0, null, null, 0, 0, Dimension(10, 10))
+    val label = LabelPanel(layoutData).apply { size = Dimension(250, 50) }
+    FakeUi(label).also { it.layout() }
+    assertFalse(label.isVisible)
+  }
+}
diff --git a/designer/testSrc/com/android/tools/idea/uibuilder/surface/NlLayoutScannerMetricTrackerTest.kt b/designer/testSrc/com/android/tools/idea/uibuilder/surface/NlLayoutScannerMetricTrackerTest.kt
index 4e6023b..c98c586 100644
--- a/designer/testSrc/com/android/tools/idea/uibuilder/surface/NlLayoutScannerMetricTrackerTest.kt
+++ b/designer/testSrc/com/android/tools/idea/uibuilder/surface/NlLayoutScannerMetricTrackerTest.kt
@@ -18,13 +18,11 @@
 import com.android.SdkConstants
 import com.android.tools.idea.common.analytics.CommonNopTracker
 import com.android.tools.idea.common.analytics.CommonUsageTracker
-import com.android.tools.idea.common.error.Issue
 import com.android.tools.idea.common.error.IssueSource
 import com.android.tools.idea.common.model.NlModel
 import com.android.tools.idea.uibuilder.LayoutTestCase
 import com.android.tools.idea.validator.ValidatorData
 import com.google.wireless.android.sdk.stats.LayoutEditorEvent
-import com.intellij.lang.annotation.HighlightSeverity
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -45,80 +43,6 @@
   }
 
   @Test
-  fun trackIssueNoIssues() {
-    val tracker = NlLayoutScannerMetricTracker(mockSurface)
-    val nlAtfIssues = setOf<Issue>()
-    val renderResultMetricData = RenderResultMetricData(1, 1, 1)
-
-    tracker.trackIssues(nlAtfIssues, renderResultMetricData)
-
-    val usageTracker = CommonUsageTracker.getInstance(mockSurface) as CommonNopTracker
-    assertNull(usageTracker.lastTrackedEvent)
-  }
-
-  @Test
-  fun trackIssueNoNlAtfIssues() {
-    val tracker = NlLayoutScannerMetricTracker(mockSurface)
-    val nlAtfIssues = setOf<Issue>(TestIssue())
-    val renderResultMetricData = RenderResultMetricData(1, 1, 1)
-
-    tracker.trackIssues(nlAtfIssues, renderResultMetricData)
-
-    val usageTracker = CommonUsageTracker.getInstance(mockSurface) as CommonNopTracker
-    assertNull(usageTracker.lastTrackedEvent)
-  }
-
-  @Test
-  fun trackIssues() {
-    val tracker = NlLayoutScannerMetricTracker(mockSurface)
-    val nlAtfIssues = setOf(createTestNlAtfIssue())
-    val renderResultMetricData = RenderResultMetricData(1, 1, 1)
-
-    tracker.trackIssues(nlAtfIssues, renderResultMetricData)
-
-    val usageTracker = CommonUsageTracker.getInstance(mockSurface) as CommonNopTracker
-    assertEquals(
-      LayoutEditorEvent.LayoutEditorEventType.ATF_AUDIT_RESULT,
-      usageTracker.lastTrackedEvent
-    )
-  }
-
-  @Test
-  fun trackExpandedNotAtfIssue() {
-    val tracker = NlLayoutScannerMetricTracker(mockSurface)
-    tracker.trackFirstExpanded(TestIssue())
-
-    val usageTracker = CommonUsageTracker.getInstance(mockSurface) as CommonNopTracker
-    assertNull(usageTracker.lastTrackedEvent)
-  }
-
-  @Test
-  fun trackExpandedAlreadyContained() {
-    val tracker = NlLayoutScannerMetricTracker(mockSurface)
-    val issue = createTestNlAtfIssue()
-    tracker.expanded.add(issue)
-
-    tracker.trackFirstExpanded(issue)
-
-    val usageTracker = CommonUsageTracker.getInstance(mockSurface) as CommonNopTracker
-    assertNull(usageTracker.lastTrackedEvent)
-  }
-
-  @Test
-  fun trackExpanded() {
-    val tracker = NlLayoutScannerMetricTracker(mockSurface)
-    val issue = createTestNlAtfIssue()
-    tracker.trackFirstExpanded(issue)
-
-    val usageTracker = CommonUsageTracker.getInstance(mockSurface) as CommonNopTracker
-    assertEquals(
-      LayoutEditorEvent.LayoutEditorEventType.ATF_AUDIT_RESULT,
-      usageTracker.lastTrackedEvent
-    )
-    assertTrue(tracker.expanded.contains(issue))
-  }
-
-  @Test
   fun trackIgnoreButtonClicked() {
     val tracker = NlLayoutScannerMetricTracker(mockSurface)
     val issue = ScannerTestHelper.createTestIssueBuilder().build()
@@ -163,17 +87,4 @@
     val issue: ValidatorData.Issue = ScannerTestHelper.createTestIssueBuilder().build()
     return NlAtfIssue(issue, IssueSource.NONE, mockModel)
   }
-
-  private class TestIssue : Issue() {
-    override val summary: String
-      get() = ""
-    override val description: String
-      get() = ""
-    override val severity: HighlightSeverity
-      get() = HighlightSeverity.ERROR
-    override val source: IssueSource
-      get() = IssueSource.NONE
-    override val category: String
-      get() = ""
-  }
 }
diff --git a/device-explorer-files/src/com/android/tools/idea/device/explorer/files/actions/GotoDatabaseFolderAction.java b/device-explorer-files/src/com/android/tools/idea/device/explorer/files/actions/GotoDatabaseFolderAction.java
deleted file mode 100644
index 801c583..0000000
--- a/device-explorer-files/src/com/android/tools/idea/device/explorer/files/actions/GotoDatabaseFolderAction.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tools.idea.device.explorer.files.actions;
-
-import com.android.tools.idea.device.explorer.files.DeviceFileExplorerControllerImpl;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.project.DumbAwareAction;
-import org.jetbrains.annotations.NotNull;
-
-public class GotoDatabaseFolderAction extends DumbAwareAction {
-  @Override
-  public void update(@NotNull AnActionEvent e) {
-    DeviceFileExplorerControllerImpl controller = DeviceFileExplorerControllerImpl.getProjectController(e.getProject());
-    e.getPresentation().setEnabled(controller != null && controller.hasActiveDevice());
-  }
-
-  @Override
-  public void actionPerformed(@NotNull AnActionEvent e) {
-  }
-}
diff --git a/device-explorer-files/src/com/android/tools/idea/device/explorer/files/actions/GotoSdcardFolderAction.java b/device-explorer-files/src/com/android/tools/idea/device/explorer/files/actions/GotoSdcardFolderAction.java
deleted file mode 100644
index ff74f39..0000000
--- a/device-explorer-files/src/com/android/tools/idea/device/explorer/files/actions/GotoSdcardFolderAction.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tools.idea.device.explorer.files.actions;
-
-import com.android.tools.idea.device.explorer.files.DeviceFileExplorerControllerImpl;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.project.DumbAwareAction;
-import org.jetbrains.annotations.NotNull;
-
-public class GotoSdcardFolderAction extends DumbAwareAction {
-  @Override
-  public void update(@NotNull AnActionEvent e) {
-    DeviceFileExplorerControllerImpl controller = DeviceFileExplorerControllerImpl.getProjectController(e.getProject());
-    e.getPresentation().setEnabled(controller != null && controller.hasActiveDevice());
-  }
-
-  @Override
-  public void actionPerformed(@NotNull AnActionEvent e) {
-  }
-}
diff --git a/device-explorer-files/src/com/android/tools/idea/device/explorer/files/actions/GotoSharedPrefsFolderAction.java b/device-explorer-files/src/com/android/tools/idea/device/explorer/files/actions/GotoSharedPrefsFolderAction.java
deleted file mode 100644
index 0a90ce8..0000000
--- a/device-explorer-files/src/com/android/tools/idea/device/explorer/files/actions/GotoSharedPrefsFolderAction.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tools.idea.device.explorer.files.actions;
-
-import com.android.tools.idea.device.explorer.files.DeviceFileExplorerControllerImpl;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.project.DumbAwareAction;
-import org.jetbrains.annotations.NotNull;
-
-public class GotoSharedPrefsFolderAction extends DumbAwareAction {
-  @Override
-  public void update(@NotNull AnActionEvent e) {
-    DeviceFileExplorerControllerImpl controller = DeviceFileExplorerControllerImpl.getProjectController(e.getProject());
-    e.getPresentation().setEnabled(controller != null && controller.hasActiveDevice());
-  }
-
-  @Override
-  public void actionPerformed(@NotNull AnActionEvent e) {
-  }
-}
diff --git a/device-explorer-files/src/com/android/tools/idea/device/explorer/files/actions/HelpAction.java b/device-explorer-files/src/com/android/tools/idea/device/explorer/files/actions/HelpAction.java
deleted file mode 100644
index 53e66347..0000000
--- a/device-explorer-files/src/com/android/tools/idea/device/explorer/files/actions/HelpAction.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tools.idea.device.explorer.files.actions;
-
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.project.DumbAwareAction;
-import org.jetbrains.annotations.NotNull;
-
-public class HelpAction extends DumbAwareAction {
-  @Override
-  public void update(@NotNull AnActionEvent e) {
-    e.getPresentation().setEnabled(false);
-  }
-
-  @Override
-  public void actionPerformed(@NotNull AnActionEvent e) {
-  }
-}
\ No newline at end of file
diff --git a/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/actions/GotoDatabaseFolderAction.java b/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/actions/GotoDatabaseFolderAction.java
index 2782df9..add6f53 100644
--- a/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/actions/GotoDatabaseFolderAction.java
+++ b/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/actions/GotoDatabaseFolderAction.java
@@ -16,11 +16,19 @@
 package com.android.tools.idea.file.explorer.toolwindow.actions;
 
 import com.android.tools.idea.file.explorer.toolwindow.DeviceExplorerController;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.project.DumbAwareAction;
 import org.jetbrains.annotations.NotNull;
 
 public class GotoDatabaseFolderAction extends DumbAwareAction {
+
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.EDT;
+  }
+
   @Override
   public void update(@NotNull AnActionEvent e) {
     DeviceExplorerController controller = DeviceExplorerController.getProjectController(e.getProject());
diff --git a/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/actions/GotoSdcardFolderAction.java b/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/actions/GotoSdcardFolderAction.java
index 2529965..92a6910 100644
--- a/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/actions/GotoSdcardFolderAction.java
+++ b/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/actions/GotoSdcardFolderAction.java
@@ -16,11 +16,19 @@
 package com.android.tools.idea.file.explorer.toolwindow.actions;
 
 import com.android.tools.idea.file.explorer.toolwindow.DeviceExplorerController;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.project.DumbAwareAction;
 import org.jetbrains.annotations.NotNull;
 
 public class GotoSdcardFolderAction extends DumbAwareAction {
+
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.EDT;
+  }
+
   @Override
   public void update(@NotNull AnActionEvent e) {
     DeviceExplorerController controller = DeviceExplorerController.getProjectController(e.getProject());
diff --git a/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/actions/GotoSharedPrefsFolderAction.java b/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/actions/GotoSharedPrefsFolderAction.java
index 555ec14..7f0f974 100644
--- a/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/actions/GotoSharedPrefsFolderAction.java
+++ b/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/actions/GotoSharedPrefsFolderAction.java
@@ -16,11 +16,19 @@
 package com.android.tools.idea.file.explorer.toolwindow.actions;
 
 import com.android.tools.idea.file.explorer.toolwindow.DeviceExplorerController;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.project.DumbAwareAction;
 import org.jetbrains.annotations.NotNull;
 
 public class GotoSharedPrefsFolderAction extends DumbAwareAction {
+
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.EDT;
+  }
+
   @Override
   public void update(@NotNull AnActionEvent e) {
     DeviceExplorerController controller = DeviceExplorerController.getProjectController(e.getProject());
diff --git a/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/actions/HelpAction.java b/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/actions/HelpAction.java
index 8882865..ea7eb09 100644
--- a/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/actions/HelpAction.java
+++ b/device-file-explorer-toolwindow/src/com/android/tools/idea/file/explorer/toolwindow/actions/HelpAction.java
@@ -15,11 +15,19 @@
  */
 package com.android.tools.idea.file.explorer.toolwindow.actions;
 
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.project.DumbAwareAction;
 import org.jetbrains.annotations.NotNull;
 
 public class HelpAction extends DumbAwareAction {
+
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
   @Override
   public void update(@NotNull AnActionEvent e) {
     e.getPresentation().setEnabled(false);
diff --git a/device-manager/src/com/android/tools/idea/devicemanager/DeviceManagerWelcomeScreenAction.java b/device-manager/src/com/android/tools/idea/devicemanager/DeviceManagerWelcomeScreenAction.java
index 28b4965..b856df7 100644
--- a/device-manager/src/com/android/tools/idea/devicemanager/DeviceManagerWelcomeScreenAction.java
+++ b/device-manager/src/com/android/tools/idea/devicemanager/DeviceManagerWelcomeScreenAction.java
@@ -17,6 +17,7 @@
 
 import com.android.tools.idea.avdmanager.HardwareAccelerationCheck;
 import com.android.tools.idea.flags.StudioFlags;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.Presentation;
 import com.intellij.openapi.project.DumbAwareAction;
@@ -47,6 +48,11 @@
   }
 
   @Override
+  public @NotNull ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
+  @Override
   public void update(@NotNull AnActionEvent event) {
     Presentation presentation = event.getPresentation();
 
diff --git a/device-manager/testSrc/com/android/tools/idea/devicemanager/physicaltab/PhysicalDeviceChangeListenerTest.java b/device-manager/testSrc/com/android/tools/idea/devicemanager/physicaltab/PhysicalDeviceChangeListenerTest.java
index 999ae6a..87ae9a2 100644
--- a/device-manager/testSrc/com/android/tools/idea/devicemanager/physicaltab/PhysicalDeviceChangeListenerTest.java
+++ b/device-manager/testSrc/com/android/tools/idea/devicemanager/physicaltab/PhysicalDeviceChangeListenerTest.java
@@ -17,8 +17,8 @@
 
 import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
 import com.android.ddmlib.IDevice;
-import com.android.tools.idea.devicemanager.CountDownLatchAssert;
-import com.android.tools.idea.devicemanager.CountDownLatchFutureCallback;
+import com.android.tools.idea.concurrency.CountDownLatchAssert;
+import com.android.tools.idea.concurrency.CountDownLatchFutureCallback;
 import com.android.tools.idea.devicemanager.DeviceManagerAndroidDebugBridge;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
diff --git a/device-manager/testSrc/com/android/tools/idea/devicemanager/physicaltab/PhysicalDeviceDetailsPanelTest.java b/device-manager/testSrc/com/android/tools/idea/devicemanager/physicaltab/PhysicalDeviceDetailsPanelTest.java
index 5bd8e14..8347020 100644
--- a/device-manager/testSrc/com/android/tools/idea/devicemanager/physicaltab/PhysicalDeviceDetailsPanelTest.java
+++ b/device-manager/testSrc/com/android/tools/idea/devicemanager/physicaltab/PhysicalDeviceDetailsPanelTest.java
@@ -19,8 +19,8 @@
 
 import com.android.sdklib.AndroidVersion;
 import com.android.tools.idea.device.Resolution;
-import com.android.tools.idea.devicemanager.CountDownLatchAssert;
-import com.android.tools.idea.devicemanager.CountDownLatchFutureCallback;
+import com.android.tools.idea.concurrency.CountDownLatchAssert;
+import com.android.tools.idea.concurrency.CountDownLatchFutureCallback;
 import com.android.tools.idea.devicemanager.DetailsPanel;
 import com.android.tools.idea.devicemanager.SerialNumber;
 import com.android.tools.idea.devicemanager.physicaltab.PhysicalDeviceDetailsPanel.SummarySection;
diff --git a/device-manager/testSrc/com/android/tools/idea/devicemanager/physicaltab/PhysicalDevicePanelTest.java b/device-manager/testSrc/com/android/tools/idea/devicemanager/physicaltab/PhysicalDevicePanelTest.java
index d3517b4..6ebb685 100644
--- a/device-manager/testSrc/com/android/tools/idea/devicemanager/physicaltab/PhysicalDevicePanelTest.java
+++ b/device-manager/testSrc/com/android/tools/idea/devicemanager/physicaltab/PhysicalDevicePanelTest.java
@@ -24,8 +24,8 @@
 import com.android.tools.idea.adb.wireless.WiFiPairingController;
 import com.android.tools.idea.devicemanager.ActivateDeviceFileExplorerWindowValue;
 import com.android.tools.idea.devicemanager.ConnectionType;
-import com.android.tools.idea.devicemanager.CountDownLatchAssert;
-import com.android.tools.idea.devicemanager.CountDownLatchFutureCallback;
+import com.android.tools.idea.concurrency.CountDownLatchAssert;
+import com.android.tools.idea.concurrency.CountDownLatchFutureCallback;
 import com.android.tools.idea.devicemanager.DetailsPanel;
 import com.android.tools.idea.devicemanager.DeviceType;
 import com.android.tools.idea.devicemanager.PopUpMenuValue;
diff --git a/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/ProcessManagerTest.java b/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/ProcessManagerTest.java
index c0cf49a..c8b3e79 100644
--- a/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/ProcessManagerTest.java
+++ b/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/ProcessManagerTest.java
@@ -21,8 +21,8 @@
 import com.android.ddmlib.IDevice.DeviceState;
 import com.android.sdklib.internal.avd.AvdInfo;
 import com.android.tools.idea.avdmanager.AvdManagerConnection;
-import com.android.tools.idea.devicemanager.CountDownLatchAssert;
-import com.android.tools.idea.devicemanager.CountDownLatchFutureCallback;
+import com.android.tools.idea.concurrency.CountDownLatchAssert;
+import com.android.tools.idea.concurrency.CountDownLatchFutureCallback;
 import com.android.tools.idea.devicemanager.Key;
 import com.android.tools.idea.devicemanager.virtualtab.ProcessManager.State;
 import com.google.common.util.concurrent.FutureCallback;
diff --git a/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/VirtualDeviceDetailsPanelTest.java b/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/VirtualDeviceDetailsPanelTest.java
index a8ba6e5..f8c092d 100644
--- a/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/VirtualDeviceDetailsPanelTest.java
+++ b/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/VirtualDeviceDetailsPanelTest.java
@@ -20,8 +20,8 @@
 import com.android.sdklib.internal.avd.AvdInfo;
 import com.android.sdklib.internal.avd.AvdInfo.AvdStatus;
 import com.android.tools.idea.device.Resolution;
-import com.android.tools.idea.devicemanager.CountDownLatchAssert;
-import com.android.tools.idea.devicemanager.CountDownLatchFutureCallback;
+import com.android.tools.idea.concurrency.CountDownLatchAssert;
+import com.android.tools.idea.concurrency.CountDownLatchFutureCallback;
 import com.android.tools.idea.devicemanager.Device;
 import com.android.tools.idea.devicemanager.InfoSection;
 import com.android.tools.idea.devicemanager.StorageDevice;
diff --git a/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/VirtualDeviceTableModelTest.java b/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/VirtualDeviceTableModelTest.java
index 885ca66..9bae7b5 100644
--- a/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/VirtualDeviceTableModelTest.java
+++ b/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/VirtualDeviceTableModelTest.java
@@ -25,8 +25,8 @@
 import com.android.sdklib.internal.avd.AvdInfo;
 import com.android.tools.idea.avdmanager.AvdLaunchListener.RequestType;
 import com.android.tools.idea.avdmanager.AvdManagerConnection;
-import com.android.tools.idea.devicemanager.CountDownLatchAssert;
-import com.android.tools.idea.devicemanager.CountDownLatchFutureCallback;
+import com.android.tools.idea.concurrency.CountDownLatchAssert;
+import com.android.tools.idea.concurrency.CountDownLatchFutureCallback;
 import com.android.tools.idea.devicemanager.DeviceManagerAndroidDebugBridge;
 import com.android.tools.idea.devicemanager.Key;
 import com.android.tools.idea.devicemanager.virtualtab.VirtualDeviceTableModel.SetAllOnline;
diff --git a/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/VirtualDeviceTableTest.java b/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/VirtualDeviceTableTest.java
index 5aaa097..5277359 100644
--- a/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/VirtualDeviceTableTest.java
+++ b/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/VirtualDeviceTableTest.java
@@ -19,8 +19,8 @@
 
 import com.android.sdklib.internal.avd.AvdInfo;
 import com.android.sdklib.repository.targets.SystemImage;
-import com.android.tools.idea.devicemanager.CountDownLatchAssert;
-import com.android.tools.idea.devicemanager.CountDownLatchFutureCallback;
+import com.android.tools.idea.concurrency.CountDownLatchAssert;
+import com.android.tools.idea.concurrency.CountDownLatchFutureCallback;
 import com.android.tools.idea.wearpairing.WearPairingManager;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
diff --git a/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/VirtualDeviceWatcherTest.java b/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/VirtualDeviceWatcherTest.java
index 5c7c25d..56a9634 100644
--- a/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/VirtualDeviceWatcherTest.java
+++ b/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/VirtualDeviceWatcherTest.java
@@ -17,7 +17,7 @@
 
 import com.android.sdklib.internal.avd.AvdInfo;
 import com.android.sdklib.internal.avd.AvdManager;
-import com.android.tools.idea.devicemanager.CountDownLatchAssert;
+import com.android.tools.idea.concurrency.CountDownLatchAssert;
 import com.intellij.openapi.wm.IdeFrame;
 import com.intellij.testFramework.ApplicationRule;
 import java.util.List;
diff --git a/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/WipeDataItemTest.kt b/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/WipeDataItemTest.kt
index e02d554..5b8f450 100644
--- a/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/WipeDataItemTest.kt
+++ b/device-manager/testSrc/com/android/tools/idea/devicemanager/virtualtab/WipeDataItemTest.kt
@@ -19,8 +19,8 @@
 import com.android.testutils.MockitoKt.mock
 import com.android.testutils.MockitoKt.whenever
 import com.android.tools.idea.avdmanager.AvdManagerConnection
-import com.android.tools.idea.devicemanager.CountDownLatchAssert
-import com.android.tools.idea.devicemanager.CountDownLatchFutureCallback
+import com.android.tools.idea.concurrency.CountDownLatchAssert
+import com.android.tools.idea.concurrency.CountDownLatchFutureCallback
 import com.android.tools.idea.devicemanager.Key
 import com.google.common.util.concurrent.FutureCallback
 import com.google.common.util.concurrent.Futures.immediateFuture
diff --git a/execution/common/BUILD b/execution/common/BUILD
index a3d16f5..d480792 100644
--- a/execution/common/BUILD
+++ b/execution/common/BUILD
@@ -1,4 +1,5 @@
 load("//tools/base/bazel:bazel.bzl", "iml_module")
+load("//tools/base/bazel:maven.bzl", "maven_repository")
 
 # managed by go/iml_to_build
 iml_module(
@@ -36,9 +37,16 @@
     test_class = "com.android.tools.idea.execution.common.AndroidExecutionCommonTestSuite",
     # keep sorted
     test_data = [
+        ":test_deps",
+        "//prebuilts/studio/sdk:build-tools/latest",
         "//prebuilts/studio/sdk:platform-tools",
         "//prebuilts/studio/sdk:platforms/latest",
+        "//tools/adt/idea/android/annotations",
         "//tools/adt/idea/android/testData",
+        "//tools/base/build-system:android_gradle_plugin.zip",
+        "//tools/base/build-system:android_gradle_plugin_runtime_dependencies",
+        "//tools/base/build-system:gradle-distrib",
+        "//tools/base/build-system/integration-test:kotlin_gradle_plugin_prebuilts",
     ],
     test_srcs = ["testSrc"],
     visibility = ["//visibility:public"],
@@ -69,3 +77,15 @@
         "//tools/base/adblib:studio.android.sdktools.adblib[module, test]",
     ],
 )
+
+maven_repository(
+    name = "test_deps",
+    # keep sorted: for buildifier
+    artifacts = [
+        "@maven//:com.android.support.appcompat-v7_28.0.0",
+        "@maven//:com.android.support.constraint.constraint-layout_1.0.2",
+        "@maven//:com.android.support.test.espresso.espresso-core_3.0.2",
+        "@maven//:com.android.support.test.runner_1.0.2",
+        "@maven//:com.google.guava.guava_19.0",
+    ],
+)
diff --git a/execution/common/src/com/android/tools/idea/execution/common/applychanges/ApplyChangesAction.java b/execution/common/src/com/android/tools/idea/execution/common/applychanges/ApplyChangesAction.java
index 8b2f079..28ea4e7 100644
--- a/execution/common/src/com/android/tools/idea/execution/common/applychanges/ApplyChangesAction.java
+++ b/execution/common/src/com/android/tools/idea/execution/common/applychanges/ApplyChangesAction.java
@@ -17,7 +17,9 @@
 
 import static icons.StudioIcons.Shell.Toolbar.APPLY_ALL_CHANGES;
 
+import com.android.ddmlib.IDevice;
 import com.android.tools.idea.execution.common.AndroidExecutionTarget;
+import com.android.tools.idea.execution.common.AndroidSessionInfo;
 import com.android.tools.idea.execution.common.UtilsKt;
 import com.android.tools.idea.run.util.SwapInfo;
 import com.intellij.execution.ExecutionTargetManager;
@@ -32,7 +34,11 @@
 import com.intellij.openapi.actionSystem.Shortcut;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.SystemInfo;
+import com.intellij.xdebugger.XDebugSession;
+import com.intellij.xdebugger.XDebuggerManager;
+import java.util.Arrays;
 import java.util.List;
+import java.util.stream.Stream;
 import javax.swing.KeyStroke;
 import org.jetbrains.annotations.NotNull;
 
@@ -73,19 +79,22 @@
       return;
     }
 
-    // Disable "Apply Changes" for any kind of test project.
-    RunnerAndConfigurationSettings runConfig = RunManager.getInstance(project).getSelectedConfiguration();
     AndroidExecutionTarget selectedExecutionTarget = (AndroidExecutionTarget)ExecutionTargetManager.getActiveTarget(project);
 
-    final List<ProcessHandler> runningProcessHandlers =
-      UtilsKt.getProcessHandlersForDevices(runConfig, project, selectedExecutionTarget.getRunningDevices().stream().toList());
+    final List<IDevice> devices = selectedExecutionTarget.getRunningDevices().stream().toList();
 
-    final List<Executor> executors = getRunningExecutorsOfDifferentType(project, runningProcessHandlers);
+    final List<ProcessHandler> debugProcessHandlers =
+      Arrays.stream(XDebuggerManager.getInstance(project).getDebugSessions()).map(x -> x.getDebugProcess().getProcessHandler()).toList();
 
-    // otherwise should be disabled by [BaseAction].
-    assert executors.size() <= 1;
+    final boolean debuggerConnected = debugProcessHandlers.stream().anyMatch(processHandler -> {
+      final AndroidSessionInfo sessionInfo = AndroidSessionInfo.Companion.from(processHandler);
+      if (sessionInfo == null) {
+        return false;
+      }
+      return devices.stream().anyMatch(device -> sessionInfo.getDevices().contains(device));
+    });
 
-    if (!executors.isEmpty() && executors.get(0) == DefaultDebugExecutor.getDebugExecutorInstance()) {
+    if (debuggerConnected) {
       disableAction(e.getPresentation(), new DisableMessage(DisableMessage.DisableMode.DISABLED, "debug execution",
                                                             "it is currently not allowed during debugging"));
     }
diff --git a/execution/common/testSrc/com/android/tools/idea/execution/common/AndroidExecutionCommonTestSuite.java b/execution/common/testSrc/com/android/tools/idea/execution/common/AndroidExecutionCommonTestSuite.java
index ef32ebc..aa308e7 100644
--- a/execution/common/testSrc/com/android/tools/idea/execution/common/AndroidExecutionCommonTestSuite.java
+++ b/execution/common/testSrc/com/android/tools/idea/execution/common/AndroidExecutionCommonTestSuite.java
@@ -16,10 +16,28 @@
 package com.android.tools.idea.execution.common;
 
 import com.android.testutils.JarTestSuiteRunner;
+import com.android.tools.tests.GradleDaemonsRule;
 import com.android.tools.tests.IdeaTestSuiteBase;
+import com.intellij.ui.IconManager;
+import com.intellij.ui.icons.CoreIconManager;
+import org.junit.ClassRule;
 import org.junit.runner.RunWith;
 
 @RunWith(JarTestSuiteRunner.class)
 public class AndroidExecutionCommonTestSuite extends IdeaTestSuiteBase {
+  @ClassRule public static GradleDaemonsRule gradle = new GradleDaemonsRule();
 
+  static {
+    unzipIntoOfflineMavenRepo("tools/base/build-system/android_gradle_plugin.zip");
+    linkIntoOfflineMavenRepo("tools/base/build-system/android_gradle_plugin_runtime_dependencies.manifest");
+    linkIntoOfflineMavenRepo("tools/adt/idea/execution/common/test_deps.manifest");
+    linkIntoOfflineMavenRepo("tools/base/build-system/integration-test/kotlin_gradle_plugin_prebuilts.manifest");
+    // Avoid depending on the execution order and initializing icons with dummies.
+    try {
+      IconManager.Companion.activate(new CoreIconManager());
+    }
+    catch (Throwable e) {
+      e.printStackTrace();
+    }
+  }
 }
diff --git a/execution/common/testSrc/com/android/tools/idea/execution/common/applychanges/ApplyChangesActionTest.kt b/execution/common/testSrc/com/android/tools/idea/execution/common/applychanges/ApplyChangesActionTest.kt
new file mode 100644
index 0000000..6c9229a
--- /dev/null
+++ b/execution/common/testSrc/com/android/tools/idea/execution/common/applychanges/ApplyChangesActionTest.kt
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.execution.common.applychanges
+
+import com.android.ddmlib.Client
+import com.android.ddmlib.IDevice
+import com.android.sdklib.AndroidVersion
+import com.android.testutils.MockitoKt.mock
+import com.android.testutils.MockitoKt.whenever
+import com.android.tools.idea.execution.common.AndroidExecutionTarget
+import com.android.tools.idea.execution.common.AndroidSessionInfo
+import com.android.tools.idea.execution.common.debug.createFakeExecutionEnvironment
+import com.android.tools.idea.execution.common.processhandler.AndroidRemoteDebugProcessHandler
+import com.android.tools.idea.gradle.project.sync.snapshots.AndroidCoreTestProject
+import com.android.tools.idea.run.DeploymentApplicationService
+import com.android.tools.idea.testing.AndroidProjectRule
+import com.android.tools.idea.testing.onEdt
+import com.google.common.truth.Truth.assertThat
+import com.intellij.execution.ExecutionTargetManager
+import com.intellij.execution.RunManager
+import com.intellij.execution.configurations.RunConfiguration
+import com.intellij.openapi.actionSystem.CommonDataKeys
+import com.intellij.openapi.actionSystem.impl.SimpleDataContext
+import com.intellij.openapi.application.ApplicationManager
+import com.intellij.testFramework.RunsInEdt
+import com.intellij.testFramework.TestActionEvent
+import com.intellij.testFramework.replaceService
+import com.intellij.xdebugger.XDebugProcess
+import com.intellij.xdebugger.XDebugProcessStarter
+import com.intellij.xdebugger.XDebugSession
+import com.intellij.xdebugger.XDebuggerManager
+import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider
+import org.junit.Rule
+import org.junit.Test
+
+
+class ApplyChangesActionTest  {
+  @get:Rule
+  val projectRule = AndroidProjectRule.testProject(AndroidCoreTestProject.SIMPLE_APPLICATION).onEdt()
+
+  private val APPLICATION_ID = "google.simpleapplication"
+
+  @Test
+  @RunsInEdt
+  fun disabledDuringDebugSession() {
+    // Set up
+    val device = createMockDevice()
+    val service = mock<DeploymentApplicationService>().also {
+      whenever(it.findClient(device, APPLICATION_ID)).thenReturn(listOf(mock<Client>()))
+    }
+    ApplicationManager.getApplication()
+      .replaceService(DeploymentApplicationService::class.java, service, projectRule.testRootDisposable)
+    setTarget(device, RunManager.getInstance(projectRule.project).selectedConfiguration!!.configuration)
+
+    val client = mock<Client>()
+    whenever(client.device).thenReturn(device)
+
+    val debugProcessHandler = AndroidRemoteDebugProcessHandler(projectRule.project, client, false)
+    AndroidSessionInfo.create(debugProcessHandler, listOf(device), APPLICATION_ID)
+
+    val executionEnvironment = createFakeExecutionEnvironment(projectRule.project, "fake env")
+
+    // Start debug session
+    XDebuggerManager.getInstance(projectRule.project).startSession(executionEnvironment, object : XDebugProcessStarter() {
+      override fun start(session: XDebugSession) = object : XDebugProcess(session) {
+        override fun getEditorsProvider() = mock<XDebuggerEditorsProvider>()
+        override fun doGetProcessHandler() = debugProcessHandler
+      }
+    })
+
+    // Update
+    val action = ApplyChangesAction()
+    val event = TestActionEvent.createTestEvent(SimpleDataContext.getSimpleContext(CommonDataKeys.PROJECT, projectRule.project))
+    action.update(event)
+
+    // Assert
+    assertThat(event.presentation.isEnabled).isFalse()
+    assertThat(event.presentation.description).isEqualTo("Apply Changes and Restart Activity is disabled for this device because it is currently not allowed during debugging.")
+  }
+
+  private fun setTarget(device: IDevice, config: RunConfiguration) {
+    val executionTarget = object : AndroidExecutionTarget() {
+      override fun getId() = "Test Target"
+
+      override fun getDisplayName() = "Test Target"
+
+      override fun getIcon() = null
+
+      override fun getAvailableDeviceCount() = 1
+
+      override fun getRunningDevices() = listOf(device)
+    }
+
+    val executionTargetManager = mock<ExecutionTargetManager>()
+      .also {
+        whenever(it.activeTarget).thenReturn(executionTarget)
+        whenever(it.getTargetsFor(config)).thenReturn(listOf(executionTarget))
+      }
+    projectRule.project.replaceService(ExecutionTargetManager::class.java, executionTargetManager, projectRule.testRootDisposable)
+  }
+
+  private fun createMockDevice(): IDevice {
+    val mockDevice = mock<IDevice>()
+    whenever(mockDevice.isOnline).thenReturn(true)
+    whenever(mockDevice.version).thenReturn(AndroidVersion(33))
+    return mockDevice
+  }
+}
\ No newline at end of file
diff --git a/execution/common/testSrc/stats/RunStatsUtilsTest.kt b/execution/common/testSrc/stats/RunStatsUtilsTest.kt
index 991465f..55b0c00 100644
--- a/execution/common/testSrc/stats/RunStatsUtilsTest.kt
+++ b/execution/common/testSrc/stats/RunStatsUtilsTest.kt
@@ -54,7 +54,7 @@
     isRemote = true
     isVirtual = false
     icon = StudioDefaultDeviceIcons.handheld
-    populateDeviceInfoProto("TestPlugin", "localhost:12345", emptyMap())
+    populateDeviceInfoProto("TestPlugin", "localhost:12345", emptyMap(), "connectionId")
   }
   private val deviceHandle = object : DeviceHandle {
     override val scope: CoroutineScope
diff --git a/gradle-tooling/studio-gradle-tooling-impl/src/com/android/ide/gradle/model/artifacts/builder/AdditionalClassifierArtifactsModelBuilder.kt b/gradle-tooling/studio-gradle-tooling-impl/src/com/android/ide/gradle/model/artifacts/builder/AdditionalClassifierArtifactsModelBuilder.kt
index b9c70e3..bcf94b6 100644
--- a/gradle-tooling/studio-gradle-tooling-impl/src/com/android/ide/gradle/model/artifacts/builder/AdditionalClassifierArtifactsModelBuilder.kt
+++ b/gradle-tooling/studio-gradle-tooling-impl/src/com/android/ide/gradle/model/artifacts/builder/AdditionalClassifierArtifactsModelBuilder.kt
@@ -16,23 +16,24 @@
 package com.android.ide.gradle.model.artifacts.builder
 
 import com.android.ide.gradle.model.AdditionalClassifierArtifactsModelParameter
+import com.android.ide.gradle.model.ArtifactIdentifier
 import com.android.ide.gradle.model.ArtifactIdentifierImpl
-import com.android.ide.gradle.model.artifacts.AdditionalClassifierArtifacts
 import com.android.ide.gradle.model.artifacts.AdditionalClassifierArtifactsModel
 import com.android.ide.gradle.model.artifacts.AdditionalClassifierArtifactsModel.SAMPLE_SOURCE_CLASSIFIER
 import com.android.ide.gradle.model.artifacts.impl.AdditionalClassifierArtifactsImpl
 import com.android.ide.gradle.model.artifacts.impl.AdditionalClassifierArtifactsModelImpl
 import org.gradle.api.Project
+import org.gradle.api.artifacts.Dependency
 import org.gradle.api.artifacts.ModuleIdentifier
 import org.gradle.api.artifacts.component.ModuleComponentIdentifier
 import org.gradle.api.artifacts.result.ComponentArtifactsResult
 import org.gradle.api.artifacts.result.ResolvedArtifactResult
+import org.gradle.api.artifacts.type.ArtifactTypeDefinition
+import org.gradle.api.attributes.AttributeContainer
+import org.gradle.api.attributes.Category
 import org.gradle.api.attributes.DocsType
 import org.gradle.api.component.Artifact
 import org.gradle.internal.component.external.model.DefaultModuleComponentIdentifier
-import org.gradle.jvm.JvmLibrary
-import org.gradle.language.base.artifact.SourcesArtifact
-import org.gradle.language.java.artifact.JavadocArtifact
 import org.gradle.maven.MavenModule
 import org.gradle.maven.MavenPomArtifact
 import org.gradle.tooling.provider.model.ParameterizedToolingModelBuilder
@@ -59,8 +60,38 @@
   }
 
   override fun buildAll(modelName: String, parameter: AdditionalClassifierArtifactsModelParameter, project: Project): Any {
-    // Collect the components to download Sources and Javadoc for. DefaultModuleComponentIdentifier is the only supported type.
-    // See DefaultArtifactResolutionQuery::validateComponentIdentifier.
+    if (parameter.artifactIdentifiers.isEmpty()) {
+      return AdditionalClassifierArtifactsModelImpl(emptyList(), null)
+    }
+
+    try {
+      val idToPomFile = getPomFiles(parameter, project)
+      val idToJavadoc = getArtifacts(project, DocsType.JAVADOC, parameter.artifactIdentifiers)
+      val idToSources = getArtifacts(project, DocsType.SOURCES, parameter.artifactIdentifiers)
+      val idToSampleLocation = getSampleSources(parameter, project)
+
+      val artifacts = parameter.artifactIdentifiers.map {
+        val artifactId = ArtifactIdentifierImpl(it.groupId, it.artifactId, it.version)
+        AdditionalClassifierArtifactsImpl(
+          id = artifactId,
+          javadoc = idToJavadoc[artifactId],
+          sources = idToSources[artifactId],
+          mavenPom = idToPomFile[artifactId],
+          sampleSources = idToSampleLocation[artifactId],
+        )
+      }
+      return AdditionalClassifierArtifactsModelImpl(artifacts, null)
+    }
+    catch (t: Throwable) {
+      return AdditionalClassifierArtifactsModelImpl(emptyList(), "Unable to download sources/javadoc: " + t.message)
+    }
+  }
+
+  private fun getPomFiles(
+    parameter: AdditionalClassifierArtifactsModelParameter,
+    project: Project
+  ): Map<ArtifactIdentifierImpl, File?> {
+    // Create query for Maven Pom File.
     val ids = parameter.artifactIdentifiers.map {
       DefaultModuleComponentIdentifier(
         object : ModuleIdentifier {
@@ -70,82 +101,56 @@
       )
     }
 
-    var artifacts = emptyList<AdditionalClassifierArtifacts>()
-    var message: String? = null
+    val pomQuery = project.dependencies.createArtifactResolutionQuery()
+      .forComponents(ids)
+      .withArtifacts(MavenModule::class.java, MavenPomArtifact::class.java)
 
-    if (ids.isEmpty()) {
-      return AdditionalClassifierArtifactsModelImpl(artifacts, message)
+    fun getFile(result: ComponentArtifactsResult, clazz: Class<out Artifact>): File? {
+      return result.getArtifacts(clazz)
+        .filterIsInstance(ResolvedArtifactResult::class.java).firstOrNull()
+        ?.file
     }
 
-    try {
-      // Create query for Maven Pom File.
-      val pomQuery = project.dependencies.createArtifactResolutionQuery()
-        .forComponents(ids)
-        .withArtifacts(MavenModule::class.java, MavenPomArtifact::class.java)
-
-      // Map from component id to Pom File.
-      val idToPomFile = pomQuery.execute().resolvedComponents.map {
-        it.id.displayName to getFile(it, MavenPomArtifact::class.java)
-      }.toMap()
-
-      // Create map from component id to location of sample sources file.
-      val idToSampleLocation: Map<String, File?> =
-        if (parameter.downloadAndroidxUISamplesSources) {
-          getSampleSources(parameter, project)
-        }
-        else {
-          emptyMap()
-        }
-
-      // Create query for Javadoc and Sources.
-      val docQuery = project.dependencies.createArtifactResolutionQuery()
-        .forComponents(ids)
-        .withArtifacts(JvmLibrary::class.java, SourcesArtifact::class.java, JavadocArtifact::class.java)
-
-      artifacts = docQuery.execute().resolvedComponents.filter { it.id is ModuleComponentIdentifier }.map {
-        val id = it.id as ModuleComponentIdentifier
-        AdditionalClassifierArtifactsImpl(
-          ArtifactIdentifierImpl(id.group, id.module, id.version),
-          getFile(it, SourcesArtifact::class.java),
-          getFile(it, JavadocArtifact::class.java),
-          idToPomFile[it.id.displayName],
-          idToSampleLocation[it.id.displayName]
-        )
-      }
+    // Map from component id to Pom File.
+    return pomQuery.execute().resolvedComponents.associate {
+      val id = it.id as ModuleComponentIdentifier
+      ArtifactIdentifierImpl(id.group, id.module, id.version) to getFile(it, MavenPomArtifact::class.java)
     }
-    catch (t: Throwable) {
-      message = "Unable to download sources/javadoc: " + t.message
-    }
-    return AdditionalClassifierArtifactsModelImpl(artifacts, message)
   }
 
-  private fun getSampleSources(parameter: AdditionalClassifierArtifactsModelParameter, project: Project): Map<String, File?> {
-    val detachedConfiguration = project.configurations.detachedConfiguration()
-    parameter.artifactIdentifiers
-      // Only androidx.ui and androidx.compose use the @Sampled annotation as of today (January 2020).
+  private fun getArtifacts(project: Project,
+                           docsType: String,
+                           artifactIdentifiers: Collection<ArtifactIdentifier>): Map<ArtifactIdentifierImpl, File> {
+    val resolvableConfiguration = project.configurations.detachedConfiguration().also {
+      it.attributes.run<AttributeContainer, Unit> {
+        attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category::class.java, Category.DOCUMENTATION))
+        attribute(ArtifactTypeDefinition.ARTIFACT_TYPE_ATTRIBUTE, ArtifactTypeDefinition.JAR_TYPE)
+        attribute(DocsType.DOCS_TYPE_ATTRIBUTE, project.objects.named(DocsType::class.java, docsType))
+      }
+    }
+    artifactIdentifiers.asDependencies(project).forEach {
+      resolvableConfiguration.dependencies.add(it)
+    }
+    return resolvableConfiguration.incoming.artifactView { view ->
+      view.lenient(true)
+      view.componentFilter { it is ModuleComponentIdentifier }
+    }.artifacts.associate {
+      val id = it.id.componentIdentifier as ModuleComponentIdentifier
+      ArtifactIdentifierImpl(id.group, id.module, id.version) to it.file
+    }
+  }
+
+  private fun getSampleSources(parameter: AdditionalClassifierArtifactsModelParameter, project: Project): Map<ArtifactIdentifierImpl, File> {
+    if (!parameter.downloadAndroidxUISamplesSources) return emptyMap()
+
+    // Only androidx.ui and androidx.compose use the @Sampled annotation as of today (January 2020).
+    val artifactsWithSamples = parameter.artifactIdentifiers
       .filter { it.groupId.startsWith("androidx.ui") || it.groupId.startsWith("androidx.compose") }
-      .forEach {
-        val dependency = project.dependencies.create(it.groupId + ":" + it.artifactId + ":" + it.version)
-        detachedConfiguration.dependencies.add(dependency)
-      }
-    detachedConfiguration.attributes.attribute(
-      DocsType.DOCS_TYPE_ATTRIBUTE,
-      project.objects.named(DocsType::class.java, SAMPLE_SOURCE_CLASSIFIER))
 
-    val samples = mutableMapOf<String, File?>()
-
-    detachedConfiguration.incoming.artifactView {
-      it.lenient(true) // this will make it not fail if something does not have samples
-    }.artifacts.forEach {
-      val id = it.id.componentIdentifier.displayName
-      samples[id] = it.file
-    }
-    return samples
+    return getArtifacts(project, SAMPLE_SOURCE_CLASSIFIER, artifactsWithSamples)
   }
 
-  private fun getFile(result: ComponentArtifactsResult, clazz: Class<out Artifact>): File? {
-    return result.getArtifacts(clazz)
-      .filterIsInstance(ResolvedArtifactResult::class.java).firstOrNull()
-      ?.file
+  private fun Collection<ArtifactIdentifier>.asDependencies(project: Project): Sequence<Dependency> {
+    return asSequence().map { project.dependencies.create(it.groupId + ":" + it.artifactId + ":" + it.version) }
   }
 }
\ No newline at end of file
diff --git a/kotlin-integration/testSrc/com/android/tools/idea/KotlinPluginTest.kt b/kotlin-integration/testSrc/com/android/tools/idea/KotlinPluginTest.kt
index cb48dec..29096c8 100644
--- a/kotlin-integration/testSrc/com/android/tools/idea/KotlinPluginTest.kt
+++ b/kotlin-integration/testSrc/com/android/tools/idea/KotlinPluginTest.kt
@@ -17,6 +17,7 @@
 
 import com.google.common.truth.Truth.assertThat
 import com.intellij.ide.plugins.IdeaPluginDescriptor
+import com.intellij.ide.plugins.PluginManager
 import com.intellij.ide.plugins.PluginManagerCore
 import com.intellij.openapi.application.ex.ApplicationInfoEx
 import com.intellij.openapi.extensions.PluginId
@@ -25,6 +26,7 @@
 import org.jetbrains.kotlin.idea.compiler.configuration.KotlinIdePluginVersion
 import org.jetbrains.kotlin.idea.compiler.configuration.KotlinPluginLayout
 import org.junit.ClassRule
+import org.junit.Ignore
 import org.junit.Test
 
 class KotlinPluginTest {
@@ -69,4 +71,15 @@
     assertThat(apiVersion.asStringWithoutProductCode()).matches("\\d+\\.\\d+\\.\\d+")
     assertThat(PluginManagerCore.checkBuildNumberCompatibility(plugin, apiVersion)).isNull()
   }
+
+  @Test
+  @Ignore("Cannot accurately run in Bazel until b/270757509 is fixed")
+  fun testPluginCannotBeDisabled() {
+    val id = "org.jetbrains.kotlin"
+    val plugin = PluginManagerCore.getPlugin(PluginId.getId(id))
+    checkNotNull(plugin)
+    assertThat(plugin.isEnabled).isTrue()
+    PluginManager.disablePlugin(id)
+    assertThat(plugin.isEnabled).isTrue()
+  }
 }
diff --git a/layout-inspector/src/com/android/tools/idea/layoutinspector/LayoutInspectorProjectService.kt b/layout-inspector/src/com/android/tools/idea/layoutinspector/LayoutInspectorProjectService.kt
index 21eced3..8d77b54 100644
--- a/layout-inspector/src/com/android/tools/idea/layoutinspector/LayoutInspectorProjectService.kt
+++ b/layout-inspector/src/com/android/tools/idea/layoutinspector/LayoutInspectorProjectService.kt
@@ -35,9 +35,11 @@
 import com.android.tools.idea.layoutinspector.pipeline.foregroundprocessdetection.ForegroundProcessDetectionInitializer
 import com.android.tools.idea.layoutinspector.settings.LayoutInspectorSettings
 import com.android.tools.idea.layoutinspector.tree.InspectorTreeSettings
+import com.android.tools.idea.transport.manager.TransportStreamManagerService
 import com.google.common.annotations.VisibleForTesting
 import com.intellij.openapi.Disposable
 import com.intellij.openapi.application.ApplicationManager
+import com.intellij.openapi.components.service
 import com.intellij.openapi.project.Project
 import com.intellij.openapi.util.Disposer
 import com.intellij.util.concurrency.EdtExecutorService
@@ -187,6 +189,7 @@
         processModel = processesModel,
         deviceModel = deviceModel,
         coroutineScope = coroutineScope,
+        streamManager = service<TransportStreamManagerService>().streamManager,
         metrics = ForegroundProcessDetectionMetrics
       )
     } else {
diff --git a/layout-inspector/src/com/android/tools/idea/layoutinspector/pipeline/foregroundprocessdetection/ForegroundProcessDetectionImpl.kt b/layout-inspector/src/com/android/tools/idea/layoutinspector/pipeline/foregroundprocessdetection/ForegroundProcessDetectionImpl.kt
index 367ce2b..7b05b60 100644
--- a/layout-inspector/src/com/android/tools/idea/layoutinspector/pipeline/foregroundprocessdetection/ForegroundProcessDetectionImpl.kt
+++ b/layout-inspector/src/com/android/tools/idea/layoutinspector/pipeline/foregroundprocessdetection/ForegroundProcessDetectionImpl.kt
@@ -116,6 +116,7 @@
   private val layoutInspectorMetrics: LayoutInspectorMetrics,
   private val metrics: ForegroundProcessDetectionMetrics,
   private val scope: CoroutineScope,
+  private val streamManager: TransportStreamManager,
   workDispatcher: CoroutineDispatcher = AndroidDispatchers.workerThread,
   @TestOnly private val onDeviceDisconnected: (DeviceDescriptor) -> Unit = {},
   @TestOnly private val pollingIntervalMs: Long = 2000
@@ -222,11 +223,8 @@
       }
     }
 
-    val manager =
-      TransportStreamManager.createManager(transportClient.transportStub, workDispatcher)
-
     scope.launch {
-      manager.streamActivityFlow().collect { activity ->
+      streamManager.streamActivityFlow().collect { activity ->
         val streamChannel = activity.streamChannel
         val streamDevice = streamChannel.stream.device.toDeviceDescriptor()
         val stream = streamChannel.stream
@@ -453,12 +451,8 @@
    *
    * @see ForegroundProcessDetectionImpl.deviceModels
    */
-  private fun shouldStopPollingDevice(selectedDevice: DeviceDescriptor): Boolean {
-    val deviceModels = ForegroundProcessDetectionImpl.deviceModels
-    val count =
-      deviceModels.mapNotNull { it.selectedDevice }.count { it.serial == selectedDevice.serial }
-    return count <= 1
-  }
+  private fun shouldStopPollingDevice(selectedDevice: DeviceDescriptor) =
+    deviceModels.mapNotNull { it.selectedDevice }.count { it.serial == selectedDevice.serial } <= 1
 
   /**
    * Initiates a new handshake. Only if [device] already executed the handshake that happens at
diff --git a/layout-inspector/src/com/android/tools/idea/layoutinspector/pipeline/foregroundprocessdetection/ForegroundProcessDetectionInitializer.kt b/layout-inspector/src/com/android/tools/idea/layoutinspector/pipeline/foregroundprocessdetection/ForegroundProcessDetectionInitializer.kt
index 3a70287..e4e3397 100644
--- a/layout-inspector/src/com/android/tools/idea/layoutinspector/pipeline/foregroundprocessdetection/ForegroundProcessDetectionInitializer.kt
+++ b/layout-inspector/src/com/android/tools/idea/layoutinspector/pipeline/foregroundprocessdetection/ForegroundProcessDetectionInitializer.kt
@@ -21,6 +21,7 @@
 import com.android.tools.idea.layoutinspector.metrics.LayoutInspectorMetrics
 import com.android.tools.idea.transport.TransportClient
 import com.android.tools.idea.transport.TransportService
+import com.android.tools.idea.transport.manager.TransportStreamManager
 import com.intellij.openapi.diagnostic.Logger
 import com.intellij.openapi.project.Project
 import kotlinx.coroutines.CoroutineScope
@@ -84,6 +85,7 @@
     processModel: ProcessesModel,
     deviceModel: DeviceModel,
     coroutineScope: CoroutineScope,
+    streamManager: TransportStreamManager,
     foregroundProcessListener: ForegroundProcessListener =
       getDefaultForegroundProcessListener(deviceModel, processModel),
     transportClient: TransportClient = getDefaultTransportClient(),
@@ -98,7 +100,8 @@
         transportClient,
         layoutInspectorMetrics,
         metrics,
-        coroutineScope
+        coroutineScope,
+        streamManager
       )
 
     foregroundProcessDetection.addForegroundProcessListener(foregroundProcessListener)
diff --git a/layout-inspector/src/com/android/tools/idea/layoutinspector/runningdevices/LayoutInspectorManager.kt b/layout-inspector/src/com/android/tools/idea/layoutinspector/runningdevices/LayoutInspectorManager.kt
index 91f6e3e..7880159 100644
--- a/layout-inspector/src/com/android/tools/idea/layoutinspector/runningdevices/LayoutInspectorManager.kt
+++ b/layout-inspector/src/com/android/tools/idea/layoutinspector/runningdevices/LayoutInspectorManager.kt
@@ -139,7 +139,7 @@
         // Dispose to trigger clean up.
         Disposer.dispose(previousTab.tabComponents)
 
-        previousTab.layoutInspector.deviceModel?.selectedDevice = null
+        previousTab.layoutInspector.stopInspector()
       }
 
       field = value
diff --git a/layout-inspector/testSrc/com/android/tools/idea/layoutinspector/pipeline/foregroundprocessdetection/ForegroundProcessDetectionInitializerTest.kt b/layout-inspector/testSrc/com/android/tools/idea/layoutinspector/pipeline/foregroundprocessdetection/ForegroundProcessDetectionInitializerTest.kt
index fb5447d..2855d9c 100644
--- a/layout-inspector/testSrc/com/android/tools/idea/layoutinspector/pipeline/foregroundprocessdetection/ForegroundProcessDetectionInitializerTest.kt
+++ b/layout-inspector/testSrc/com/android/tools/idea/layoutinspector/pipeline/foregroundprocessdetection/ForegroundProcessDetectionInitializerTest.kt
@@ -30,6 +30,7 @@
 import com.android.tools.idea.transport.faketransport.FakeGrpcServer
 import com.android.tools.idea.transport.faketransport.FakeTransportService
 import com.android.tools.idea.transport.faketransport.commands.CommandHandler
+import com.android.tools.idea.transport.manager.TransportStreamManagerRule
 import com.android.tools.profiler.proto.Commands
 import com.android.tools.profiler.proto.Common
 import com.google.common.truth.Truth.assertThat
@@ -43,17 +44,20 @@
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
+import org.junit.rules.RuleChain
 
 class ForegroundProcessDetectionInitializerTest {
   private val timer = FakeTimer()
   private val transportService = FakeTransportService(timer, false)
 
-  @get:Rule
-  val grpcServerRule =
+  private val grpcServerRule =
     FakeGrpcServer.createFakeGrpcServer(
       "ForegroundProcessDetectionInitializerTest",
       transportService
     )
+  private val streamManagerRule = TransportStreamManagerRule(grpcServerRule)
+
+  @get:Rule val ruleChain = RuleChain.outerRule(grpcServerRule).around(streamManagerRule)
 
   private val device1 = FakeDevice(serial = "1")
   private val device2 = FakeDevice(serial = "2")
@@ -104,6 +108,7 @@
       processModel = processModel,
       deviceModel = deviceModel,
       coroutineScope = CoroutineScope(SameThreadExecutor.INSTANCE.asCoroutineDispatcher()),
+      streamManager = streamManagerRule.streamManager,
       foregroundProcessListener = foregroundProcessListener,
       metrics = ForegroundProcessDetectionMetrics,
     )
@@ -191,7 +196,8 @@
       project = projectRule.project,
       processModel = processModel,
       deviceModel = deviceModel,
-      coroutineScope = projectRule.project.coroutineScope,
+      coroutineScope = CoroutineScope(SameThreadExecutor.INSTANCE.asCoroutineDispatcher()),
+      streamManager = streamManagerRule.streamManager,
       transportClient = transportClient,
       metrics = ForegroundProcessDetectionMetrics,
     )
diff --git a/layout-inspector/testSrc/com/android/tools/idea/layoutinspector/pipeline/foregroundprocessdetection/ForegroundProcessDetectionTest.kt b/layout-inspector/testSrc/com/android/tools/idea/layoutinspector/pipeline/foregroundprocessdetection/ForegroundProcessDetectionTest.kt
index b0b2a24..d2a7566 100644
--- a/layout-inspector/testSrc/com/android/tools/idea/layoutinspector/pipeline/foregroundprocessdetection/ForegroundProcessDetectionTest.kt
+++ b/layout-inspector/testSrc/com/android/tools/idea/layoutinspector/pipeline/foregroundprocessdetection/ForegroundProcessDetectionTest.kt
@@ -31,16 +31,17 @@
 import com.android.tools.idea.layoutinspector.pipeline.adb.AdbDebugViewProperties
 import com.android.tools.idea.layoutinspector.pipeline.adb.FakeShellCommandHandler
 import com.android.tools.idea.layoutinspector.pipeline.appinspection.DebugViewAttributes
+import com.android.tools.idea.testing.disposable
 import com.android.tools.idea.transport.TransportClient
 import com.android.tools.idea.transport.faketransport.FakeGrpcServer
 import com.android.tools.idea.transport.faketransport.FakeTransportService
 import com.android.tools.idea.transport.faketransport.commands.CommandHandler
+import com.android.tools.idea.transport.manager.TransportStreamManagerRule
 import com.android.tools.profiler.proto.Commands.Command
 import com.android.tools.profiler.proto.Common
 import com.google.common.truth.Truth.assertThat
 import com.google.wireless.android.sdk.stats.DynamicLayoutInspectorTransportError
 import com.intellij.openapi.util.Disposer
-import com.intellij.testFramework.DisposableRule
 import com.intellij.testFramework.ProjectRule
 import com.intellij.util.containers.reverse
 import java.util.concurrent.atomic.AtomicLong
@@ -63,24 +64,24 @@
 import org.mockito.Mockito.verifyNoMoreInteractions
 
 class ForegroundProcessDetectionTest {
-  @get:Rule val disposableRule = DisposableRule()
-
   private val projectRule = ProjectRule()
-
   private val adbRule = FakeAdbRule()
   private val adbProperties: AdbDebugViewProperties =
     FakeShellCommandHandler().apply { adbRule.withDeviceCommandHandler(this) }
   private val adbService = AdbServiceRule(projectRule::project, adbRule)
-
-  @get:Rule
-  val ruleChain: RuleChain = RuleChain.outerRule(projectRule).around(adbRule).around(adbService)
-
   private val timer = FakeTimer()
   private val transportService = FakeTransportService(timer, false)
+  private val grpcServerRule =
+    FakeGrpcServer.createFakeGrpcServer("ForegroundProcessDetectionTest", transportService)
+  private val streamManagerRule = TransportStreamManagerRule(grpcServerRule)
 
   @get:Rule
-  val grpcServerRule =
-    FakeGrpcServer.createFakeGrpcServer("ForegroundProcessDetectionTest", transportService)
+  val ruleChain: RuleChain =
+    RuleChain.outerRule(projectRule)
+      .around(adbRule)
+      .around(adbService)
+      .around(grpcServerRule)
+      .around(streamManagerRule)
 
   private val timestampGenerator = AtomicLong()
 
@@ -171,7 +172,7 @@
     workDispatcher = AndroidDispatchers.workerThread
     transportClient = TransportClient(grpcServerRule.name)
 
-    coroutineScope = AndroidCoroutineScope(disposableRule.disposable)
+    coroutineScope = AndroidCoroutineScope(projectRule.disposable)
 
     // mock device response to handshake command
     transportService.setCommandHandler(
@@ -228,6 +229,7 @@
         mock(),
         mock(),
         coroutineScope,
+        streamManagerRule.streamManager,
         workDispatcher,
         onDeviceDisconnected = {},
         pollingIntervalMs = 500L
@@ -271,8 +273,8 @@
     val (deviceModel1, processModel1) = createDeviceModel(device1)
     val (deviceModel2, processModel2) = createDeviceModel(device1)
 
-    val coroutineScope1 = AndroidCoroutineScope(disposableRule.disposable)
-    val coroutineScope2 = AndroidCoroutineScope(disposableRule.disposable)
+    val coroutineScope1 = AndroidCoroutineScope(projectRule.disposable)
+    val coroutineScope2 = AndroidCoroutineScope(projectRule.disposable)
 
     // studio1
     val foregroundProcessDetection1 =
@@ -284,6 +286,7 @@
         mock(),
         mock(),
         coroutineScope1,
+        streamManagerRule.streamManager,
         workDispatcher,
         onDeviceDisconnected = {},
         pollingIntervalMs = 500L
@@ -299,6 +302,7 @@
         mock(),
         mock(),
         coroutineScope2,
+        streamManagerRule.streamManager,
         workDispatcher,
         onDeviceDisconnected = {},
         pollingIntervalMs = 500L
@@ -360,6 +364,7 @@
         mock(),
         mock(),
         coroutineScope,
+        streamManagerRule.streamManager,
         workDispatcher,
         onDeviceDisconnected = {},
         pollingIntervalMs = 500L
@@ -415,6 +420,7 @@
         mock(),
         mock(),
         coroutineScope,
+        streamManagerRule.streamManager,
         workDispatcher,
         onDeviceDisconnected = {},
         pollingIntervalMs = 500L
@@ -459,6 +465,7 @@
         mock(),
         mock(),
         coroutineScope,
+        streamManagerRule.streamManager,
         workDispatcher,
         onDeviceDisconnected = {},
         pollingIntervalMs = 500L
@@ -553,6 +560,7 @@
         mock(),
         mock(),
         coroutineScope,
+        streamManagerRule.streamManager,
         workDispatcher,
         onDeviceDisconnected,
         pollingIntervalMs = 500L
@@ -592,6 +600,7 @@
         mock(),
         mock(),
         coroutineScope,
+        streamManagerRule.streamManager,
         workDispatcher,
         onDeviceDisconnected = {},
         pollingIntervalMs = 500L
@@ -683,6 +692,7 @@
         mock(),
         mock(),
         coroutineScope,
+        streamManagerRule.streamManager,
         workDispatcher,
         onDeviceDisconnected = {},
         pollingIntervalMs = 500L
@@ -763,6 +773,7 @@
         mock(),
         mock(),
         coroutineScope,
+        streamManagerRule.streamManager,
         workDispatcher,
         onDeviceDisconnected = {},
         pollingIntervalMs = 500L
@@ -804,6 +815,7 @@
         mock(),
         mock(),
         coroutineScope,
+        streamManagerRule.streamManager,
         workDispatcher,
         onDeviceDisconnected = {},
         pollingIntervalMs = 500L
@@ -868,6 +880,7 @@
       layoutInspectorMetrics,
       mock(),
       coroutineScope,
+      streamManagerRule.streamManager,
       workDispatcher,
       onDeviceDisconnected = onDeviceDisconnected,
       pollingIntervalMs = 500L
@@ -933,6 +946,7 @@
         mock(),
         mock(),
         coroutineScope,
+        streamManagerRule.streamManager,
         workDispatcher,
         onDeviceDisconnected = {},
         pollingIntervalMs = 500L
@@ -978,6 +992,7 @@
         mock(),
         mock(),
         coroutineScope,
+        streamManagerRule.streamManager,
         workDispatcher,
         onDeviceDisconnected = {},
         pollingIntervalMs = 500L
@@ -1080,7 +1095,7 @@
   ): Pair<DeviceModel, ProcessesModel> {
     devices.forEach { testProcessDiscovery.addDevice(it.toDeviceDescriptor()) }
     val processModel = ProcessesModel(testProcessDiscovery)
-    return DeviceModel(disposableRule.disposable, processModel) to processModel
+    return DeviceModel(projectRule.disposable, processModel) to processModel
   }
 
   private fun createForegroundProcessEvent(
diff --git a/lint/BUILD b/lint/BUILD
index dceb166..b5db901 100644
--- a/lint/BUILD
+++ b/lint/BUILD
@@ -23,12 +23,13 @@
 # managed by go/iml_to_build
 iml_module(
     name = "intellij.lint.tests",
+    generate_k2_tests = True,
     iml_files = ["tests/intellij.lint.tests.iml"],
     test_class = "com.android.tools.idea.lint.common.LintIdeTestSuite",
     test_data = [
+        "//tools/adt/idea/android/annotations",
         "//tools/adt/idea/android/testData",
         "//tools/adt/idea/lint/tests/testData",
-        "//tools/adt/idea/android/annotations",
     ],
     test_resources = ["tests/testData"],
     test_srcs = ["tests/testSrc"],
diff --git a/lint/tests/testSrc/com/android/tools/idea/lint/common/AnnotateQuickFixTest.kt b/lint/tests/testSrc/com/android/tools/idea/lint/common/AnnotateQuickFixTest.kt
index 06b89aa..12a4948 100644
--- a/lint/tests/testSrc/com/android/tools/idea/lint/common/AnnotateQuickFixTest.kt
+++ b/lint/tests/testSrc/com/android/tools/idea/lint/common/AnnotateQuickFixTest.kt
@@ -18,9 +18,9 @@
 import com.intellij.openapi.command.WriteCommandAction
 import com.intellij.psi.PsiElement
 import com.intellij.refactoring.suggested.startOffset
-import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase
+import org.jetbrains.android.JavaCodeInsightFixtureAdtTestCase
 
-class AnnotateQuickFixTest : JavaCodeInsightFixtureTestCase() {
+class AnnotateQuickFixTest : JavaCodeInsightFixtureAdtTestCase() {
 
   fun testKotlinAnnotationArgs() {
     val file =
diff --git a/lint/tests/testSrc/com/android/tools/idea/lint/common/LintIdeTest.kt b/lint/tests/testSrc/com/android/tools/idea/lint/common/LintIdeTest.kt
index e9d984a..2bf082c 100644
--- a/lint/tests/testSrc/com/android/tools/idea/lint/common/LintIdeTest.kt
+++ b/lint/tests/testSrc/com/android/tools/idea/lint/common/LintIdeTest.kt
@@ -263,12 +263,17 @@
   }
 
   fun testDisabledTestsEnabledOnTheFly() {
-    // If this changes test no longer applies; pick different disabled issue
-    /* b/214265385
-        assertThat(CommentDetector.STOP_SHIP.isEnabledByDefault()).isFalse()
-    b/214265385 */
-    myFixture.copyFileToProject("$globalTestDir/Stopship.java", "src/p1/p2/Stopship.java")
-    doGlobalInspectionTest(AndroidLintStopShipInspection())
+    // Verifies that inspections are force-enabled when the IDE inspection profile mentions them.
+    val wasEnabled = CommentDetector.STOP_SHIP.isEnabledByDefault()
+    try {
+      CommentDetector.STOP_SHIP.setEnabledByDefault(false)
+      myFixture.copyFileToProject("$globalTestDir/Stopship.java", "src/p1/p2/Stopship.java")
+      doGlobalInspectionTest(AndroidLintStopShipInspection())
+      assertThat(CommentDetector.STOP_SHIP.isEnabledByDefault()).isTrue()
+    }
+    finally {
+      CommentDetector.STOP_SHIP.setEnabledByDefault(wasEnabled)
+    }
   }
 
   fun testGradleWindows() {
diff --git a/lint/tests/testSrc/com/android/tools/idea/lint/common/ReplaceStringQuickFixTest.kt b/lint/tests/testSrc/com/android/tools/idea/lint/common/ReplaceStringQuickFixTest.kt
index a62ef93..2a60a7b 100644
--- a/lint/tests/testSrc/com/android/tools/idea/lint/common/ReplaceStringQuickFixTest.kt
+++ b/lint/tests/testSrc/com/android/tools/idea/lint/common/ReplaceStringQuickFixTest.kt
@@ -15,20 +15,15 @@
  */
 package com.android.tools.idea.lint.common
 
-import com.android.testutils.TestUtils
 import com.android.tools.lint.detector.api.LintFix
 import com.intellij.openapi.command.WriteCommandAction
 import com.intellij.psi.PsiDocumentManager
 import com.intellij.psi.PsiJavaFile
 import com.intellij.psi.PsiManager
-import com.intellij.testFramework.builders.JavaModuleFixtureBuilder
-import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase
 import com.intellij.util.ThrowableRunnable
+import org.jetbrains.android.JavaCodeInsightFixtureAdtTestCase
 
-class ReplaceStringQuickFixTest : JavaCodeInsightFixtureTestCase() {
-  override fun tuneFixture(builder: JavaModuleFixtureBuilder<*>) {
-    builder.addJdk(TestUtils.getMockJdk().toString())
-  }
+class ReplaceStringQuickFixTest : JavaCodeInsightFixtureAdtTestCase() {
 
   fun testImportsJava() {
     // Unit test for [ReplaceStringQuickFix] import handling of Java files.
diff --git a/logcat/testSrc/com/android/tools/idea/logcat/testing/TestDevice.kt b/logcat/testSrc/com/android/tools/idea/logcat/testing/TestDevice.kt
index 91ddf9e..5c4edd4 100644
--- a/logcat/testSrc/com/android/tools/idea/logcat/testing/TestDevice.kt
+++ b/logcat/testSrc/com/android/tools/idea/logcat/testing/TestDevice.kt
@@ -54,7 +54,7 @@
           makeAvdInfo(avdName, manufacturer, model, AndroidVersion(sdk))
         ) {
           icon = StudioIcons.DeviceExplorer.PHYSICAL_DEVICE_PHONE
-          populateDeviceInfoProto("Test", null, emptyMap())
+          populateDeviceInfoProto("Test", null, emptyMap(), "connectionId")
         }
       else ->
         DeviceProperties.buildForTest {
diff --git a/mlkit/BUILD b/mlkit/BUILD
index 178833a..cf7dfca 100644
--- a/mlkit/BUILD
+++ b/mlkit/BUILD
@@ -36,6 +36,7 @@
 # managed by go/iml_to_build
 iml_module(
     name = "intellij.android.mlkit.tests",
+    generate_k2_tests = True,
     iml_files = ["intellij.android.mlkit.tests.iml"],
     tags = [
         "no_test_windows",  # b/135665870
diff --git a/mlkit/testSrc/com/android/tools/idea/mlkit/MlProjectTestUtil.java b/mlkit/testSrc/com/android/tools/idea/mlkit/MlProjectTestUtil.java
index ddc7cb6..76205e7 100644
--- a/mlkit/testSrc/com/android/tools/idea/mlkit/MlProjectTestUtil.java
+++ b/mlkit/testSrc/com/android/tools/idea/mlkit/MlProjectTestUtil.java
@@ -23,6 +23,8 @@
 import com.android.tools.idea.gradle.model.impl.IdeSourceProviderImpl;
 import com.android.tools.idea.testing.AndroidModuleModelBuilder;
 import com.android.tools.idea.testing.AndroidProjectBuilder;
+import com.android.tools.idea.testing.JavaLibraryDependency;
+import com.android.tools.tests.AdtTestKotlinArtifacts;
 import com.google.common.collect.ImmutableList;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.io.FileUtil;
@@ -51,6 +53,18 @@
           .withMinSdk(it -> minSdk)
           .withMlModelBindingEnabled(it -> true)
           .withNamespace("p1.p2")
+          .withJavaLibraryDependencyList(
+            // TODO(b/300170256): Remove this once 2023.3 merges and we no longer need kotlin-stdlib for every Kotlin test.
+            (it, variant) -> {
+              // NB: yes, this is fragile, depending on test name pattern that ends with "kotlin" suffix.
+              //  But, it's still helpful to avoid unnecessary lib loading for all other tests.
+              if (it.getProjectName().endsWith("kotlin")) {
+                return ImmutableList.of(JavaLibraryDependency.Companion.forJar(AdtTestKotlinArtifacts.INSTANCE.getKotlinStdlib()));
+              } else {
+                return ImmutableList.of();
+              }
+            }
+          )
           .withMainSourceProvider(it -> new IdeSourceProviderImpl(
             ARTIFACT_NAME_MAIN,
             it.getModuleBasePath(),
diff --git a/nav/editor/lint_baseline.xml b/nav/editor/lint_baseline.xml
index ed1eea1..379fb70 100644
--- a/nav/editor/lint_baseline.xml
+++ b/nav/editor/lint_baseline.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<issues format="5" by="lint 8.2.0-dev">
+<issues format="5" by="lint 8.3.0-dev">
 
     <issue
         id="DefaultLocale"
         message="Implicitly using the default locale is a common source of bugs: Use `toLowerCase(Locale)` instead. For strings meant to be internal use `Locale.ROOT`, otherwise `Locale.getDefault()`.">
         <location
             file="src/com/android/tools/idea/naveditor/editor/AddDestinationMenu.kt"
-            line="329"/>
+            line="327"/>
     </issue>
 
     <issue
@@ -1331,6 +1331,14 @@
 
     <issue
         id="VisibleForTests"
+        message="This class should only be accessed from tests or within private scope">
+        <location
+            file="src/com/android/tools/idea/naveditor/analytics/NavUsageTracker.kt"
+            line="36"/>
+    </issue>
+
+    <issue
+        id="VisibleForTests"
         message="This method should only be accessed from tests or within private scope">
         <location
             file="src/com/android/tools/idea/naveditor/analytics/NavUsageTracker.kt"
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/SafeArgsMode.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/SafeArgsMode.kt
index b303df9..a3d4dae 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/SafeArgsMode.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/SafeArgsMode.kt
@@ -23,23 +23,16 @@
 import org.jetbrains.annotations.TestOnly
 
 enum class SafeArgsMode {
-  /**
-   * Safe Args is not enabled for this module.
-   */
+  /** Safe Args is not enabled for this module. */
   NONE,
 
-  /**
-   * Safe Args is enabled for this module and will generate Java classes.
-   */
+  /** Safe Args is enabled for this module and will generate Java classes. */
   JAVA,
 
-  /**
-   * Safe Args is enabled for this module and will generate Kotlin classes.
-   */
+  /** Safe Args is enabled for this module and will generate Kotlin classes. */
   KOTLIN,
 }
 
-
 var AndroidFacet.safeArgsMode: SafeArgsMode
   get() = SafeArgsModeModuleService.getInstance(module).safeArgsMode
   /**
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/cache/ActionBuilderShortNamesCache.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/cache/ActionBuilderShortNamesCache.kt
index bb1f611..8c49d0b 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/cache/ActionBuilderShortNamesCache.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/cache/ActionBuilderShortNamesCache.kt
@@ -32,7 +32,8 @@
 import com.intellij.util.Processor
 
 /**
- * A short names cache for finding any [LightActionBuilderClass] instances by their unqualified name.
+ * A short names cache for finding any [LightActionBuilderClass] instances by their unqualified
+ * name.
  */
 class ActionBuilderShortNamesCache(project: Project) : PsiShortNamesCache() {
   private val enabledFacetsProvider = SafeArgsEnabledFacetsProjectService.getInstance(project)
@@ -41,21 +42,28 @@
   init {
     val cachedValuesManager = CachedValuesManager.getManager(project)
 
-    lightClassesCache = cachedValuesManager.createCachedValue {
-      val builders = enabledFacetsProvider.modulesUsingSafeArgs
-        .asSequence()
-        .flatMap { facet -> SafeArgsCacheModuleService.getInstance(facet).directions.asSequence() }
-        .flatMap { it.innerClasses.asSequence() }
-        .filterIsInstance<LightActionBuilderClass>()
-        .toList()
+    lightClassesCache =
+      cachedValuesManager.createCachedValue {
+        val builders =
+          enabledFacetsProvider.modulesUsingSafeArgs
+            .asSequence()
+            .flatMap { facet ->
+              SafeArgsCacheModuleService.getInstance(facet).directions.asSequence()
+            }
+            .flatMap { it.innerClasses.asSequence() }
+            .filterIsInstance<LightActionBuilderClass>()
+            .toList()
 
-      CachedValueProvider.Result.create(builders,
-                                        ProjectNavigationResourceModificationTracker.getInstance(project),
-                                        project.safeArgsModeTracker)
-    }
+        CachedValueProvider.Result.create(
+          builders,
+          ProjectNavigationResourceModificationTracker.getInstance(project),
+          project.safeArgsModeTracker
+        )
+      }
   }
 
-  override fun getAllClassNames(): Array<String> = lightClassesCache.value.mapNotNull { it.name }.toTypedArray()
+  override fun getAllClassNames(): Array<String> =
+    lightClassesCache.value.mapNotNull { it.name }.toTypedArray()
 
   override fun getClassesByName(name: String, scope: GlobalSearchScope): Array<PsiClass> {
     return lightClassesCache.value.filter { it.name == name }.toTypedArray()
@@ -63,13 +71,19 @@
 
   override fun getAllMethodNames() = arrayOf<String>()
   override fun getMethodsByName(name: String, scope: GlobalSearchScope) = arrayOf<PsiMethod>()
-  override fun getMethodsByNameIfNotMoreThan(name: String, scope: GlobalSearchScope, maxCount: Int): Array<PsiMethod> {
+  override fun getMethodsByNameIfNotMoreThan(
+    name: String,
+    scope: GlobalSearchScope,
+    maxCount: Int
+  ): Array<PsiMethod> {
     return getMethodsByName(name, scope).take(maxCount).toTypedArray()
   }
 
-  override fun processMethodsWithName(name: String,
-                                      scope: GlobalSearchScope,
-                                      processor: Processor<in PsiMethod>): Boolean {
+  override fun processMethodsWithName(
+    name: String,
+    scope: GlobalSearchScope,
+    processor: Processor<in PsiMethod>
+  ): Boolean {
     // We are asked to process each method in turn, aborting if false is ever returned, and passing
     // that result back up the chain.
     return getMethodsByName(name, scope).all { method -> processor.process(method) }
@@ -77,7 +91,11 @@
 
   override fun getAllFieldNames() = arrayOf<String>()
   override fun getFieldsByName(name: String, scope: GlobalSearchScope) = arrayOf<PsiField>()
-  override fun getFieldsByNameIfNotMoreThan(name: String, scope: GlobalSearchScope, maxCount: Int): Array<PsiField> {
+  override fun getFieldsByNameIfNotMoreThan(
+    name: String,
+    scope: GlobalSearchScope,
+    maxCount: Int
+  ): Array<PsiField> {
     return getFieldsByName(name, scope).take(maxCount).toTypedArray()
   }
 }
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/cache/ArgsBuilderShortNamesCache.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/cache/ArgsBuilderShortNamesCache.kt
index 6095283..6d05ad5 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/cache/ArgsBuilderShortNamesCache.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/cache/ArgsBuilderShortNamesCache.kt
@@ -41,18 +41,22 @@
   init {
     val cachedValuesManager = CachedValuesManager.getManager(project)
 
-    lightClassesCache = cachedValuesManager.createCachedValue {
-      val builders = enabledFacetsProvider.modulesUsingSafeArgs
-        .asSequence()
-        .flatMap { facet -> SafeArgsCacheModuleService.getInstance(facet).args.asSequence() }
-        .flatMap { it.innerClasses.asSequence() }
-        .filterIsInstance<LightArgsBuilderClass>()
-        .toList()
+    lightClassesCache =
+      cachedValuesManager.createCachedValue {
+        val builders =
+          enabledFacetsProvider.modulesUsingSafeArgs
+            .asSequence()
+            .flatMap { facet -> SafeArgsCacheModuleService.getInstance(facet).args.asSequence() }
+            .flatMap { it.innerClasses.asSequence() }
+            .filterIsInstance<LightArgsBuilderClass>()
+            .toList()
 
-      CachedValueProvider.Result.create(builders,
-                                        ProjectNavigationResourceModificationTracker.getInstance(project),
-                                        project.safeArgsModeTracker)
-    }
+        CachedValueProvider.Result.create(
+          builders,
+          ProjectNavigationResourceModificationTracker.getInstance(project),
+          project.safeArgsModeTracker
+        )
+      }
   }
 
   override fun getAllClassNames(): Array<String> = arrayOf("Builder")
@@ -67,13 +71,19 @@
 
   override fun getAllMethodNames() = arrayOf<String>()
   override fun getMethodsByName(name: String, scope: GlobalSearchScope) = arrayOf<PsiMethod>()
-  override fun getMethodsByNameIfNotMoreThan(name: String, scope: GlobalSearchScope, maxCount: Int): Array<PsiMethod> {
+  override fun getMethodsByNameIfNotMoreThan(
+    name: String,
+    scope: GlobalSearchScope,
+    maxCount: Int
+  ): Array<PsiMethod> {
     return getMethodsByName(name, scope).take(maxCount).toTypedArray()
   }
 
-  override fun processMethodsWithName(name: String,
-                                      scope: GlobalSearchScope,
-                                      processor: Processor<in PsiMethod>): Boolean {
+  override fun processMethodsWithName(
+    name: String,
+    scope: GlobalSearchScope,
+    processor: Processor<in PsiMethod>
+  ): Boolean {
     // We are asked to process each method in turn, aborting if false is ever returned, and passing
     // that result back up the chain.
     return getMethodsByName(name, scope).all { method -> processor.process(method) }
@@ -81,7 +91,11 @@
 
   override fun getAllFieldNames() = arrayOf<String>()
   override fun getFieldsByName(name: String, scope: GlobalSearchScope) = arrayOf<PsiField>()
-  override fun getFieldsByNameIfNotMoreThan(name: String, scope: GlobalSearchScope, maxCount: Int): Array<PsiField> {
+  override fun getFieldsByNameIfNotMoreThan(
+    name: String,
+    scope: GlobalSearchScope,
+    maxCount: Int
+  ): Array<PsiField> {
     return getFieldsByName(name, scope).take(maxCount).toTypedArray()
   }
 }
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/cache/ArgsShortNamesCache.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/cache/ArgsShortNamesCache.kt
index 206a4c2..136debb 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/cache/ArgsShortNamesCache.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/cache/ArgsShortNamesCache.kt
@@ -32,9 +32,7 @@
 import com.intellij.psi.util.CachedValuesManager
 import com.intellij.util.Processor
 
-/**
- * A short names cache for finding any [LightArgsClass] instances by their unqualified name.
- */
+/** A short names cache for finding any [LightArgsClass] instances by their unqualified name. */
 class ArgsShortNamesCache(project: Project) : PsiShortNamesCache() {
   private val enabledFacetsProvider = SafeArgsEnabledFacetsProjectService.getInstance(project)
   private val lightClassesCache: CachedValue<Map<String, List<LightArgsClass>>>
@@ -44,45 +42,56 @@
   init {
     val cachedValuesManager = CachedValuesManager.getManager(project)
 
-    lightClassesCache = cachedValuesManager.createCachedValue {
-      val lightClasses = enabledFacetsProvider.modulesUsingSafeArgs
-        .asSequence()
-        .flatMap { facet ->
-          SafeArgsCacheModuleService.getInstance(facet).args.asSequence()
-        }
-        .groupBy { lightClass -> lightClass.name }
-      CachedValueProvider.Result.create(lightClasses,
-                                        ProjectNavigationResourceModificationTracker.getInstance(project),
-                                        project.safeArgsModeTracker)
-    }
+    lightClassesCache =
+      cachedValuesManager.createCachedValue {
+        val lightClasses =
+          enabledFacetsProvider.modulesUsingSafeArgs
+            .asSequence()
+            .flatMap { facet -> SafeArgsCacheModuleService.getInstance(facet).args.asSequence() }
+            .groupBy { lightClass -> lightClass.name }
+        CachedValueProvider.Result.create(
+          lightClasses,
+          ProjectNavigationResourceModificationTracker.getInstance(project),
+          project.safeArgsModeTracker
+        )
+      }
 
-    allClassNamesCache = cachedValuesManager.createCachedValue {
-      CachedValueProvider.Result.create(lightClassesCache.value.keys.toTypedArray(), lightClassesCache)
-    }
+    allClassNamesCache =
+      cachedValuesManager.createCachedValue {
+        CachedValueProvider.Result.create(
+          lightClassesCache.value.keys.toTypedArray(),
+          lightClassesCache
+        )
+      }
   }
 
-
   override fun getAllClassNames(): Array<String> = allClassNamesCache.value
 
   override fun getClassesByName(name: String, scope: GlobalSearchScope): Array<PsiClass> {
     return lightClassesCache.value[name]
-             ?.asSequence()
-             ?.filter { PsiSearchScopeUtil.isInScope(scope, it) }
-             ?.map { it as PsiClass }
-             ?.toList()
-             ?.toTypedArray()
-           ?: PsiClass.EMPTY_ARRAY
+      ?.asSequence()
+      ?.filter { PsiSearchScopeUtil.isInScope(scope, it) }
+      ?.map { it as PsiClass }
+      ?.toList()
+      ?.toTypedArray()
+      ?: PsiClass.EMPTY_ARRAY
   }
 
   override fun getAllMethodNames() = arrayOf<String>()
   override fun getMethodsByName(name: String, scope: GlobalSearchScope) = arrayOf<PsiMethod>()
-  override fun getMethodsByNameIfNotMoreThan(name: String, scope: GlobalSearchScope, maxCount: Int): Array<PsiMethod> {
+  override fun getMethodsByNameIfNotMoreThan(
+    name: String,
+    scope: GlobalSearchScope,
+    maxCount: Int
+  ): Array<PsiMethod> {
     return getMethodsByName(name, scope).take(maxCount).toTypedArray()
   }
 
-  override fun processMethodsWithName(name: String,
-                                      scope: GlobalSearchScope,
-                                      processor: Processor<in PsiMethod>): Boolean {
+  override fun processMethodsWithName(
+    name: String,
+    scope: GlobalSearchScope,
+    processor: Processor<in PsiMethod>
+  ): Boolean {
     // We are asked to process each method in turn, aborting if false is ever returned, and passing
     // that result back up the chain.
     return getMethodsByName(name, scope).all { method -> processor.process(method) }
@@ -91,7 +100,11 @@
   override fun getAllFieldNames() = arrayOf<String>()
   override fun getFieldsByName(name: String, scope: GlobalSearchScope) = arrayOf<PsiField>()
 
-  override fun getFieldsByNameIfNotMoreThan(name: String, scope: GlobalSearchScope, maxCount: Int): Array<PsiField> {
+  override fun getFieldsByNameIfNotMoreThan(
+    name: String,
+    scope: GlobalSearchScope,
+    maxCount: Int
+  ): Array<PsiField> {
     return getFieldsByName(name, scope).take(maxCount).toTypedArray()
   }
 }
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/cache/DirectionsShortNamesCache.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/cache/DirectionsShortNamesCache.kt
index a6a31fc..cf239ca 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/cache/DirectionsShortNamesCache.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/cache/DirectionsShortNamesCache.kt
@@ -33,8 +33,8 @@
 import com.intellij.util.Processor
 
 /**
- * A short names cache for finding any [LightDirectionsClass] classes or their methods by their unqualified
- * name.
+ * A short names cache for finding any [LightDirectionsClass] classes or their methods by their
+ * unqualified name.
  */
 class DirectionsShortNamesCache(project: Project) : PsiShortNamesCache() {
   private val enabledFacetsProvider = SafeArgsEnabledFacetsProjectService.getInstance(project)
@@ -45,45 +45,58 @@
   init {
     val cachedValuesManager = CachedValuesManager.getManager(project)
 
-    lightClassesCache = cachedValuesManager.createCachedValue {
-      val lightClasses = enabledFacetsProvider.modulesUsingSafeArgs
-        .asSequence()
-        .flatMap { facet ->
-          SafeArgsCacheModuleService.getInstance(facet).directions.asSequence()
-        }
-        .groupBy { lightClass -> lightClass.name }
-      CachedValueProvider.Result.create(lightClasses,
-                                        ProjectNavigationResourceModificationTracker.getInstance(project),
-                                        project.safeArgsModeTracker)
-    }
+    lightClassesCache =
+      cachedValuesManager.createCachedValue {
+        val lightClasses =
+          enabledFacetsProvider.modulesUsingSafeArgs
+            .asSequence()
+            .flatMap { facet ->
+              SafeArgsCacheModuleService.getInstance(facet).directions.asSequence()
+            }
+            .groupBy { lightClass -> lightClass.name }
+        CachedValueProvider.Result.create(
+          lightClasses,
+          ProjectNavigationResourceModificationTracker.getInstance(project),
+          project.safeArgsModeTracker
+        )
+      }
 
-    allClassNamesCache = cachedValuesManager.createCachedValue {
-      CachedValueProvider.Result.create(lightClassesCache.value.keys.toTypedArray(), lightClassesCache)
-    }
+    allClassNamesCache =
+      cachedValuesManager.createCachedValue {
+        CachedValueProvider.Result.create(
+          lightClassesCache.value.keys.toTypedArray(),
+          lightClassesCache
+        )
+      }
   }
 
-
   override fun getAllClassNames(): Array<String> = allClassNamesCache.value
   override fun getClassesByName(name: String, scope: GlobalSearchScope): Array<PsiClass> {
     return lightClassesCache.value[name]
-             ?.asSequence()
-             ?.filter { PsiSearchScopeUtil.isInScope(scope, it) }
-             ?.map { it as PsiClass }
-             ?.toList()
-             ?.toTypedArray()
-           ?: PsiClass.EMPTY_ARRAY
+      ?.asSequence()
+      ?.filter { PsiSearchScopeUtil.isInScope(scope, it) }
+      ?.map { it as PsiClass }
+      ?.toList()
+      ?.toTypedArray()
+      ?: PsiClass.EMPTY_ARRAY
   }
 
   override fun getAllMethodNames() = arrayOf<String>()
   override fun getMethodsByName(name: String, scope: GlobalSearchScope) = arrayOf<PsiMethod>()
 
-  override fun getMethodsByNameIfNotMoreThan(name: String, scope: GlobalSearchScope, maxCount: Int): Array<PsiMethod> {
+  override fun getMethodsByNameIfNotMoreThan(
+    name: String,
+    scope: GlobalSearchScope,
+    maxCount: Int
+  ): Array<PsiMethod> {
     return getMethodsByName(name, scope).take(maxCount).toTypedArray()
   }
 
-  override fun processMethodsWithName(name: String,
-                                      scope: GlobalSearchScope,
-                                      processor: Processor<in PsiMethod>): Boolean {
+  override fun processMethodsWithName(
+    name: String,
+    scope: GlobalSearchScope,
+    processor: Processor<in PsiMethod>
+  ): Boolean {
     // We are asked to process each method in turn, aborting if false is ever returned, and passing
     // that result back up the chain.
     return getMethodsByName(name, scope).all { method -> processor.process(method) }
@@ -92,7 +105,11 @@
   override fun getAllFieldNames() = arrayOf<String>()
   override fun getFieldsByName(name: String, scope: GlobalSearchScope) = arrayOf<PsiField>()
 
-  override fun getFieldsByNameIfNotMoreThan(name: String, scope: GlobalSearchScope, maxCount: Int): Array<PsiField> {
+  override fun getFieldsByNameIfNotMoreThan(
+    name: String,
+    scope: GlobalSearchScope,
+    maxCount: Int
+  ): Array<PsiField> {
     return getFieldsByName(name, scope).take(maxCount).toTypedArray()
   }
 }
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/ActionBuilderClassFinder.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/ActionBuilderClassFinder.kt
index dc3729b..0e235f3 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/ActionBuilderClassFinder.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/ActionBuilderClassFinder.kt
@@ -20,13 +20,12 @@
 import com.intellij.openapi.project.Project
 import org.jetbrains.android.facet.AndroidFacet
 
-/**
- * A finder that can find instances of [LightActionBuilderClass] by qualified name / package.
- */
+/** A finder that can find instances of [LightActionBuilderClass] by qualified name / package. */
 class ActionBuilderClassFinder(project: Project) : SafeArgsClassFinderBase(project) {
   override fun findAll(facet: AndroidFacet): List<LightActionBuilderClass> {
-    return SafeArgsCacheModuleService.getInstance(facet).directions
+    return SafeArgsCacheModuleService.getInstance(facet)
+      .directions
       .flatMap { it.innerClasses.toList() }
       .filterIsInstance<LightActionBuilderClass>()
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/ArgsBuilderClassFinder.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/ArgsBuilderClassFinder.kt
index d935d51..412e26d 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/ArgsBuilderClassFinder.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/ArgsBuilderClassFinder.kt
@@ -20,12 +20,11 @@
 import com.intellij.openapi.project.Project
 import org.jetbrains.android.facet.AndroidFacet
 
-/**
- * A finder that can find instances of [LightArgsBuilderClass] by qualified name / package.
- */
+/** A finder that can find instances of [LightArgsBuilderClass] by qualified name / package. */
 class ArgsBuilderClassFinder(project: Project) : SafeArgsClassFinderBase(project) {
   override fun findAll(facet: AndroidFacet): List<LightArgsBuilderClass> {
-    return SafeArgsCacheModuleService.getInstance(facet).args
+    return SafeArgsCacheModuleService.getInstance(facet)
+      .args
       .flatMap { it.innerClasses.toList() }
       .filterIsInstance<LightArgsBuilderClass>()
   }
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/ArgsClassFinder.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/ArgsClassFinder.kt
index d5f15ae..f658cd6 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/ArgsClassFinder.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/ArgsClassFinder.kt
@@ -21,11 +21,9 @@
 import com.intellij.openapi.project.Project
 import org.jetbrains.android.facet.AndroidFacet
 
-/**
- * A finder that can find instances of [LightArgsClass] by qualified name / package.
- */
+/** A finder that can find instances of [LightArgsClass] by qualified name / package. */
 class ArgsClassFinder(project: Project) : SafeArgsClassFinderBase(project) {
   override fun findAll(facet: AndroidFacet): List<SafeArgsLightBaseClass> {
     return SafeArgsCacheModuleService.getInstance(facet).args
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/DirectionsClassFinder.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/DirectionsClassFinder.kt
index f2d731f..d88ad2f 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/DirectionsClassFinder.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/DirectionsClassFinder.kt
@@ -21,9 +21,7 @@
 import com.intellij.openapi.project.Project
 import org.jetbrains.android.facet.AndroidFacet
 
-/**
- * A finder that can find instances of [LightDirectionsClass] by qualified name / package.
- */
+/** A finder that can find instances of [LightDirectionsClass] by qualified name / package. */
 class DirectionsClassFinder(project: Project) : SafeArgsClassFinderBase(project) {
   override fun findAll(facet: AndroidFacet): List<SafeArgsLightBaseClass> {
     return SafeArgsCacheModuleService.getInstance(facet).directions
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/SafeArgsClassFinderBase.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/SafeArgsClassFinderBase.kt
index c71b5a7..32a3bad 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/SafeArgsClassFinderBase.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/SafeArgsClassFinderBase.kt
@@ -29,23 +29,23 @@
 import org.jetbrains.android.augment.AndroidLightClassBase
 import org.jetbrains.android.facet.AndroidFacet
 
-/**
- * A base class for safe arg light class finder
- *
- */
+/** A base class for safe arg light class finder */
 abstract class SafeArgsClassFinderBase(private val project: Project) : PsiElementFinder() {
 
   private fun findAll(project: Project): List<AndroidLightClassBase> {
     val provider = {
-      val result = SafeArgsEnabledFacetsProjectService.getInstance(project)
-        .modulesUsingSafeArgs
-        .asSequence()
-        .flatMap { facet -> findAll(facet).asSequence() }
-        .toList()
+      val result =
+        SafeArgsEnabledFacetsProjectService.getInstance(project)
+          .modulesUsingSafeArgs
+          .asSequence()
+          .flatMap { facet -> findAll(facet).asSequence() }
+          .toList()
 
-      CachedValueProvider.Result.create(result,
-                                        ProjectNavigationResourceModificationTracker.getInstance(project),
-                                        project.safeArgsModeTracker)
+      CachedValueProvider.Result.create(
+        result,
+        ProjectNavigationResourceModificationTracker.getInstance(project),
+        project.safeArgsModeTracker
+      )
     }
 
     val manager = CachedValuesManager.getManager(project)
@@ -55,18 +55,15 @@
   abstract fun findAll(facet: AndroidFacet): List<AndroidLightClassBase>
 
   override fun findClass(qualifiedName: String, scope: GlobalSearchScope): PsiClass? {
-    return findAll(project)
-      .firstOrNull { lightClass ->
-        lightClass.qualifiedName == qualifiedName
-        && PsiSearchScopeUtil.isInScope(scope, lightClass)
-      }
+    return findAll(project).firstOrNull { lightClass ->
+      lightClass.qualifiedName == qualifiedName && PsiSearchScopeUtil.isInScope(scope, lightClass)
+    }
   }
 
   override fun findClasses(qualifiedName: String, scope: GlobalSearchScope): Array<PsiClass> {
     return findAll(project)
       .filter { lightClass ->
-        lightClass.qualifiedName == qualifiedName
-        && PsiSearchScopeUtil.isInScope(scope, lightClass)
+        lightClass.qualifiedName == qualifiedName && PsiSearchScopeUtil.isInScope(scope, lightClass)
       }
       .toTypedArray()
   }
@@ -78,9 +75,9 @@
 
     return findAll(psiPackage.project)
       .filter { lightClass ->
-        psiPackage.qualifiedName == lightClass.qualifiedName?.substringBeforeLast('.')
-        && PsiSearchScopeUtil.isInScope(scope, lightClass)
+        psiPackage.qualifiedName == lightClass.qualifiedName?.substringBeforeLast('.') &&
+          PsiSearchScopeUtil.isInScope(scope, lightClass)
       }
       .toTypedArray()
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/SafeArgsScopeEnlarger.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/SafeArgsScopeEnlarger.kt
index 2503e01..4bda74f 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/SafeArgsScopeEnlarger.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/finder/SafeArgsScopeEnlarger.kt
@@ -47,16 +47,24 @@
 
   internal fun getAdditionalResolveScope(facet: AndroidFacet): SearchScope? {
     return CachedValuesManager.getManager(facet.module.project).getCachedValue(facet) {
-      val allFacets = listOf(facet) + ModuleRootManager.getInstance(facet.module)
-        .getDependencies(false)
-        .mapNotNull { module -> module.androidFacet }
+      val allFacets =
+        listOf(facet) +
+          ModuleRootManager.getInstance(facet.module).getDependencies(false).mapNotNull { module ->
+            module.androidFacet
+          }
 
-      val scopeIncludingDeps = allFacets
-        .filter { it.safeArgsMode == SafeArgsMode.JAVA }
-        .map { it.getLocalScope() }
-        .fold(GlobalSearchScope.EMPTY_SCOPE) { scopeAccum, depScope -> scopeAccum.union(depScope) }
+      val scopeIncludingDeps =
+        allFacets
+          .filter { it.safeArgsMode == SafeArgsMode.JAVA }
+          .map { it.getLocalScope() }
+          .fold(GlobalSearchScope.EMPTY_SCOPE) { scopeAccum, depScope ->
+            scopeAccum.union(depScope)
+          }
 
-      CachedValueProvider.Result.create(scopeIncludingDeps, PsiModificationTracker.MODIFICATION_COUNT)
+      CachedValueProvider.Result.create(
+        scopeIncludingDeps,
+        PsiModificationTracker.MODIFICATION_COUNT
+      )
     }
   }
 
@@ -83,10 +91,11 @@
  * Therefore, we provide one here that simply delegates to it.
  */
 class SafeArgsKotlinScopeEnlarger : KotlinResolveScopeEnlarger {
-  private val delegateEnlarger = ResolveScopeEnlarger.EP_NAME.findExtensionOrFail(SafeArgsScopeEnlarger::class.java)
+  private val delegateEnlarger =
+    ResolveScopeEnlarger.EP_NAME.findExtensionOrFail(SafeArgsScopeEnlarger::class.java)
 
   override fun getAdditionalResolveScope(module: Module, isTestScope: Boolean): SearchScope? {
     val facet = module.androidFacet ?: return null
     return delegateEnlarger.getAdditionalResolveScope(facet)
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/index/JaxbNavData.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/index/JaxbNavData.kt
index 4bbb932..59eafc2 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/index/JaxbNavData.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/index/JaxbNavData.kt
@@ -20,8 +20,6 @@
 import com.android.SdkConstants.ANDROID_URI
 import com.android.SdkConstants.AUTO_URI
 import com.android.resources.ResourceUrl
-import org.w3c.dom.Document
-import org.w3c.dom.Element
 import javax.xml.bind.JAXBContext
 import javax.xml.bind.annotation.XmlAccessType
 import javax.xml.bind.annotation.XmlAccessorType
@@ -32,20 +30,20 @@
 import javax.xml.bind.annotation.adapters.XmlAdapter
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter
 import javax.xml.transform.dom.DOMResult
+import org.w3c.dom.Document
+import org.w3c.dom.Element
 
 // NOTE: If you change any class in this file, you should also increment NavXmlIndex#getVersion()
 
-/**
- * Adapter to handle serializing attributes that represent android IDs (e.g. "@id/asdf")
- */
+/** Adapter to handle serializing attributes that represent android IDs (e.g. "@id/asdf") */
 private class AndroidIdAdapter : XmlAdapter<String, String>() {
   override fun marshal(s: String) = "@id/$s"
   override fun unmarshal(s: String) = ResourceUrl.parse(s)?.name ?: ""
 }
 
 /**
- * Adapter to handle serializing attributes that represent android IDs that might not be
- * present. See also: [AndroidIdAdapter]
+ * Adapter to handle serializing attributes that represent android IDs that might not be present.
+ * See also: [AndroidIdAdapter]
  */
 private class OptionalAndroidIdAdapter : XmlAdapter<String?, String?>() {
   private val delegateAdapter = AndroidIdAdapter()
@@ -58,9 +56,9 @@
  * An adapter which allows us to catch any unspecified tag and try to fit it into a
  * [MaybeNavDestinationData].
  *
- * This adapter will always succeed at creating a "maybe" destination, but only if
- * expected attributes are found on the custom tag will it return a non-null
- * destination if [MaybeNavDestinationData.toDestination] is called.
+ * This adapter will always succeed at creating a "maybe" destination, but only if expected
+ * attributes are found on the custom tag will it return a non-null destination if
+ * [MaybeNavDestinationData.toDestination] is called.
  */
 private class MaybeDestinationAdapter : XmlAdapter<Element, MaybeNavDestinationData>() {
   private val jaxbContext = JAXBContext.newInstance(MutableMaybeNavDestinationData::class.java)
@@ -82,15 +80,9 @@
 @XmlRootElement(name = "argument")
 @XmlAccessorType(XmlAccessType.FIELD)
 data class MutableNavArgumentData(
-  @field:XmlAttribute(namespace = ANDROID_URI)
-  override var name: String,
-
-  @field:XmlAttribute(namespace = AUTO_URI, name = "argType")
-  override var type: String?,
-
-  @field:XmlAttribute(namespace = AUTO_URI, name = "nullable")
-  override var nullable: String?,
-
+  @field:XmlAttribute(namespace = ANDROID_URI) override var name: String,
+  @field:XmlAttribute(namespace = AUTO_URI, name = "argType") override var type: String?,
+  @field:XmlAttribute(namespace = AUTO_URI, name = "nullable") override var nullable: String?,
   @field:XmlAttribute(namespace = ANDROID_URI, name = "defaultValue")
   override var defaultValue: String?
 ) : NavArgumentData {
@@ -103,37 +95,29 @@
   @field:XmlJavaTypeAdapter(AndroidIdAdapter::class)
   @field:XmlAttribute(namespace = ANDROID_URI)
   override var id: String,
-
   @field:XmlJavaTypeAdapter(OptionalAndroidIdAdapter::class)
   @field:XmlAttribute(namespace = AUTO_URI)
   override var destination: String?,
-
   @field:XmlJavaTypeAdapter(OptionalAndroidIdAdapter::class)
   @field:XmlAttribute(namespace = AUTO_URI)
   override var popUpTo: String?,
-
-  @field:XmlElement(name = "argument")
-  override var arguments: List<MutableNavArgumentData>
+  @field:XmlElement(name = "argument") override var arguments: List<MutableNavArgumentData>
 ) : NavActionData {
   constructor() : this("", null, null, mutableListOf())
 }
 
-@XmlRootElement(name = "maybeDestination") // Fake root element name only used for indexing, required by JAXB marshalling
+@XmlRootElement(
+  name = "maybeDestination"
+) // Fake root element name only used for indexing, required by JAXB marshalling
 @XmlAccessorType(XmlAccessType.FIELD)
 data class MutableMaybeNavDestinationData(
   @field:XmlJavaTypeAdapter(OptionalAndroidIdAdapter::class)
   @field:XmlAttribute(namespace = ANDROID_URI)
   var id: String?,
-
-  @field:XmlAttribute(namespace = ANDROID_URI)
-  var name: String?,
-
-  @field:XmlElement(name = "argument")
-  var arguments: List<MutableNavArgumentData>,
-
-  @field:XmlElement(name = "action")
-  var actions: List<MutableNavActionData>)
-  : MaybeNavDestinationData {
+  @field:XmlAttribute(namespace = ANDROID_URI) var name: String?,
+  @field:XmlElement(name = "argument") var arguments: List<MutableNavArgumentData>,
+  @field:XmlElement(name = "action") var actions: List<MutableNavActionData>
+) : MaybeNavDestinationData {
   constructor() : this(null, null, mutableListOf(), mutableListOf())
 
   override fun toDestination(): NavDestinationData? {
@@ -155,20 +139,12 @@
   @field:XmlJavaTypeAdapter(OptionalAndroidIdAdapter::class)
   @field:XmlAttribute(namespace = ANDROID_URI)
   override var id: String?,
-
   @field:XmlJavaTypeAdapter(AndroidIdAdapter::class)
   @field:XmlAttribute(namespace = AUTO_URI)
   override var startDestination: String,
-
-  @field:XmlElement(name = "action")
-  override var actions: List<MutableNavActionData>,
-
-  @field:XmlElement(name = "argument")
-  override var arguments: List<MutableNavArgumentData>,
-
-  @field:XmlElement(name = "navigation")
-  override var navigations: List<MutableNavNavigationData>,
-
+  @field:XmlElement(name = "action") override var actions: List<MutableNavActionData>,
+  @field:XmlElement(name = "argument") override var arguments: List<MutableNavArgumentData>,
+  @field:XmlElement(name = "navigation") override var navigations: List<MutableNavNavigationData>,
   @field:XmlAnyElement()
   @field:XmlJavaTypeAdapter(MaybeDestinationAdapter::class)
   override var potentialDestinations: List<MaybeNavDestinationData>
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/index/NavData.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/index/NavData.kt
index da4cf09..7ad4654 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/index/NavData.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/index/NavData.kt
@@ -24,9 +24,8 @@
  * A destination may have zero or more arguments. Actions may also have arguments, which act as
  * default values for their destinations.
  *
- * In most cases, users will provide [type] explicitly, but if not specified, it can be
- * inferred from [defaultValue]. If neither [type] nor [defaultValue] are set, this
- * argument data is invalid.
+ * In most cases, users will provide [type] explicitly, but if not specified, it can be inferred
+ * from [defaultValue]. If neither [type] nor [defaultValue] are set, this argument data is invalid.
  */
 interface NavArgumentData {
   val name: String
@@ -45,9 +44,9 @@
  *
  * A destination may have zero or more actions.
  *
- * An action itself should point to a single target destination, which is usually set by `destination`,
- * but could also just be set by `popUpTo` (which essentially means the user wants to navigate backwards
- * to a destination that's in the back stack)
+ * An action itself should point to a single target destination, which is usually set by
+ * `destination`, but could also just be set by `popUpTo` (which essentially means the user wants to
+ * navigate backwards to a destination that's in the back stack)
  */
 interface NavActionData {
   val id: String
@@ -60,9 +59,7 @@
   }
 }
 
-/**
- * A useful abstraction across multiple destination types, e.g. <activity> and <fragment>
- */
+/** A useful abstraction across multiple destination types, e.g. <activity> and <fragment> */
 interface NavDestinationData {
   val id: String
   val name: String
@@ -98,7 +95,9 @@
     val id = this.id ?: return null
     return object : NavDestinationData {
       override val id = id
-      override val name = ".${id.toUpperCamelCase()}" // The prefix '.' means this class should be scoped in the current module
+      override val name =
+        ".${id.toUpperCamelCase()}" // The prefix '.' means this class should be scoped in the
+      // current module
       override val arguments = this@NavNavigationData.arguments
       override val actions = this@NavNavigationData.actions
     }
@@ -106,15 +105,16 @@
 }
 
 /**
- * Data class for storing the indexed content nav XML files, useful for generating relevant
- * safe args classes.
+ * Data class for storing the indexed content nav XML files, useful for generating relevant safe
+ * args classes.
  */
 data class NavXmlData(val root: NavNavigationData) {
   /**
    * Returns a list of all destinations with global actions updated.
    * (https://developer.android.com/guide/navigation/navigation-global-action)
    *
-   * Global actions are collected along the path while traversing, and duplicates are resolved like actions overrides.
+   * Global actions are collected along the path while traversing, and duplicates are resolved like
+   * actions overrides.
    */
   val resolvedDestinations: List<NavDestinationData> by lazy {
     root.traverse(emptyList(), mutableListOf())
@@ -131,18 +131,18 @@
       .mapNotNull { it.toDestination()?.withGlobalActions(newGlobalActions) }
       .let { allDestinations.addAll(it) }
 
-    this.navigations.map {
-      it.traverse(newGlobalActions, allDestinations)
-    }
+    this.navigations.map { it.traverse(newGlobalActions, allDestinations) }
 
     return allDestinations
   }
 
-  private fun NavDestinationData.withGlobalActions(globalActions: List<NavActionData>): NavDestinationData {
+  private fun NavDestinationData.withGlobalActions(
+    globalActions: List<NavActionData>
+  ): NavDestinationData {
     if (globalActions.isEmpty()) return this
 
     return object : NavDestinationData by this {
       override val actions = (this@withGlobalActions.actions + globalActions).distinctBy { it.id }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/index/NavXmlIndex.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/index/NavXmlIndex.kt
index 0ecae16..a565fd8 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/index/NavXmlIndex.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/index/NavXmlIndex.kt
@@ -46,11 +46,13 @@
 
     fun getDataForFile(project: Project, file: VirtualFile): NavXmlData? {
       ApplicationManager.getApplication().assertReadAccessAllowed()
-      val navXmlData = FileBasedIndex.getInstance().getSingleEntryIndexData(NAME, file, project) ?: return null
+      val navXmlData =
+        FileBasedIndex.getInstance().getSingleEntryIndexData(NAME, file, project) ?: return null
 
       // Verify that this is a navigation resource file before returning.
       val containingFolderName = file.parent?.name ?: return null
-      if (ResourceFolderType.getFolderType(containingFolderName) != ResourceFolderType.NAVIGATION) return null
+      if (ResourceFolderType.getFolderType(containingFolderName) != ResourceFolderType.NAVIGATION)
+        return null
 
       return navXmlData
     }
@@ -58,8 +60,10 @@
 
   private val jaxbContext = JAXBContext.newInstance(MutableNavNavigationData::class.java)
   // JAXB marshallers / unmarshallers are not thread-safe, so create a new one each time
-  private val jaxbSerializer get() = jaxbContext.createMarshaller()
-  private val jaxbDeserializer get() = jaxbContext.createUnmarshaller()
+  private val jaxbSerializer
+    get() = jaxbContext.createMarshaller()
+  private val jaxbDeserializer
+    get() = jaxbContext.createUnmarshaller()
 
   override fun getVersion() = 11
   override fun dependsOnFileContent() = true
@@ -74,15 +78,17 @@
   }
 
   /**
-   * Defines the data externalizer handling the serialization/de-serialization of indexed information.
+   * Defines the data externalizer handling the serialization/de-serialization of indexed
+   * information.
    */
   override fun getValueExternalizer(): DataExternalizer<NavXmlData> {
     return object : DataExternalizer<NavXmlData> {
       override fun save(out: DataOutput, value: NavXmlData) {
-        val outBytes = ByteArrayOutputStream().use { writer ->
-          jaxbSerializer.marshal(value.root, writer)
-          writer.toByteArray()
-        }
+        val outBytes =
+          ByteArrayOutputStream().use { writer ->
+            jaxbSerializer.marshal(value.root, writer)
+            writer.toByteArray()
+          }
         out.writeInt(outBytes.size)
         out.write(outBytes)
       }
@@ -90,7 +96,10 @@
       override fun read(`in`: DataInput): NavXmlData {
         val inBytes = ByteArray(`in`.readInt())
         `in`.readFully(inBytes)
-        val rootNav = ByteArrayInputStream(inBytes).use { bytes -> jaxbDeserializer.unmarshal(bytes) as NavNavigationData }
+        val rootNav =
+          ByteArrayInputStream(inBytes).use { bytes ->
+            jaxbDeserializer.unmarshal(bytes) as NavNavigationData
+          }
         return NavXmlData(rootNav)
       }
     }
@@ -103,7 +112,8 @@
         if (!text.contains("<navigation")) return null
 
         return try {
-          val rootNav = jaxbDeserializer.unmarshal(StringReader(text.toString())) as NavNavigationData
+          val rootNav =
+            jaxbDeserializer.unmarshal(StringReader(text.toString())) as NavNavigationData
           NavXmlData(rootNav)
         }
         // Normally we'd just catch explicit exceptions, like UnmarshalException, but JAXB also
@@ -111,7 +121,10 @@
         // failed, and we definitely don't want any exceptions to leak to our users here, to be safe
         // we just catch and log all possible problems.
         catch (e: Throwable) {
-          getLog().info("${NavXmlIndex::class.java.simpleName} skipping over \"${inputData.file.path}\": ${e.message}")
+          getLog()
+            .info(
+              "${NavXmlIndex::class.java.simpleName} skipping over \"${inputData.file.path}\": ${e.message}"
+            )
           null
         }
       }
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/module/ModuleNavigationResourcesModificationTracker.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/module/ModuleNavigationResourcesModificationTracker.kt
index 88441dc..669ee8b 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/module/ModuleNavigationResourcesModificationTracker.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/module/ModuleNavigationResourcesModificationTracker.kt
@@ -17,37 +17,38 @@
 
 import com.android.tools.idea.nav.safeargs.project.NAVIGATION_RESOURCES_CHANGED
 import com.android.tools.idea.nav.safeargs.project.NavigationResourcesChangeListener
-import com.android.tools.idea.nav.safeargs.project.NavigationResourcesModificationListener
-import com.android.tools.idea.nav.safeargs.safeArgsModeTracker
 import com.intellij.openapi.Disposable
 import com.intellij.openapi.diagnostic.debug
 import com.intellij.openapi.diagnostic.logger
 import com.intellij.openapi.module.Module
-import com.intellij.openapi.startup.StartupManager
 import com.intellij.openapi.util.ModificationTracker
 import com.intellij.openapi.util.SimpleModificationTracker
 
 /**
- * A module-wide modification tracker whose modification count is a value incremented by any modifications of
- * corresponding navigation resource files.
+ * A module-wide modification tracker whose modification count is a value incremented by any
+ * modifications of corresponding navigation resource files.
  */
-class ModuleNavigationResourcesModificationTracker(val module: Module) : ModificationTracker, Disposable {
+class ModuleNavigationResourcesModificationTracker(val module: Module) :
+  ModificationTracker, Disposable {
   private val navigationModificationTracker = SimpleModificationTracker()
 
   init {
-    module.project.messageBus.connect(this).subscribe(
-      NAVIGATION_RESOURCES_CHANGED,
-      NavigationResourcesChangeListener { changedModule ->
-        if (changedModule == null || changedModule == module) {
-          navigationChanged()
+    module.project.messageBus
+      .connect(this)
+      .subscribe(
+        NAVIGATION_RESOURCES_CHANGED,
+        NavigationResourcesChangeListener { changedModule ->
+          if (changedModule == null || changedModule == module) {
+            navigationChanged()
+          }
         }
-      }
-    )
+      )
   }
 
   companion object {
     @JvmStatic
-    fun getInstance(module: Module) = module.getService(ModuleNavigationResourcesModificationTracker::class.java)!!
+    fun getInstance(module: Module) =
+      module.getService(ModuleNavigationResourcesModificationTracker::class.java)!!
   }
 
   override fun getModificationCount() = navigationModificationTracker.modificationCount
@@ -55,11 +56,13 @@
   override fun dispose() {}
 
   /**
-   * This is invoked when NavigationModificationListener detects a navigation file has been changed or added or deleted for this module
+   * This is invoked when NavigationModificationListener detects a navigation file has been changed
+   * or added or deleted for this module
    */
   private fun navigationChanged() {
     navigationModificationTracker.incModificationCount()
-    logger<ModuleNavigationResourcesModificationTracker>()
-      .debug { "Navigation Modification Tracker of $module is updated to $modificationCount" }
+    logger<ModuleNavigationResourcesModificationTracker>().debug {
+      "Navigation Modification Tracker of $module is updated to $modificationCount"
+    }
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/module/NavInfoFetcher.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/module/NavInfoFetcher.kt
index 8c27511..44d5c38 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/module/NavInfoFetcher.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/module/NavInfoFetcher.kt
@@ -42,9 +42,9 @@
 import com.intellij.openapi.vfs.VirtualFile
 import com.intellij.psi.PsiManager
 import com.intellij.psi.xml.XmlFile
+import kotlin.reflect.KProperty
 import net.jcip.annotations.GuardedBy
 import org.jetbrains.android.facet.AndroidFacet
-import kotlin.reflect.KProperty
 
 /** Information about a single navigation file. */
 data class NavEntry(
@@ -72,7 +72,9 @@
   val entries: List<NavEntry>,
   /** The configured Jetpack Navigation version for which this [NavInfo] is valid. */
   val navVersion: Version,
-  /** The modification count, from the source [NavInfoFetcher], at which this [NavInfo] was valid. */
+  /**
+   * The modification count, from the source [NavInfoFetcher], at which this [NavInfo] was valid.
+   */
   val modificationCount: Long,
 )
 
@@ -81,10 +83,10 @@
   SAFE_ARGS_MODE_CHANGED,
   GRADLE_SYNC,
   DUMB_MODE_CHANGED,
-  ;
 }
 
-@VisibleForTesting interface NavInfoFetcherBase : ModificationTracker {
+@VisibleForTesting
+interface NavInfoFetcherBase : ModificationTracker {
   val isEnabled: Boolean
   fun getCurrentNavInfo(): NavInfo?
 }
@@ -95,7 +97,10 @@
   parent: Disposable,
   /** The [Module] for which to fetch navigation state. */
   private val module: Module,
-  /** The [SafeArgsMode] for which the navigation state is valid. [getCurrentNavInfo] will return `null` for projects in other modes. */
+  /**
+   * The [SafeArgsMode] for which the navigation state is valid. [getCurrentNavInfo] will return
+   * `null` for projects in other modes.
+   */
   private val mode: SafeArgsMode,
   /** A callback that will be called when the result of [getCurrentNavInfo] may have changed. */
   private val onChange: (NavInfoChangeReason) -> Unit = {}
@@ -127,9 +132,7 @@
       // Invalidate on project sync, in case nav version changes.
       subscribe(
         PROJECT_SYSTEM_SYNC_TOPIC,
-        ProjectSystemSyncManager.SyncResultListener {
-          invalidate(NavInfoChangeReason.GRADLE_SYNC)
-        }
+        ProjectSystemSyncManager.SyncResultListener { invalidate(NavInfoChangeReason.GRADLE_SYNC) }
       )
       subscribe(
         DumbService.DUMB_MODE,
@@ -149,9 +152,13 @@
   }
 
   private val androidFacetIfEnabled: AndroidFacet?
-    get() = AndroidFacet.getInstance(module)?.takeIf { it.isSafeArgsEnabled() && it.safeArgsMode == mode }
+    get() =
+      AndroidFacet.getInstance(module)?.takeIf { it.isSafeArgsEnabled() && it.safeArgsMode == mode }
 
-  /** Whether the project is currently enabled (SafeArgs enabled for project, and [SafeArgsMode] matches filter). */
+  /**
+   * Whether the project is currently enabled (SafeArgs enabled for project, and [SafeArgsMode]
+   * matches filter).
+   */
   override val isEnabled: Boolean
     get() = androidFacetIfEnabled != null
 
@@ -171,8 +178,8 @@
   /**
    * Gets the [NavInfo] for the current state of the project.
    *
-   * Returns `null` if Jetpack Navigation is [disabled](isEnabled) for the project, the project is in the wrong [SafeArgsMode], or the
-   * project indices are not yet ready for querying.
+   * Returns `null` if Jetpack Navigation is [disabled](isEnabled) for the project, the project is
+   * in the wrong [SafeArgsMode], or the project indices are not yet ready for querying.
    */
   override fun getCurrentNavInfo(): NavInfo? {
     val facet = androidFacetIfEnabled ?: return null
@@ -180,30 +187,40 @@
 
     if (DumbService.getInstance(module.project).isDumb) {
       Logger.getInstance(this.javaClass)
-        .warn("Safe Args classes may be temporarily stale or unavailable due to indices not being ready right now.")
+        .warn(
+          "Safe Args classes may be temporarily stale or unavailable due to indices not being ready right now."
+        )
       return null
     }
 
-    // Save version and modification count _before_ reading resources - in the event of a change, this ensures that we don't match up the
+    // Save version and modification count _before_ reading resources - in the event of a change,
+    // this ensures that we don't match up the
     // current modification count with stale data.
     val navVersion = facet.findNavigationVersion()
     val modificationCount = modificationCount
 
     val moduleResources = StudioResourceRepositoryManager.getModuleResources(facet)
-    val navResources = moduleResources.getResources(ResourceNamespace.RES_AUTO, ResourceType.NAVIGATION)
+    val navResources =
+      moduleResources.getResources(ResourceNamespace.RES_AUTO, ResourceType.NAVIGATION)
 
-    val entries = navResources.values().mapNotNull { resource ->
-      val file = resource.getSourceAsVirtualFile() ?: return@mapNotNull null
-      val data = NavXmlIndex.getDataForFile(module.project, file) ?: return@mapNotNull null
-      NavEntry(facet, resource, file, data)
-    }
+    val entries =
+      navResources.values().mapNotNull { resource ->
+        val file = resource.getSourceAsVirtualFile() ?: return@mapNotNull null
+        val data = NavXmlIndex.getDataForFile(module.project, file) ?: return@mapNotNull null
+        NavEntry(facet, resource, file, data)
+      }
 
     return NavInfo(facet, modulePackage, entries, navVersion, modificationCount)
   }
 }
 
-/** An object that creates and caches arbitrary status objects that depend on the current state of Jetpack Navigation. */
-class NavStatusCache<TStatus : Any> @VisibleForTesting constructor(
+/**
+ * An object that creates and caches arbitrary status objects that depend on the current state of
+ * Jetpack Navigation.
+ */
+class NavStatusCache<TStatus : Any>
+@VisibleForTesting
+constructor(
   private val onCacheInvalidate: (NavInfoChangeReason) -> Unit,
   private val update: (NavInfo) -> TStatus,
   navInfoFetcherFactory: ((NavInfoChangeReason) -> Unit) -> NavInfoFetcherBase
@@ -227,46 +244,48 @@
      * Will be called with a lock held, and will be called at most once per new [navInfo] generated.
      */
     update: (NavInfo) -> TStatus
-  ) : this(onCacheInvalidate, update, { invalidate -> NavInfoFetcher(parent, module, mode, invalidate) })
+  ) : this(
+    onCacheInvalidate,
+    update,
+    { invalidate -> NavInfoFetcher(parent, module, mode, invalidate) }
+  )
 
   private val lock = Any()
 
   private val fetcher = navInfoFetcherFactory { invalidateReason ->
     // Invalidate cached status.
-    synchronized(lock) {
-      lastStatusValid = false
-    }
+    synchronized(lock) { lastStatusValid = false }
     onCacheInvalidate(invalidateReason)
   }
 
-  @GuardedBy("lock")
-  private var lastStatus: TStatus? = null
+  @GuardedBy("lock") private var lastStatus: TStatus? = null
 
-  @GuardedBy("lock")
-  private var lastStatusValid = false
+  @GuardedBy("lock") private var lastStatusValid = false
 
   /**
    * Gets the current status, as generated by [update] for the current state of Jetpack Navigation.
    *
-   * If [NavInfoFetcher.getCurrentNavInfo] returns `null`, returns a previously-cached result if available.
+   * If [NavInfoFetcher.getCurrentNavInfo] returns `null`, returns a previously-cached result if
+   * available.
    */
   val currentStatus: TStatus?
-    get() = synchronized(lock) {
-      // Don't return cached data if this entire service is no longer enabled (mode change).
-      if (!fetcher.isEnabled) return null
-      if (!lastStatusValid) {
-        // A null from getCurrentNavInfo() here means either SafeArgs is disabled, or we're
-        // in dumb mode. The former case is handled by the isEnabled check above.
-        // If we're in dumb mode, stale data is the best we can do, so return it anyway.
-        // We'll get a cache-invalidate event from NavInfoFetcher when we become smart, and
-        // our caller will know to query us again.
-        val newNavInfo = fetcher.getCurrentNavInfo() ?: return lastStatus
-        val newStatus = update(newNavInfo)
-        lastStatus = newStatus
-        lastStatusValid = true
+    get() =
+      synchronized(lock) {
+        // Don't return cached data if this entire service is no longer enabled (mode change).
+        if (!fetcher.isEnabled) return null
+        if (!lastStatusValid) {
+          // A null from getCurrentNavInfo() here means either SafeArgs is disabled, or we're
+          // in dumb mode. The former case is handled by the isEnabled check above.
+          // If we're in dumb mode, stale data is the best we can do, so return it anyway.
+          // We'll get a cache-invalidate event from NavInfoFetcher when we become smart, and
+          // our caller will know to query us again.
+          val newNavInfo = fetcher.getCurrentNavInfo() ?: return lastStatus
+          val newStatus = update(newNavInfo)
+          lastStatus = newStatus
+          lastStatusValid = true
+        }
+        return lastStatus
       }
-      return lastStatus
-    }
 
   /** A [ModificationTracker] that will update when provided cached data needs to be invalidated. */
   val modificationTracker: ModificationTracker = fetcher
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/module/SafeArgsCacheModuleService.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/module/SafeArgsCacheModuleService.kt
index 293814f..870610b 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/module/SafeArgsCacheModuleService.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/module/SafeArgsCacheModuleService.kt
@@ -15,7 +15,6 @@
  */
 package com.android.tools.idea.nav.safeargs.module
 
-import com.android.ide.common.gradle.Version
 import com.android.tools.idea.nav.safeargs.SafeArgsMode
 import com.android.tools.idea.nav.safeargs.psi.java.LightArgsClass
 import com.android.tools.idea.nav.safeargs.psi.java.LightDirectionsClass
@@ -35,17 +34,16 @@
 class SafeArgsCacheModuleService private constructor(module: Module) : Disposable.Default {
   private class Status(val directions: List<LightDirectionsClass>, val args: List<LightArgsClass>)
 
-  private val currentStatus by NavStatusCache(this, module, SafeArgsMode.JAVA) { navInfo ->
-    val directions = navInfo.entries
-      .flatMap { entry -> createLightDirectionsClasses(navInfo, entry) }
-      .toList()
+  private val currentStatus by
+    NavStatusCache(this, module, SafeArgsMode.JAVA) { navInfo ->
+      val directions =
+        navInfo.entries.flatMap { entry -> createLightDirectionsClasses(navInfo, entry) }.toList()
 
-    val args = navInfo.entries
-      .flatMap { entry -> createLightArgsClasses(navInfo, entry) }
-      .toList()
+      val args =
+        navInfo.entries.flatMap { entry -> createLightArgsClasses(navInfo, entry) }.toList()
 
-    Status(directions, args)
-  }
+      Status(directions, args)
+    }
 
   val directions: List<LightDirectionsClass>
     get() = currentStatus?.directions ?: emptyList()
@@ -53,14 +51,20 @@
   val args: List<LightArgsClass>
     get() = currentStatus?.args ?: emptyList()
 
-  private fun createLightDirectionsClasses(navInfo: NavInfo, navEntry: NavEntry): Collection<LightDirectionsClass> {
+  private fun createLightDirectionsClasses(
+    navInfo: NavInfo,
+    navEntry: NavEntry
+  ): Collection<LightDirectionsClass> {
     return navEntry.data.resolvedDestinations
       .filter { destination -> destination.actions.isNotEmpty() }
       .map { destination -> LightDirectionsClass(navInfo, navEntry, destination) }
       .toSet()
   }
 
-  private fun createLightArgsClasses(navInfo: NavInfo, navEntry: NavEntry): Collection<LightArgsClass> {
+  private fun createLightArgsClasses(
+    navInfo: NavInfo,
+    navEntry: NavEntry
+  ): Collection<LightArgsClass> {
     return navEntry.data.resolvedDestinations
       .filter { destination -> destination.arguments.isNotEmpty() }
       .map { destination -> LightArgsClass(navInfo, navEntry, destination) }
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/module/SafeArgsModeModuleService.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/module/SafeArgsModeModuleService.kt
index ce537b6..7fb4b2d 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/module/SafeArgsModeModuleService.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/module/SafeArgsModeModuleService.kt
@@ -30,8 +30,7 @@
 /**
  * Component that owns and updates a module's [SafeArgsMode] state.
  *
- * See also: [SafeArgsModeTrackerProjectService]
- * See also: [safeArgsMode]
+ * See also: [SafeArgsModeTrackerProjectService] See also: [safeArgsMode]
  */
 class SafeArgsModeModuleService(val module: Module) : Disposable.Default {
   fun interface SafeArgsModeChangedListener {
@@ -39,7 +38,8 @@
   }
 
   companion object {
-    fun getInstance(module: Module): SafeArgsModeModuleService = module.getService(SafeArgsModeModuleService::class.java)
+    fun getInstance(module: Module): SafeArgsModeModuleService =
+      module.getService(SafeArgsModeModuleService::class.java)
 
     val MODE_CHANGED: Topic<SafeArgsModeChangedListener> =
       Topic(SafeArgsModeChangedListener::class.java, Topic.BroadcastDirection.TO_CHILDREN, true)
@@ -60,19 +60,23 @@
     // initialized before here, so call update immediately just in case.
     updateSafeArgsMode()
 
-    GradleSyncState.subscribe(module.project, object : GradleSyncListener {
-      override fun syncSucceeded(project: Project) {
-        updateSafeArgsMode()
-      }
+    GradleSyncState.subscribe(
+      module.project,
+      object : GradleSyncListener {
+        override fun syncSucceeded(project: Project) {
+          updateSafeArgsMode()
+        }
 
-      override fun syncFailed(project: Project, errorMessage: String) {
-        updateSafeArgsMode()
-      }
+        override fun syncFailed(project: Project, errorMessage: String) {
+          updateSafeArgsMode()
+        }
 
-      override fun syncSkipped(project: Project) {
-        updateSafeArgsMode()
-      }
-    }, this)
+        override fun syncSkipped(project: Project) {
+          updateSafeArgsMode()
+        }
+      },
+      this
+    )
   }
 
   private fun updateSafeArgsMode() {
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/project/NavigationResourcesModificationListener.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/project/NavigationResourcesModificationListener.kt
index 1c4a172..cf50472 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/project/NavigationResourcesModificationListener.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/project/NavigationResourcesModificationListener.kt
@@ -51,18 +51,16 @@
 import org.jetbrains.annotations.TestOnly
 
 /**
- * A project-wide listener that determines which modules' navigation files are affected by VFS changes or Document
- * changes and sends a [NAVIGATION_RESOURCES_CHANGED] event to tell the corresponding
- * [ModuleNavigationResourcesModificationTracker]s and [ProjectNavigationResourceModificationTracker]s to increment counter.
+ * A project-wide listener that determines which modules' navigation files are affected by VFS
+ * changes or Document changes and sends a [NAVIGATION_RESOURCES_CHANGED] event to tell the
+ * corresponding [ModuleNavigationResourcesModificationTracker]s and
+ * [ProjectNavigationResourceModificationTracker]s to increment counter.
  *
- * [NavigationResourcesModificationListener] registers itself to start actively listening for VFS changes and Document
- * changes after the project opening.
+ * [NavigationResourcesModificationListener] registers itself to start actively listening for VFS
+ * changes and Document changes after the project opening.
  */
-class NavigationResourcesModificationListener(
-  project: Project
-) : PoliteAndroidVirtualFileListener(project),
-    DocumentListener,
-    FileDocumentManagerListener {
+class NavigationResourcesModificationListener(project: Project) :
+  PoliteAndroidVirtualFileListener(project), DocumentListener, FileDocumentManagerListener {
 
   private val psiDocumentManager = PsiDocumentManager.getInstance(project)
   private val fileDocumentManager = FileDocumentManager.getInstance()
@@ -74,7 +72,9 @@
   }
 
   override fun isRelevant(file: VirtualFile, facet: AndroidFacet): Boolean {
-    if (ResourceFolderType.getFolderType(file.parent?.name.orEmpty()) == ResourceFolderType.NAVIGATION) {
+    if (
+      ResourceFolderType.getFolderType(file.parent?.name.orEmpty()) == ResourceFolderType.NAVIGATION
+    ) {
       return true
     }
 
@@ -82,18 +82,20 @@
       return false
     }
 
-    // If module resources aren't cached, we don't want to load them now on the event thread; just say the file is relevant. In the case
-    // where it's not truly relevant but we increment the modification trackers anyway, we may have some unnecessary cache invalidation.
-    val moduleResources = StudioResourceRepositoryManager.getInstance(facet).cachedModuleResources ?: return true
-    val navResourceVfs = moduleResources
-      .getResources(ResourceNamespace.RES_AUTO, ResourceType.NAVIGATION)
-      .values()
-      .mapNotNull(ResourceItem::getSourceAsVirtualFile)
+    // If module resources aren't cached, we don't want to load them now on the event thread; just
+    // say the file is relevant. In the case
+    // where it's not truly relevant but we increment the modification trackers anyway, we may have
+    // some unnecessary cache invalidation.
+    val moduleResources =
+      StudioResourceRepositoryManager.getInstance(facet).cachedModuleResources ?: return true
+    val navResourceVfs =
+      moduleResources
+        .getResources(ResourceNamespace.RES_AUTO, ResourceType.NAVIGATION)
+        .values()
+        .mapNotNull(ResourceItem::getSourceAsVirtualFile)
 
     // If the directory is an ancestor of any navigation resource files.
-    return navResourceVfs.any { navVFile ->
-      VfsUtilCore.isAncestor(file, navVFile, false)
-    }
+    return navResourceVfs.any { navVFile -> VfsUtilCore.isAncestor(file, navVFile, false) }
   }
 
   override fun fileChanged(path: PathString, facet: AndroidFacet) {
@@ -101,7 +103,8 @@
   }
 
   override fun contentsChanged(event: VirtualFileEvent) {
-    // Content changes are not handled at the VFS level but either in fileWithNoDocumentChanged or documentChanged
+    // Content changes are not handled at the VFS level but either in fileWithNoDocumentChanged or
+    // documentChanged
   }
 
   override fun fileWithNoDocumentChanged(file: VirtualFile) = possiblyIrrelevantFileChanged(file)
@@ -112,15 +115,15 @@
 
     if (psiFile == null) {
       fileDocumentManager.getFile(document)?.let { possiblyIrrelevantFileChanged(it) }
-    }
-    else {
+    } else {
       psiFile.virtualFile?.let { possiblyIrrelevantFileChanged(it) }
     }
   }
 
   /**
-   * [StartupActivity] responsible for ensuring that a [Project] has a [NavigationResourcesModificationListener]
-   * subscribed to listen for both VFS and Document changes when opening projects.
+   * [StartupActivity] responsible for ensuring that a [Project] has a
+   * [NavigationResourcesModificationListener] subscribed to listen for both VFS and Document
+   * changes when opening projects.
    */
   class SubscriptionStartupActivity : ProjectActivity {
     override suspend fun execute(project: Project) {
@@ -131,9 +134,11 @@
   @Service(Service.Level.PROJECT)
   private class Subscriber(private val project: Project) : Disposable.Default {
     private val subscriber =
-      object : LazyFileListenerSubscriber<NavigationResourcesModificationListener>(
-        NavigationResourcesModificationListener(project), this
-      ) {
+      object :
+        LazyFileListenerSubscriber<NavigationResourcesModificationListener>(
+          NavigationResourcesModificationListener(project),
+          this
+        ) {
         override fun subscribe() {
           // To receive all changes happening in the VFS. File modifications may
           // not be picked up immediately if such changes are not saved on the disk yet
@@ -158,14 +163,15 @@
   }
 
   private fun dispatchResourcesChanged(module: Module?) {
-    project.messageBus.syncPublisher(NAVIGATION_RESOURCES_CHANGED).onNavigationResourcesChanged(module)
+    project.messageBus
+      .syncPublisher(NAVIGATION_RESOURCES_CHANGED)
+      .onNavigationResourcesChanged(module)
   }
 
   companion object {
     /**
-     * Normally, this listener waits for the project to finish syncing before subscribing
-     * to events, but for tests, we sometimes have to kickstart the subscription process
-     * manually.
+     * Normally, this listener waits for the project to finish syncing before subscribing to events,
+     * but for tests, we sometimes have to kickstart the subscription process manually.
      */
     @TestOnly
     fun ensureSubscribed(project: Project) {
@@ -178,7 +184,8 @@
   /**
    * Called when the navigation resources for a given module have changed.
    *
-   * If [module] is `null`, this is the result of a project-wide change, and all modules should be considered changed.
+   * If [module] is `null`, this is the result of a project-wide change, and all modules should be
+   * considered changed.
    */
   fun onNavigationResourcesChanged(module: Module?)
 }
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/project/ProjectNavigationResourceModificationTracker.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/project/ProjectNavigationResourceModificationTracker.kt
index 1af55a3..5a13bb0 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/project/ProjectNavigationResourceModificationTracker.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/project/ProjectNavigationResourceModificationTracker.kt
@@ -16,39 +16,40 @@
 package com.android.tools.idea.nav.safeargs.project
 
 import com.intellij.openapi.Disposable
-import com.intellij.openapi.project.DumbService
 import com.intellij.openapi.project.Project
-import com.intellij.openapi.startup.StartupManager
 import com.intellij.openapi.util.ModificationTracker
 import com.intellij.openapi.util.SimpleModificationTracker
 
 /**
- * A project-wide modification tracker whose modification count is a value incremented by any modifications of
- * corresponding navigation resource files.
+ * A project-wide modification tracker whose modification count is a value incremented by any
+ * modifications of corresponding navigation resource files.
  */
-class ProjectNavigationResourceModificationTracker(project: Project) : ModificationTracker, Disposable.Default {
+class ProjectNavigationResourceModificationTracker(project: Project) :
+  ModificationTracker, Disposable.Default {
   private val navigationModificationTracker = SimpleModificationTracker()
 
   init {
-    project.messageBus.connect(this).subscribe(
-      NAVIGATION_RESOURCES_CHANGED,
-      NavigationResourcesChangeListener {
-        navigationChanged()
-      }
-    )
+    project.messageBus
+      .connect(this)
+      .subscribe(
+        NAVIGATION_RESOURCES_CHANGED,
+        NavigationResourcesChangeListener { navigationChanged() }
+      )
   }
 
   companion object {
     @JvmStatic
-    fun getInstance(project: Project) = project.getService(ProjectNavigationResourceModificationTracker::class.java)!!
+    fun getInstance(project: Project) =
+      project.getService(ProjectNavigationResourceModificationTracker::class.java)!!
   }
 
   override fun getModificationCount() = navigationModificationTracker.modificationCount
 
   /**
-   * This is invoked when NavigationModificationListener detects a navigation file has been changed or added or deleted for this project
+   * This is invoked when NavigationModificationListener detects a navigation file has been changed
+   * or added or deleted for this project
    */
   private fun navigationChanged() {
     navigationModificationTracker.incModificationCount()
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/project/SafeArgsEnabledFacetsProjectService.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/project/SafeArgsEnabledFacetsProjectService.kt
index 1db87bc..d6c3828 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/project/SafeArgsEnabledFacetsProjectService.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/project/SafeArgsEnabledFacetsProjectService.kt
@@ -28,17 +28,17 @@
 import org.jetbrains.android.facet.AndroidFacet
 
 /**
- * Component that tracks / caches all [AndroidFacet] instances that have enabled
- * safe args on them, for quick iteration in light class short names caches and
- * class finders.
+ * Component that tracks / caches all [AndroidFacet] instances that have enabled safe args on them,
+ * for quick iteration in light class short names caches and class finders.
  *
- * This component also serves as a [ModificationTracker] that will allow caches
- * to know when this list might have been updated.
+ * This component also serves as a [ModificationTracker] that will allow caches to know when this
+ * list might have been updated.
  */
 @Service
 class SafeArgsEnabledFacetsProjectService(val project: Project) : ModificationTracker {
   companion object {
-    fun getInstance(project: Project): SafeArgsEnabledFacetsProjectService = project.getService(SafeArgsEnabledFacetsProjectService::class.java)
+    fun getInstance(project: Project): SafeArgsEnabledFacetsProjectService =
+      project.getService(SafeArgsEnabledFacetsProjectService::class.java)
   }
 
   private val modulesUsingSafeArgsCache: CachedValue<List<AndroidFacet>>
@@ -49,14 +49,19 @@
     val cachedValuesManager = CachedValuesManager.getManager(project)
     val facetManager = ProjectFacetManager.getInstance(project)
 
-    modulesUsingSafeArgsCache = cachedValuesManager.createCachedValue(
-      {
-        val facets = facetManager.getFacets(AndroidFacet.ID)
-          .filter { facet -> facet.isSafeArgsEnabled() }
+    modulesUsingSafeArgsCache =
+      cachedValuesManager.createCachedValue(
+        {
+          val facets =
+            facetManager.getFacets(AndroidFacet.ID).filter { facet -> facet.isSafeArgsEnabled() }
 
-        CachedValueProvider.Result.create(facets, this)
-      }, false)
+          CachedValueProvider.Result.create(facets, this)
+        },
+        false
+      )
   }
 
-  override fun getModificationCount() = ModuleManager.getInstance(project).modificationCount + project.safeArgsModeTracker.modificationCount
-}
\ No newline at end of file
+  override fun getModificationCount() =
+    ModuleManager.getInstance(project).modificationCount +
+      project.safeArgsModeTracker.modificationCount
+}
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/project/SafeArgsModeTrackerProjectService.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/project/SafeArgsModeTrackerProjectService.kt
index d8178ff..40e9f1f 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/project/SafeArgsModeTrackerProjectService.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/project/SafeArgsModeTrackerProjectService.kt
@@ -28,28 +28,29 @@
  * Component that owns a project-wide tracker which gets updated whenever any module's
  * `safeArgsMode` is updated.
  *
- * See also: [SafeArgsModeModuleService]
- * See also: [safeArgsModeTracker]
+ * See also: [SafeArgsModeModuleService] See also: [safeArgsModeTracker]
  */
 @ThreadSafe
 @Service(Service.Level.PROJECT)
-class SafeArgsModeTrackerProjectService(project: Project) : ModificationTracker, Disposable.Default {
+class SafeArgsModeTrackerProjectService(project: Project) :
+  ModificationTracker, Disposable.Default {
   companion object {
-    fun getInstance(project: Project) = project.getService(SafeArgsModeTrackerProjectService::class.java)!!
+    fun getInstance(project: Project) =
+      project.getService(SafeArgsModeTrackerProjectService::class.java)!!
   }
 
   init {
-    project.messageBus.connect(this).subscribe(
-      SafeArgsModeModuleService.MODE_CHANGED,
-      SafeArgsModeModuleService.SafeArgsModeChangedListener { _, _ ->
-        tracker.incModificationCount()
-      }
-    )
+    project.messageBus
+      .connect(this)
+      .subscribe(
+        SafeArgsModeModuleService.MODE_CHANGED,
+        SafeArgsModeModuleService.SafeArgsModeChangedListener { _, _ ->
+          tracker.incModificationCount()
+        }
+      )
   }
 
-  /**
-   * A thread-safe modification tracker that should get updated
-   */
+  /** A thread-safe modification tracker that should get updated */
   private val tracker = SimpleModificationTracker()
 
   override fun getModificationCount(): Long = tracker.modificationCount
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/ArgumentUtils.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/ArgumentUtils.kt
index bd3fe06..50852a5 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/ArgumentUtils.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/ArgumentUtils.kt
@@ -1,4 +1,5 @@
-// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the
+// Apache 2.0 license.
 package com.android.tools.idea.nav.safeargs.psi
 
 import com.android.tools.idea.nav.safeargs.index.NavActionData
@@ -34,18 +35,20 @@
 
       val argsFromTargetDestination = action.getTargetDestination(data)?.arguments.orEmpty()
 
-      val resolvedArguments = (action.arguments + argsFromTargetDestination)
-        .groupBy { it.name }
-        .map { entry ->
-          if (entry.value.size > 1) checkArguments(entry, modulePackage)
-          entry.value.first()
-        }
+      val resolvedArguments =
+        (action.arguments + argsFromTargetDestination)
+          .groupBy { it.name }
+          .map { entry ->
+            if (entry.value.size > 1) checkArguments(entry, modulePackage)
+            entry.value.first()
+          }
 
-      val adjustedArguments = if (adjustArgumentsWithDefaults) {
-        resolvedArguments.sortedBy { it.defaultValue != null }
-      } else {
-        resolvedArguments
-      }
+      val adjustedArguments =
+        if (adjustArgumentsWithDefaults) {
+          resolvedArguments.sortedBy { it.defaultValue != null }
+        } else {
+          resolvedArguments
+        }
 
       return@mapNotNull object : NavActionData by action {
         override val arguments: List<NavArgumentData> = adjustedArguments
@@ -53,15 +56,21 @@
     }
 
   /**
-   * Warn if incompatible types of argument exist. We still provide best results though it fails to compile.
+   * Warn if incompatible types of argument exist. We still provide best results though it fails to
+   * compile.
    */
-  private fun checkArguments(entry: Map.Entry<String, List<NavArgumentData>>, modulePackage: String) {
-    val types = entry.value
-      .asSequence()
-      .map { arg -> getPsiTypeStr(modulePackage, arg.type, arg.defaultValue) }
-      .toSet()
+  private fun checkArguments(
+    entry: Map.Entry<String, List<NavArgumentData>>,
+    modulePackage: String
+  ) {
+    val types =
+      entry.value
+        .asSequence()
+        .map { arg -> getPsiTypeStr(modulePackage, arg.type, arg.defaultValue) }
+        .toSet()
 
-    if (types.size > 1) LOG.warn("Incompatible types of argument ${entry.key}: ${types.joinToString(", ")}.")
+    if (types.size > 1)
+      LOG.warn("Incompatible types of argument ${entry.key}: ${types.joinToString(", ")}.")
   }
 
   private val LOG = thisLogger()
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/SafeArgsFeatureVersions.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/SafeArgsFeatureVersions.kt
index 6c26c45..d43ae8e 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/SafeArgsFeatureVersions.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/SafeArgsFeatureVersions.kt
@@ -37,8 +37,8 @@
  */
 internal fun AndroidFacet.findNavigationVersion(): Version {
   return module
-           .getModuleSystem()
-           .getResolvedDependency(GoogleMavenArtifactId.ANDROIDX_NAVIGATION_COMMON.getCoordinate("+"))
-           ?.lowerBoundVersion
-         ?: GRADLE_VERSION_ZERO
+    .getModuleSystem()
+    .getResolvedDependency(GoogleMavenArtifactId.ANDROIDX_NAVIGATION_COMMON.getCoordinate("+"))
+    ?.lowerBoundVersion
+    ?: GRADLE_VERSION_ZERO
 }
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightActionBuilderClass.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightActionBuilderClass.kt
index 6fcecc6..f11a882 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightActionBuilderClass.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightActionBuilderClass.kt
@@ -21,7 +21,6 @@
 import com.android.tools.idea.nav.safeargs.psi.xml.findChildTagElementByNameAttr
 import com.android.tools.idea.nav.safeargs.psi.xml.findFirstMatchingElementByTraversingUp
 import com.android.tools.idea.nav.safeargs.psi.xml.findXmlTagById
-import com.android.utils.usLocaleCapitalize
 import com.intellij.psi.JavaPsiFacade
 import com.intellij.psi.PsiElement
 import com.intellij.psi.PsiField
@@ -33,7 +32,6 @@
 import com.intellij.psi.xml.XmlFile
 import com.intellij.psi.xml.XmlTag
 import org.jetbrains.android.augment.AndroidLightClassBase
-import org.jetbrains.android.facet.AndroidFacet
 
 /**
  * Inner class that is generated inside a Directions class, which helps build actions.
@@ -46,17 +44,28 @@
   private val directionsClass: LightDirectionsClass,
   private val action: NavActionData,
   private val backingResourceFile: XmlFile?,
-) : AndroidLightClassBase(PsiManager.getInstance(navInfo.facet.module.project), setOf(PsiModifier.PUBLIC, PsiModifier.STATIC)) {
+) :
+  AndroidLightClassBase(
+    PsiManager.getInstance(navInfo.facet.module.project),
+    setOf(PsiModifier.PUBLIC, PsiModifier.STATIC)
+  ) {
   private val NAV_DIRECTIONS_FQCN = "androidx.navigation.NavDirections"
   private val name: String = className
   private val qualifiedName: String = "${directionsClass.qualifiedName}.$name"
   private val _constructors by lazy { computeConstructors() }
   private val _methods by lazy { computeMethods() }
   private val _fields by lazy { computeFields() }
-  private val navDirectionsType by lazy { PsiType.getTypeByName(NAV_DIRECTIONS_FQCN, project, this.resolveScope) }
-  private val navDirectionsClass by lazy { JavaPsiFacade.getInstance(project).findClass(NAV_DIRECTIONS_FQCN, this.resolveScope) }
+  private val navDirectionsType by lazy {
+    PsiType.getTypeByName(NAV_DIRECTIONS_FQCN, project, this.resolveScope)
+  }
+  private val navDirectionsClass by lazy {
+    JavaPsiFacade.getInstance(project).findClass(NAV_DIRECTIONS_FQCN, this.resolveScope)
+  }
   private val _navigationElement by lazy {
-    (directionsClass.navigationElement as? XmlTag)?.findFirstMatchingElementByTraversingUp(SdkConstants.TAG_ACTION, action.id)
+    (directionsClass.navigationElement as? XmlTag)?.findFirstMatchingElementByTraversingUp(
+      SdkConstants.TAG_ACTION,
+      action.id
+    )
   }
 
   override fun getName() = name
@@ -81,32 +90,41 @@
   private fun computeMethods(): Array<PsiMethod> {
     val thisType = PsiTypesUtil.getClassType(this)
 
-    return action.arguments.flatMap { arg ->
-      // Create a getter and setter per argument
-      val argType = arg.parsePsiType(navInfo.packageName, this)
-      val setter = createMethod(name = "set${arg.name.toUpperCamelCase()}",
-                                navigationElement = getFieldNavigationElementByName(arg.name),
-                                returnType = annotateNullability(thisType))
-        .addParameter(arg.name.toCamelCase(), argType)
+    return action.arguments
+      .flatMap { arg ->
+        // Create a getter and setter per argument
+        val argType = arg.parsePsiType(navInfo.packageName, this)
+        val setter =
+          createMethod(
+              name = "set${arg.name.toUpperCamelCase()}",
+              navigationElement = getFieldNavigationElementByName(arg.name),
+              returnType = annotateNullability(thisType)
+            )
+            .addParameter(arg.name.toCamelCase(), argType)
 
-      val getter = createMethod(name = "get${arg.name.toUpperCamelCase()}",
-                                navigationElement = getFieldNavigationElementByName(arg.name),
-                                returnType = annotateNullability(argType, arg.isNonNull()))
+        val getter =
+          createMethod(
+            name = "get${arg.name.toUpperCamelCase()}",
+            navigationElement = getFieldNavigationElementByName(arg.name),
+            returnType = annotateNullability(argType, arg.isNonNull())
+          )
 
-      listOf(setter, getter)
-    }.toTypedArray()
+        listOf(setter, getter)
+      }
+      .toTypedArray()
   }
 
   private fun computeConstructors(): Array<PsiMethod> {
-    val privateConstructor = createConstructor().apply {
-      action.arguments.forEach { arg ->
-        if (arg.defaultValue == null) {
-          val argType = arg.parsePsiType(navInfo.packageName, this)
-          this.addParameter(arg.name.toCamelCase(), argType)
+    val privateConstructor =
+      createConstructor().apply {
+        action.arguments.forEach { arg ->
+          if (arg.defaultValue == null) {
+            val argType = arg.parsePsiType(navInfo.packageName, this)
+            this.addParameter(arg.name.toCamelCase(), argType)
+          }
         }
+        this.setModifiers(PsiModifier.PRIVATE)
       }
-      this.setModifiers(PsiModifier.PRIVATE)
-    }
 
     return arrayOf(privateConstructor)
   }
@@ -117,10 +135,15 @@
     return action.arguments
       .asSequence()
       .map { arg ->
-        // Since we support args overrides, we first try to locate argument tag within current action. If not found,
+        // Since we support args overrides, we first try to locate argument tag within current
+        // action. If not found,
         // we search in the target destination tag.
-        val targetArgumentTag = _navigationElement?.findChildTagElementByNameAttr(SdkConstants.TAG_ARGUMENT, arg.name)
-                                ?: targetDestinationTag?.findChildTagElementByNameAttr(SdkConstants.TAG_ARGUMENT, arg.name)
+        val targetArgumentTag =
+          _navigationElement?.findChildTagElementByNameAttr(SdkConstants.TAG_ARGUMENT, arg.name)
+            ?: targetDestinationTag?.findChildTagElementByNameAttr(
+              SdkConstants.TAG_ARGUMENT,
+              arg.name
+            )
         createField(arg, navInfo.packageName, targetArgumentTag)
       }
       .toList()
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsBuilderClass.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsBuilderClass.kt
index d68e1f2..ba0df98 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsBuilderClass.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsBuilderClass.kt
@@ -21,13 +21,11 @@
 import com.intellij.psi.PsiModifier
 import com.intellij.psi.util.PsiTypesUtil
 import org.jetbrains.android.augment.AndroidLightClassBase
-import org.jetbrains.android.facet.AndroidFacet
 
 /**
  * Light class for Args.Builder classes generated from navigation xml files.
  *
  * For example, if you had the following "nav.xml":
- *
  * ```
  *  <action id="@+id/sendMessage" destination="@+id/editorFragment">
  *    <argument name="message" argType="string" />
@@ -36,7 +34,6 @@
  * ```
  *
  * This would generate a builder class like the following:
- *
  * ```
  *  class EditorFragmentArgs {
  *    static class Builder {
@@ -57,7 +54,11 @@
 class LightArgsBuilderClass(
   private val navInfo: NavInfo,
   private val argsClass: LightArgsClass,
-) : AndroidLightClassBase(PsiManager.getInstance(navInfo.facet.module.project), setOf(PsiModifier.PUBLIC, PsiModifier.STATIC)) {
+) :
+  AndroidLightClassBase(
+    PsiManager.getInstance(navInfo.facet.module.project),
+    setOf(PsiModifier.PUBLIC, PsiModifier.STATIC)
+  ) {
   companion object {
     const val BUILDER_NAME = "Builder"
   }
@@ -84,16 +85,17 @@
   }
 
   private fun computeConstructors(): Array<PsiMethod> {
-    val copyConstructor = createConstructor()
-      .addParameter("original", PsiTypesUtil.getClassType(argsClass))
+    val copyConstructor =
+      createConstructor().addParameter("original", PsiTypesUtil.getClassType(argsClass))
 
-    val argsConstructor = createConstructor().apply {
-      argsClass.destination.arguments.forEach { arg ->
-        if (arg.defaultValue == null) {
-          this.addParameter(arg.name.toCamelCase(), arg.parsePsiType(navInfo.packageName, this))
+    val argsConstructor =
+      createConstructor().apply {
+        argsClass.destination.arguments.forEach { arg ->
+          if (arg.defaultValue == null) {
+            this.addParameter(arg.name.toCamelCase(), arg.parsePsiType(navInfo.packageName, this))
+          }
         }
       }
-    }
 
     return arrayOf(copyConstructor, argsConstructor)
   }
@@ -102,21 +104,34 @@
     val thisType = PsiTypesUtil.getClassType(this)
 
     // Create a getter and setter per argument
-    val argMethods: Array<PsiMethod> = containingClass.destination.arguments.flatMap { arg ->
-      val argType = arg.parsePsiType(navInfo.packageName, this)
-      val setter = createMethod(name = "set${arg.name.toUpperCamelCase()}",
-                                navigationElement = containingClass.getFieldNavigationElementByName(arg.name),
-                                returnType = annotateNullability(thisType))
-        .addParameter(arg.name.toCamelCase(), argType)
+    val argMethods: Array<PsiMethod> =
+      containingClass.destination.arguments
+        .flatMap { arg ->
+          val argType = arg.parsePsiType(navInfo.packageName, this)
+          val setter =
+            createMethod(
+                name = "set${arg.name.toUpperCamelCase()}",
+                navigationElement = containingClass.getFieldNavigationElementByName(arg.name),
+                returnType = annotateNullability(thisType)
+              )
+              .addParameter(arg.name.toCamelCase(), argType)
 
-      val getter = createMethod(name = "get${arg.name.toUpperCamelCase()}",
-                                navigationElement = containingClass.getFieldNavigationElementByName(arg.name),
-                                returnType = annotateNullability(argType, arg.isNonNull()))
+          val getter =
+            createMethod(
+              name = "get${arg.name.toUpperCamelCase()}",
+              navigationElement = containingClass.getFieldNavigationElementByName(arg.name),
+              returnType = annotateNullability(argType, arg.isNonNull())
+            )
 
-      listOf(setter, getter)
-    }.toTypedArray()
+          listOf(setter, getter)
+        }
+        .toTypedArray()
 
-    val build = createMethod(name = "build", returnType = annotateNullability(PsiTypesUtil.getClassType(argsClass)))
+    val build =
+      createMethod(
+        name = "build",
+        returnType = annotateNullability(PsiTypesUtil.getClassType(argsClass))
+      )
     return argMethods + build
   }
 }
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsClass.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsClass.kt
index a785b42..156ac70 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsClass.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsClass.kt
@@ -36,7 +36,6 @@
  * An "Arg" represents an argument which can get passed from one destination to another.
  *
  * For example, if you had the following "nav.xml":
- *
  * ```
  * <argument
  *    android:name="message"
@@ -44,7 +43,6 @@
  * ```
  *
  * This would generate a class like the following:
- *
  * ```
  *  class EditorFragmentArgs implements NavArgs {
  *    static EditorFragmentArgs fromBundle(Bundle bundle);
@@ -66,8 +64,12 @@
   private val _fields by lazy { computeFields() }
   private val _methods by lazy { computeMethods() }
   private val backingXmlTag by lazy { navEntry.backingXmlFile?.findXmlTagById(destination.id) }
-  private val navArgsType by lazy { PsiType.getTypeByName(NAV_ARGS_FQCN, project, this.resolveScope) }
-  private val navArgsClass by lazy { JavaPsiFacade.getInstance(project).findClass(NAV_ARGS_FQCN, this.resolveScope) }
+  private val navArgsType by lazy {
+    PsiType.getTypeByName(NAV_ARGS_FQCN, project, this.resolveScope)
+  }
+  private val navArgsClass by lazy {
+    JavaPsiFacade.getInstance(project).findClass(NAV_ARGS_FQCN, this.resolveScope)
+  }
 
   override fun getImplementsListTypes() = arrayOf(navArgsType)
   override fun getSuperTypes() = arrayOf(navArgsType)
@@ -91,42 +93,56 @@
   private fun computeMethods(): Array<PsiMethod> {
     val thisType = PsiTypesUtil.getClassType(this)
     val bundleType = parsePsiType(navInfo.packageName, "android.os.Bundle", null, this)
-    val savedStateHandleType = parsePsiType(navInfo.packageName, "androidx.lifecycle.SavedStateHandle", null, this)
+    val savedStateHandleType =
+      parsePsiType(navInfo.packageName, "androidx.lifecycle.SavedStateHandle", null, this)
 
     val methods = mutableListOf<PsiMethod>()
 
-    methods.addAll(destination.arguments.map { arg ->
-      val psiType = arg.parsePsiType(navInfo.packageName, this)
-      createMethod(name = "get${arg.name.toUpperCamelCase()}",
-                   navigationElement = getFieldNavigationElementByName(arg.name),
-                   returnType = annotateNullability(psiType, arg.isNonNull()))
-    })
+    methods.addAll(
+      destination.arguments.map { arg ->
+        val psiType = arg.parsePsiType(navInfo.packageName, this)
+        createMethod(
+          name = "get${arg.name.toUpperCamelCase()}",
+          navigationElement = getFieldNavigationElementByName(arg.name),
+          returnType = annotateNullability(psiType, arg.isNonNull())
+        )
+      }
+    )
 
-    methods.add(createMethod(name = "fromBundle",
-                             modifiers = MODIFIERS_STATIC_PUBLIC_METHOD,
-                             returnType = annotateNullability(thisType))
-                  .addParameter("bundle", bundleType))
+    methods.add(
+      createMethod(
+          name = "fromBundle",
+          modifiers = MODIFIERS_STATIC_PUBLIC_METHOD,
+          returnType = annotateNullability(thisType)
+        )
+        .addParameter("bundle", bundleType)
+    )
 
-    // Add on version specific methods since the navigation library side is keeping introducing new methods.
+    // Add on version specific methods since the navigation library side is keeping introducing new
+    // methods.
     if (navInfo.navVersion >= SafeArgsFeatureVersions.FROM_SAVED_STATE_HANDLE) {
       methods.add(
         createMethod(
-          name = "fromSavedStateHandle",
-          modifiers = MODIFIERS_STATIC_PUBLIC_METHOD,
-          returnType = annotateNullability(thisType)
-        ).addParameter("savedStateHandle", savedStateHandleType)
+            name = "fromSavedStateHandle",
+            modifiers = MODIFIERS_STATIC_PUBLIC_METHOD,
+            returnType = annotateNullability(thisType)
+          )
+          .addParameter("savedStateHandle", savedStateHandleType)
       )
     }
 
-    // Add on version specific methods since the navigation library side is keeping introducing new methods.
+    // Add on version specific methods since the navigation library side is keeping introducing new
+    // methods.
     if (navInfo.navVersion >= SafeArgsFeatureVersions.TO_SAVED_STATE_HANDLE) {
-      methods.add(createMethod(name = "toSavedStateHandle", returnType = annotateNullability(savedStateHandleType)))
+      methods.add(
+        createMethod(
+          name = "toSavedStateHandle",
+          returnType = annotateNullability(savedStateHandleType)
+        )
+      )
     }
 
-    methods.add(createMethod(
-      name = "toBundle",
-      returnType = annotateNullability(bundleType)
-    ))
+    methods.add(createMethod(name = "toBundle", returnType = annotateNullability(bundleType)))
 
     return methods.toTypedArray()
   }
@@ -135,7 +151,8 @@
     return destination.arguments
       .asSequence()
       .map { arg ->
-        val targetArgumentTag = backingXmlTag?.findChildTagElementByNameAttr(SdkConstants.TAG_ARGUMENT, arg.name)
+        val targetArgumentTag =
+          backingXmlTag?.findChildTagElementByNameAttr(SdkConstants.TAG_ARGUMENT, arg.name)
         createField(arg, navInfo.packageName, targetArgumentTag)
       }
       .toList()
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightDirectionsClass.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightDirectionsClass.kt
index 55872ca..eb53895 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightDirectionsClass.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightDirectionsClass.kt
@@ -35,7 +35,6 @@
  * A "Direction" represents functionality that takes you away from one destination to another.
  *
  * For example, if you had the following "nav.xml":
- *
  * ```
  *  <navigation>
  *    <fragment id="@+id/mainMenu">
@@ -54,7 +53,6 @@
  * ```
  *
  * This would generate a class like the following:
- *
  * ```
  *  class MainMenuDirections {
  *    static NavDirections actionToOptions();
@@ -71,16 +69,16 @@
  *
  * ```
  */
-class LightDirectionsClass(
-  navInfo: NavInfo,
-  navEntry: NavEntry,
-  destination: NavDestinationData
-) : SafeArgsLightBaseClass(navInfo, navEntry, destination, "Directions") {
-  private val LOG get() = Logger.getInstance(LightDirectionsClass::class.java)
+class LightDirectionsClass(navInfo: NavInfo, navEntry: NavEntry, destination: NavDestinationData) :
+  SafeArgsLightBaseClass(navInfo, navEntry, destination, "Directions") {
+  private val LOG
+    get() = Logger.getInstance(LightDirectionsClass::class.java)
   private val actionClasses by lazy { computeInnerClasses() }
   private val _methods by lazy { computeMethods() }
   private val _navigationElement by lazy { navEntry.backingXmlFile?.findXmlTagById(destination.id) }
-  private val _actions by lazy { destination.getActionsWithResolvedArguments(navEntry.data, navInfo.packageName) }
+  private val _actions by lazy {
+    destination.getActionsWithResolvedArguments(navEntry.data, navInfo.packageName)
+  }
 
   override fun getMethods() = _methods
   override fun getAllMethods() = methods
@@ -99,18 +97,27 @@
   }
 
   private fun computeMethods(): Array<PsiMethod> {
-    val navDirectionsType = parsePsiType(navInfo.packageName, "androidx.navigation.NavDirections", null, this)
+    val navDirectionsType =
+      parsePsiType(navInfo.packageName, "androidx.navigation.NavDirections", null, this)
     return _actions
       .map { action ->
         val methodName = action.id.toCamelCase()
-        val resolvedNavigationElement = _navigationElement?.findFirstMatchingElementByTraversingUp(SdkConstants.TAG_ACTION, action.id)
-        val resolvedNavDirectionsType = actionClasses.find { it.name!!.usLocaleDecapitalize() == methodName }
-                                          ?.let { PsiTypesUtil.getClassType(it) }
-                                        ?: navDirectionsType
-        createMethod(name = methodName,
-                     navigationElement = resolvedNavigationElement,
-                     modifiers = MODIFIERS_STATIC_PUBLIC_METHOD,
-                     returnType = annotateNullability(resolvedNavDirectionsType))
+        val resolvedNavigationElement =
+          _navigationElement?.findFirstMatchingElementByTraversingUp(
+            SdkConstants.TAG_ACTION,
+            action.id
+          )
+        val resolvedNavDirectionsType =
+          actionClasses
+            .find { it.name!!.usLocaleDecapitalize() == methodName }
+            ?.let { PsiTypesUtil.getClassType(it) }
+            ?: navDirectionsType
+        createMethod(
+            name = methodName,
+            navigationElement = resolvedNavigationElement,
+            modifiers = MODIFIERS_STATIC_PUBLIC_METHOD,
+            returnType = annotateNullability(resolvedNavDirectionsType)
+          )
           .apply {
             action.arguments.forEach { arg ->
               if (arg.defaultValue == null) {
@@ -119,8 +126,8 @@
               }
             }
           }
-
-      }.toTypedArray()
+      }
+      .toTypedArray()
   }
 
   private fun computeInnerClasses(): Array<PsiClass> {
@@ -133,6 +140,4 @@
       }
       .toTypedArray()
   }
-
 }
-
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/SafeArgsLightBaseClass.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/SafeArgsLightBaseClass.kt
index 70cbbc5..b1e38cf 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/SafeArgsLightBaseClass.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/SafeArgsLightBaseClass.kt
@@ -15,11 +15,9 @@
  */
 package com.android.tools.idea.nav.safeargs.psi.java
 
-import com.android.ide.common.resources.ResourceItem
 import com.android.tools.idea.nav.safeargs.index.NavDestinationData
 import com.android.tools.idea.nav.safeargs.module.NavEntry
 import com.android.tools.idea.nav.safeargs.module.NavInfo
-import com.android.tools.idea.res.getSourceAsVirtualFile
 import com.intellij.ide.highlighter.JavaFileType
 import com.intellij.psi.PsiClass
 import com.intellij.psi.PsiElement
@@ -27,19 +25,19 @@
 import com.intellij.psi.PsiJavaFile
 import com.intellij.psi.PsiManager
 import com.intellij.psi.PsiModifier
-import com.intellij.psi.xml.XmlFile
 import org.jetbrains.android.augment.AndroidLightClassBase
-import org.jetbrains.android.facet.AndroidFacet
 
-/**
- * Common functionality for all safe args light classes.
- */
+/** Common functionality for all safe args light classes. */
 abstract class SafeArgsLightBaseClass(
   protected val navInfo: NavInfo,
   protected val navEntry: NavEntry,
   val destination: NavDestinationData,
   suffix: String,
-) : AndroidLightClassBase(PsiManager.getInstance(navInfo.facet.module.project), setOf(PsiModifier.PUBLIC, PsiModifier.FINAL)) {
+) :
+  AndroidLightClassBase(
+    PsiManager.getInstance(navInfo.facet.module.project),
+    setOf(PsiModifier.PUBLIC, PsiModifier.FINAL)
+  ) {
 
   private val name: String
   private val qualifiedName: String
@@ -49,15 +47,20 @@
     super.setModuleInfo(navInfo.facet.module, false)
     val fileFactory = PsiFileFactory.getInstance(project)
 
-    qualifiedName = destination.name.let { name ->
-      val nameWithoutSuffix = if (!name.startsWith('.')) name else "${navInfo.packageName}$name"
-      "$nameWithoutSuffix$suffix"
-    }
+    qualifiedName =
+      destination.name.let { name ->
+        val nameWithoutSuffix = if (!name.startsWith('.')) name else "${navInfo.packageName}$name"
+        "$nameWithoutSuffix$suffix"
+      }
     name = qualifiedName.substringAfterLast('.')
 
     // Create a placeholder backing file to represent this light class
-    backingFile = fileFactory.createFileFromText("${name}.java", JavaFileType.INSTANCE,
-                                                 "// This class is generated on-the-fly by the IDE.") as PsiJavaFile
+    backingFile =
+      fileFactory.createFileFromText(
+        "${name}.java",
+        JavaFileType.INSTANCE,
+        "// This class is generated on-the-fly by the IDE."
+      ) as PsiJavaFile
     backingFile.packageName = (qualifiedName.substringBeforeLast('.'))
   }
 
@@ -69,4 +72,4 @@
   override fun getNavigationElement(): PsiElement {
     return navEntry.backingXmlFile ?: return super.getNavigationElement()
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/SafeArgsLightClassUtils.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/SafeArgsLightClassUtils.kt
index 2360259..9ce53fc 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/SafeArgsLightClassUtils.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/java/SafeArgsLightClassUtils.kt
@@ -41,38 +41,42 @@
 private const val INT_ARRAY = "int[]"
 private const val FALLBACK_TYPE = STRING_FQCN
 
-private val NAV_TO_JAVA_TYPE_MAP = mapOf(
-  "string" to STRING_FQCN,
-  "string[]" to STRING_FQCN_ARRAY,
-  "integer" to PsiTypes.intType().name,
-  "integer[]" to INT_ARRAY,
-  "reference" to PsiTypes.intType().name,
-  "reference[]" to INT_ARRAY
-)
+private val NAV_TO_JAVA_TYPE_MAP =
+  mapOf(
+    "string" to STRING_FQCN,
+    "string[]" to STRING_FQCN_ARRAY,
+    "integer" to PsiTypes.intType().name,
+    "integer[]" to INT_ARRAY,
+    "reference" to PsiTypes.intType().name,
+    "reference[]" to INT_ARRAY
+  )
 
 /**
- * Given type strings we pull out of navigation xml files, generate a corresponding [PsiType]
- * for them.
+ * Given type strings we pull out of navigation xml files, generate a corresponding [PsiType] for
+ * them.
  *
  * @param modulePackage The current package that safe args are being generated into. This will be
- *    used if `typeStr` is specified with a relative path name (i.e. if it starts with '.')
+ *   used if `typeStr` is specified with a relative path name (i.e. if it starts with '.')
  * @param context The [PsiElement] context we are in when creating this [PsiType] -- this is needed
- *    for IntelliJ machinery.
+ *   for IntelliJ machinery.
  * @param typeStr A String of the type we want to create, e.g. "com.example.SomeClass". This value
- *    can start with a '.', e.g. ".util.SomeClass", at which point it will be placed within the
- *    current module package. This value can also be a special type as documented here:
- *    https://developer.android.com/guide/navigation/navigation-pass-data#supported_argument_types
- *    If null, `defaultValue` will be used to infer the type.
+ *   can start with a '.', e.g. ".util.SomeClass", at which point it will be placed within the
+ *   current module package. This value can also be a special type as documented here:
+ *   https://developer.android.com/guide/navigation/navigation-pass-data#supported_argument_types If
+ *   null, `defaultValue` will be used to infer the type.
  * @param defaultValue The default value specified for this type. This is used as a fallback if
- *    `typeStr` itself is not specified.
- *
+ *   `typeStr` itself is not specified.
  */
-fun parsePsiType(modulePackage: String, typeStr: String?, defaultValue: String?, context: PsiElement): PsiType {
+fun parsePsiType(
+  modulePackage: String,
+  typeStr: String?,
+  defaultValue: String?,
+  context: PsiElement
+): PsiType {
   val psiTypeStr = getPsiTypeStr(modulePackage, typeStr, defaultValue)
   return try {
     PsiElementFactory.getInstance(context.project).createTypeFromText(psiTypeStr, context)
-  }
-  catch (e: IncorrectOperationException) {
+  } catch (e: IncorrectOperationException) {
     PsiElementFactory.getInstance(context.project).createTypeFromText(FALLBACK_TYPE, context)
   }
 }
@@ -81,7 +85,8 @@
   parsePsiType(modulePackage, type, defaultValue, context)
 
 fun getPsiTypeStr(modulePackage: String, typeStr: String?, defaultValue: String?): String {
-  // When specified as inputs to safe args, inner classes in XML should use the Java syntax (e.g. "Outer$Inner"), but IntelliJ resolves
+  // When specified as inputs to safe args, inner classes in XML should use the Java syntax (e.g.
+  // "Outer$Inner"), but IntelliJ resolves
   // the type using dot syntax ("Outer.Inner")
   var psiTypeStr = typeStr?.replace('$', '.')
 
@@ -144,8 +149,7 @@
   try {
     Integer.parseUnsignedInt(this.substring(2), 16)
     return PsiTypes.intType().name
-  }
-  catch (ignore: NumberFormatException) {
+  } catch (ignore: NumberFormatException) {
     return null
   }
 }
@@ -169,22 +173,30 @@
   val fallback = this.navigationElement
   return LightMethodBuilder(this, JavaLanguage.INSTANCE)
     .setConstructor(true)
-    .addModifiers(*modifiers).apply {
-      this.navigationElement = navigationElement ?: fallback
-    }
+    .addModifiers(*modifiers)
+    .apply { this.navigationElement = navigationElement ?: fallback }
 }
 
-internal fun PsiClass.createField(arg: NavArgumentData, modulePackage: String, xmlTag: XmlTag?): LightFieldBuilder {
+internal fun PsiClass.createField(
+  arg: NavArgumentData,
+  modulePackage: String,
+  xmlTag: XmlTag?
+): LightFieldBuilder {
   val psiType = arg.parsePsiType(modulePackage, this)
   val nonNull = psiType is PsiPrimitiveType || arg.isNonNull()
-  return NullabilityLightFieldBuilder(manager, arg.name, psiType, nonNull, PsiModifier.PUBLIC, PsiModifier.FINAL).apply {
-    this.navigationElement = xmlTag ?: this.navigationElement
-  }
+  return NullabilityLightFieldBuilder(
+      manager,
+      arg.name,
+      psiType,
+      nonNull,
+      PsiModifier.PUBLIC,
+      PsiModifier.FINAL
+    )
+    .apply { this.navigationElement = xmlTag ?: this.navigationElement }
 }
 
 /**
- * Annotate the target type with the proper nullability based on the <argument> nullable
- * attribute.
+ * Annotate the target type with the proper nullability based on the <argument> nullable attribute.
  */
 internal fun PsiClass.annotateNullability(psiType: PsiType, isNonNull: Boolean = true): PsiType {
   val nonNull = psiType is PsiPrimitiveType || isNonNull
@@ -201,10 +213,13 @@
   return LightMethodBuilder(manager, JavaLanguage.INSTANCE, name)
     .setContainingClass(this)
     .setModifiers(*modifiers)
-    .setMethodReturnType(returnType).apply {
-      this.navigationElement = navigationElement ?: this@createMethod.navigationElement
-    }
+    .setMethodReturnType(returnType)
+    .apply { this.navigationElement = navigationElement ?: this@createMethod.navigationElement }
 }
 
-fun String.toCamelCase() = this.split("_").mapIndexed { index, s -> if (index > 0) s.usLocaleCapitalize() else s }.joinToString("")
-fun String.toUpperCamelCase() = this.toCamelCase().usLocaleCapitalize()
\ No newline at end of file
+fun String.toCamelCase() =
+  this.split("_")
+    .mapIndexed { index, s -> if (index > 0) s.usLocaleCapitalize() else s }
+    .joinToString("")
+
+fun String.toUpperCamelCase() = this.toCamelCase().usLocaleCapitalize()
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/xml/SafeArgsXmlTag.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/xml/SafeArgsXmlTag.kt
index 3a3d544..45280e7 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/xml/SafeArgsXmlTag.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/xml/SafeArgsXmlTag.kt
@@ -51,8 +51,8 @@
 
   override fun isEquivalentTo(another: PsiElement?): Boolean {
     val anotherSafeArgsXmlTag = another as? SafeArgsXmlTag ?: return false
-    return xmlTag.isEquivalentTo(xmlTag)
-           && name == anotherSafeArgsXmlTag.name
-           && containerIdentifier == anotherSafeArgsXmlTag.containerIdentifier
+    return xmlTag.isEquivalentTo(xmlTag) &&
+      name == anotherSafeArgsXmlTag.name &&
+      containerIdentifier == anotherSafeArgsXmlTag.containerIdentifier
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/xml/XmlUtils.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/xml/XmlUtils.kt
index c172fc3..9c9c263 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/xml/XmlUtils.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/psi/xml/XmlUtils.kt
@@ -23,16 +23,17 @@
 
 fun XmlFile.findXmlTagById(attrId: String): XmlTag? {
   var resultTag: XmlTag? = null
-  val visitor = object : XmlRecursiveElementWalkingVisitor() {
-    override fun visitXmlTag(tag: XmlTag) {
-      super.visitXmlTag(tag)
-      // unique resource id in the same xml file
-      if (tag.isTagIdEqualTo(attrId)) {
-        resultTag = tag
-        stopWalking()
+  val visitor =
+    object : XmlRecursiveElementWalkingVisitor() {
+      override fun visitXmlTag(tag: XmlTag) {
+        super.visitXmlTag(tag)
+        // unique resource id in the same xml file
+        if (tag.isTagIdEqualTo(attrId)) {
+          resultTag = tag
+          stopWalking()
+        }
       }
     }
-  }
   this.accept(visitor)
   return resultTag
 }
diff --git a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/tracker/SafeArgsTracker.kt b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/tracker/SafeArgsTracker.kt
index b5341b8..1937903 100644
--- a/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/tracker/SafeArgsTracker.kt
+++ b/nav/safeargs/common/src/com/android/tools/idea/nav/safeargs/tracker/SafeArgsTracker.kt
@@ -16,18 +16,16 @@
 package com.android.tools.idea.nav.safeargs.tracker
 
 import com.android.tools.analytics.UsageTracker
+import com.android.tools.analytics.withProjectId
 import com.android.tools.idea.nav.safeargs.SafeArgsMode
 import com.android.tools.idea.nav.safeargs.safeArgsMode
 import com.android.tools.idea.projectsystem.getAndroidFacets
-import com.android.tools.analytics.withProjectId
 import com.google.wireless.android.sdk.stats.AndroidStudioEvent
 import com.google.wireless.android.sdk.stats.NavSafeArgsEvent
 import com.intellij.openapi.application.ApplicationManager
 import com.intellij.openapi.project.Project
 
-/**
- * A service which allows tracking safe args related metrics.
- */
+/** A service which allows tracking safe args related metrics. */
 abstract class SafeArgsTracker(private val project: Project) {
   companion object {
     @JvmStatic
@@ -43,22 +41,25 @@
       val kotlinPluginFacets = allFacets.count { it.safeArgsMode == SafeArgsMode.KOTLIN }
       if (javaPluginFacets + kotlinPluginFacets == 0) return@runSlowWork
 
-      val safeArgsEvent = NavSafeArgsEvent.newBuilder()
-        .setEventContext(context)
-        .setProjectMetadata(NavSafeArgsEvent.ProjectMetadata.newBuilder()
-                              .setModuleCount(allFacets.size)
-                              .setJavaPluginCount(javaPluginFacets)
-                              .setKotlinPluginCount(kotlinPluginFacets))
+      val safeArgsEvent =
+        NavSafeArgsEvent.newBuilder()
+          .setEventContext(context)
+          .setProjectMetadata(
+            NavSafeArgsEvent.ProjectMetadata.newBuilder()
+              .setModuleCount(allFacets.size)
+              .setJavaPluginCount(javaPluginFacets)
+              .setKotlinPluginCount(kotlinPluginFacets)
+          )
 
       track(safeArgsEvent)
     }
   }
 
   private fun track(safeArgsEvent: NavSafeArgsEvent.Builder) {
-    val studioEvent = AndroidStudioEvent
-      .newBuilder()
-      .setKind(AndroidStudioEvent.EventKind.NAV_SAFE_ARGS_EVENT)
-      .setNavSafeArgsEvent(safeArgsEvent)
+    val studioEvent =
+      AndroidStudioEvent.newBuilder()
+        .setKind(AndroidStudioEvent.EventKind.NAV_SAFE_ARGS_EVENT)
+        .setNavSafeArgsEvent(safeArgsEvent)
 
     UsageTracker.log(studioEvent.withProjectId(project))
   }
@@ -75,4 +76,4 @@
   override fun runSlowWork(block: () -> Unit) {
     ApplicationManager.getApplication().executeOnPooledThread { block() }
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KotlinTypeUtils.kt b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KotlinTypeUtils.kt
index 26b409b..a2e0c52 100644
--- a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KotlinTypeUtils.kt
+++ b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KotlinTypeUtils.kt
@@ -42,34 +42,28 @@
   moduleDescriptor: ModuleDescriptor,
   isNonNull: Boolean = true
 ): KotlinType {
-  val modulePackageName = moduleDescriptor.module.toModule()?.getModuleSystem()?.getPackageName() ?: ""
+  val modulePackageName =
+    moduleDescriptor.module.toModule()?.getModuleSystem()?.getPackageName() ?: ""
   val resolvedTypeStr = getPsiTypeStr(modulePackageName, typeStr, defaultValue)
 
   // array type
   if (resolvedTypeStr.endsWith("[]")) {
     val type = resolvedTypeStr.removeSuffix("[]")
-    val arrayType = try {
-      JvmPrimitiveType.get(type).primitiveType.let {
-        getPrimitiveArrayKotlinType(it)
+    val arrayType =
+      try {
+        JvmPrimitiveType.get(type).primitiveType.let { getPrimitiveArrayKotlinType(it) }
+      } catch (e: AssertionError) {
+        this.getArrayType(Variance.INVARIANT, getKotlinClassType(FqName(type), moduleDescriptor))
       }
-    }
-    catch (e: AssertionError) {
-      this.getArrayType(Variance.INVARIANT, getKotlinClassType(FqName(type), moduleDescriptor))
-    }
-    if (isNonNull) return arrayType
-    else return arrayType.makeNullable()
+    if (isNonNull) return arrayType else return arrayType.makeNullable()
   }
 
   return try {
-    JvmPrimitiveType.get(resolvedTypeStr).primitiveType.let {
-      getPrimitiveKotlinType(it)
-    }
-  }
-  catch (e: AssertionError) {
+    JvmPrimitiveType.get(resolvedTypeStr).primitiveType.let { getPrimitiveKotlinType(it) }
+  } catch (e: AssertionError) {
     val rawType = getKotlinClassType(FqName(resolvedTypeStr), moduleDescriptor)
 
-    if (isNonNull) return rawType
-    else return rawType.makeNullable()
+    if (isNonNull) return rawType else return rawType.makeNullable()
   }
 }
 
@@ -78,13 +72,16 @@
   moduleDescriptor: ModuleDescriptor
 ): KotlinType {
   val classId = JavaToKotlinClassMap.mapJavaToKotlin(fqName)
-  val classDescriptor = if (classId != null) getBuiltInClassByFqName(classId.asSingleFqName()) else null
+  val classDescriptor =
+    if (classId != null) getBuiltInClassByFqName(classId.asSingleFqName()) else null
   return classDescriptor?.defaultType
-         ?: ClassId.topLevel(fqName).let { moduleDescriptor.findClassAcrossModuleDependencies(it)?.defaultType }
-         ?: fqName.getUnresolvedType()
+    ?: ClassId.topLevel(fqName).let {
+      moduleDescriptor.findClassAcrossModuleDependencies(it)?.defaultType
+    }
+      ?: fqName.getUnresolvedType()
 }
 
 private fun FqName.getUnresolvedType(): KotlinType {
   val presentableName = this.toString()
   return ErrorUtils.createErrorType(ErrorTypeKind.UNRESOLVED_TYPE, presentableName)
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KtArgsPackageDescriptor.kt b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KtArgsPackageDescriptor.kt
index 59a29db..608999d 100644
--- a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KtArgsPackageDescriptor.kt
+++ b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KtArgsPackageDescriptor.kt
@@ -34,7 +34,8 @@
 import org.jetbrains.kotlin.utils.alwaysTrue
 
 /**
- * Args Kt package descriptor, which wraps and indirectly exposes a [LightArgsKtClass] class descriptor
+ * Args Kt package descriptor, which wraps and indirectly exposes a [LightArgsKtClass] class
+ * descriptor
  */
 class KtArgsPackageDescriptor(
   private val containingNavFileInfo: SafeArgsNavFileInfo,
@@ -56,24 +57,29 @@
   private val safeArgsPackageDescriptor = this@KtArgsPackageDescriptor
 
   private inner class SafeArgsModuleScope : MemberScopeImpl() {
-    private val classes = storageManager.createLazyValue {
-      val argsClass = LightArgsKtClass(
-        containingNavFileInfo.navInfo,
-        className,
-        destination,
-        superTypesProvider(safeArgsPackageDescriptor),
-        sourceElement,
-        safeArgsPackageDescriptor,
-        storageManager
-      )
-      listOfNotNull(argsClass)
-    }
+    private val classes =
+      storageManager.createLazyValue {
+        val argsClass =
+          LightArgsKtClass(
+            containingNavFileInfo.navInfo,
+            className,
+            destination,
+            superTypesProvider(safeArgsPackageDescriptor),
+            sourceElement,
+            safeArgsPackageDescriptor,
+            storageManager
+          )
+        listOfNotNull(argsClass)
+      }
 
     override fun getContributedDescriptors(
       kindFilter: DescriptorKindFilter,
       nameFilter: (Name) -> Boolean
     ): Collection<DeclarationDescriptor> {
-      return classes().filter { kindFilter.acceptsKinds(DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS_MASK) && nameFilter(it.name) }
+      return classes().filter {
+        kindFilter.acceptsKinds(DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS_MASK) &&
+          nameFilter(it.name)
+      }
     }
 
     override fun getClassifierNames(): Set<Name> {
@@ -82,7 +88,10 @@
         .mapTo(mutableSetOf()) { it.name }
     }
 
-    override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
+    override fun getContributedClassifier(
+      name: Name,
+      location: LookupLocation
+    ): ClassifierDescriptor? {
       return classes().firstOrNull { it.name == name }
     }
 
@@ -90,4 +99,4 @@
       p.println(this::class.java.simpleName)
     }
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KtDescriptorCacheModuleService.kt b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KtDescriptorCacheModuleService.kt
index 5330566..655be75 100644
--- a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KtDescriptorCacheModuleService.kt
+++ b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KtDescriptorCacheModuleService.kt
@@ -44,19 +44,24 @@
 /**
  * A module service which stores safe args kt package descriptors([KtArgsPackageDescriptor]s and
  * [KtDirectionsPackageDescriptor]s) by querying from [NavXmlIndex].
- *
  */
 class KtDescriptorCacheModuleService(private val module: Module) : Disposable.Default {
   private val fetcher = NavInfoFetcher(this, module, SafeArgsMode.KOTLIN)
 
-  private data class QualifiedDescriptor(val fqName: FqName, val descriptor: PackageFragmentDescriptor)
+  private data class QualifiedDescriptor(
+    val fqName: FqName,
+    val descriptor: PackageFragmentDescriptor
+  )
 
   companion object {
     @JvmStatic
-    fun getInstance(module: Module) = module.getService(KtDescriptorCacheModuleService::class.java)!!
+    fun getInstance(module: Module) =
+      module.getService(KtDescriptorCacheModuleService::class.java)!!
   }
 
-  fun getDescriptors(moduleDescriptor: ModuleDescriptor): Map<FqName, List<PackageFragmentDescriptor>> {
+  fun getDescriptors(
+    moduleDescriptor: ModuleDescriptor
+  ): Map<FqName, List<PackageFragmentDescriptor>> {
     ProgressManager.checkCanceled()
 
     val navInfo = fetcher.getCurrentNavInfo() ?: return emptyMap()
@@ -64,12 +69,13 @@
     return navInfo.entries
       .asSequence()
       .flatMap { navEntry ->
-        val sourceElement = navEntry.backingXmlFile?.let { XmlSourceElement(it) } ?: SourceElement.NO_SOURCE
+        val sourceElement =
+          navEntry.backingXmlFile?.let { XmlSourceElement(it) } ?: SourceElement.NO_SOURCE
         val navFileInfo = SafeArgsNavFileInfo(moduleDescriptor, module, navInfo, navEntry)
 
         val packages =
           createArgsPackages(navFileInfo, sourceElement) +
-          createDirectionsPackages(navFileInfo, sourceElement)
+            createDirectionsPackages(navFileInfo, sourceElement)
 
         packages.asSequence()
       }
@@ -85,36 +91,38 @@
       .asSequence()
       .filter { destination -> destination.actions.isNotEmpty() }
       .mapNotNull { destination ->
-        val fqName = destination.name.let { name ->
-          val resolvedName = if (!name.startsWith('.')) name else "${navFileInfo.navInfo.packageName}$name"
-          resolvedName + "Directions"
-        }
+        val fqName =
+          destination.name.let { name ->
+            val resolvedName =
+              if (!name.startsWith('.')) name else "${navFileInfo.navInfo.packageName}$name"
+            resolvedName + "Directions"
+          }
 
         val className = fqName.substringAfterLast('.').let { Name.identifier(it) }
         val packageName = FqName(fqName.substringBeforeLast('.'))
 
-        val resolvedSourceElement = (sourceElement.getPsi() as? XmlFile)
-                                      ?.findXmlTagById(destination.id)
-                                      ?.let {
-                                        XmlSourceElement(
-                                          SafeArgsXmlTag(
-                                            it as XmlTagImpl,
-                                            IconManager.getInstance().getPlatformIcon(PlatformIcons.Class),
-                                            className.asString(),
-                                            packageName.asString()
-                                          )
-                                        )
-                                      }
-                                    ?: sourceElement
+        val resolvedSourceElement =
+          (sourceElement.getPsi() as? XmlFile)?.findXmlTagById(destination.id)?.let {
+            XmlSourceElement(
+              SafeArgsXmlTag(
+                it as XmlTagImpl,
+                IconManager.getInstance().getPlatformIcon(PlatformIcons.Class),
+                className.asString(),
+                packageName.asString()
+              )
+            )
+          }
+            ?: sourceElement
 
-        val packageDescriptor = KtDirectionsPackageDescriptor(
-          navFileInfo,
-          packageName,
-          className,
-          destination,
-          resolvedSourceElement,
-          storageManager
-        )
+        val packageDescriptor =
+          KtDirectionsPackageDescriptor(
+            navFileInfo,
+            packageName,
+            className,
+            destination,
+            resolvedSourceElement,
+            storageManager
+          )
 
         QualifiedDescriptor(packageName, packageDescriptor)
       }
@@ -130,43 +138,49 @@
       .asSequence()
       .filter { destination -> destination.arguments.isNotEmpty() }
       .mapNotNull { destination ->
-
-        val fqName = destination.name.let { name ->
-          val resolvedName = if (!name.startsWith('.')) name else "${navFileInfo.navInfo.packageName}$name"
-          resolvedName + "Args"
-        }
+        val fqName =
+          destination.name.let { name ->
+            val resolvedName =
+              if (!name.startsWith('.')) name else "${navFileInfo.navInfo.packageName}$name"
+            resolvedName + "Args"
+          }
 
         val className = fqName.substringAfterLast('.').let { Name.identifier(it) }
         val packageName = FqName(fqName.substringBeforeLast('.'))
 
-        val resolvedSourceElement = (sourceElement.getPsi() as? XmlFile)
-                                      ?.findXmlTagById(destination.id)
-                                      ?.let {
-                                        XmlSourceElement(
-                                          SafeArgsXmlTag(
-                                            it as XmlTagImpl,
-                                            IconManager.getInstance().getPlatformIcon(PlatformIcons.Class),
-                                            className.asString(),
-                                            packageName.asString()
-                                          )
-                                        )
-                                      }
-                                    ?: sourceElement
+        val resolvedSourceElement =
+          (sourceElement.getPsi() as? XmlFile)?.findXmlTagById(destination.id)?.let {
+            XmlSourceElement(
+              SafeArgsXmlTag(
+                it as XmlTagImpl,
+                IconManager.getInstance().getPlatformIcon(PlatformIcons.Class),
+                className.asString(),
+                packageName.asString()
+              )
+            )
+          }
+            ?: sourceElement
 
         val superTypesProvider = { packageDescriptor: PackageFragmentDescriptorImpl ->
-          val ktType = packageDescriptor.builtIns.getKotlinType("androidx.navigation.NavArgs", null, packageDescriptor.module)
+          val ktType =
+            packageDescriptor.builtIns.getKotlinType(
+              "androidx.navigation.NavArgs",
+              null,
+              packageDescriptor.module
+            )
           listOf(ktType)
         }
 
-        val packageDescriptor = KtArgsPackageDescriptor(
-          navFileInfo,
-          packageName,
-          className,
-          destination,
-          superTypesProvider,
-          resolvedSourceElement,
-          storageManager
-        )
+        val packageDescriptor =
+          KtArgsPackageDescriptor(
+            navFileInfo,
+            packageName,
+            className,
+            destination,
+            superTypesProvider,
+            resolvedSourceElement,
+            storageManager
+          )
 
         QualifiedDescriptor(packageName, packageDescriptor)
       }
diff --git a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KtDirectionsPackageDescriptor.kt b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KtDirectionsPackageDescriptor.kt
index dc802d9..e6ead23 100644
--- a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KtDirectionsPackageDescriptor.kt
+++ b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KtDirectionsPackageDescriptor.kt
@@ -33,7 +33,8 @@
 import org.jetbrains.kotlin.utils.alwaysTrue
 
 /**
- * Directions Kt package descriptor, which wraps and indirectly exposes a [LightDirectionsKtClass] class descriptor
+ * Directions Kt package descriptor, which wraps and indirectly exposes a [LightDirectionsKtClass]
+ * class descriptor
  */
 class KtDirectionsPackageDescriptor(
   private val containingNavFileInfo: SafeArgsNavFileInfo,
@@ -54,24 +55,29 @@
   private val safeArgsPackageDescriptor = this@KtDirectionsPackageDescriptor
 
   private inner class SafeArgsModuleScope : MemberScopeImpl() {
-    private val classes = storageManager.createLazyValue {
-      val directionsClass = LightDirectionsKtClass(
-        containingNavFileInfo.navInfo,
-        containingNavFileInfo.navEntry,
-        className,
-        destination,
-        sourceElement,
-        safeArgsPackageDescriptor,
-        storageManager
-      )
-      listOfNotNull(directionsClass)
-    }
+    private val classes =
+      storageManager.createLazyValue {
+        val directionsClass =
+          LightDirectionsKtClass(
+            containingNavFileInfo.navInfo,
+            containingNavFileInfo.navEntry,
+            className,
+            destination,
+            sourceElement,
+            safeArgsPackageDescriptor,
+            storageManager
+          )
+        listOfNotNull(directionsClass)
+      }
 
     override fun getContributedDescriptors(
       kindFilter: DescriptorKindFilter,
       nameFilter: (Name) -> Boolean
     ): Collection<DeclarationDescriptor> {
-      return classes().filter { kindFilter.acceptsKinds(DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS_MASK) && nameFilter(it.name) }
+      return classes().filter {
+        kindFilter.acceptsKinds(DescriptorKindFilter.NON_SINGLETON_CLASSIFIERS_MASK) &&
+          nameFilter(it.name)
+      }
     }
 
     override fun getClassifierNames(): Set<Name> {
@@ -80,7 +86,10 @@
         .mapTo(mutableSetOf()) { it.name }
     }
 
-    override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
+    override fun getContributedClassifier(
+      name: Name,
+      location: LookupLocation
+    ): ClassifierDescriptor? {
       return classes().firstOrNull { it.name == name }
     }
 
@@ -88,4 +97,4 @@
       p.println(this::class.java.simpleName)
     }
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/LightArgsKtClass.kt b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/LightArgsKtClass.kt
index dd6eae5..9f91b4b 100644
--- a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/LightArgsKtClass.kt
+++ b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/LightArgsKtClass.kt
@@ -16,9 +16,7 @@
 package com.android.tools.idea.nav.safeargs.kotlin.k1
 
 import com.android.SdkConstants
-import com.android.ide.common.gradle.Version
 import com.android.tools.idea.nav.safeargs.index.NavDestinationData
-import com.android.tools.idea.nav.safeargs.module.NavEntry
 import com.android.tools.idea.nav.safeargs.module.NavInfo
 import com.android.tools.idea.nav.safeargs.psi.SafeArgsFeatureVersions
 import com.android.tools.idea.nav.safeargs.psi.java.toCamelCase
@@ -62,7 +60,6 @@
  * An "Arg" represents an argument which can get passed from one destination to another.
  *
  * For example, if you had the following "nav.xml":
- *
  * ```
  * <argument
  *    android:name="message"
@@ -70,7 +67,6 @@
  * ```
  *
  * This would generate a class like the following:
- *
  * ```
  *  data class FirstFragmentArgs( val message: String) : NavArgs {
  *       fun toBundle(): Bundle
@@ -91,14 +87,25 @@
   sourceElement: SourceElement,
   containingDescriptor: DeclarationDescriptor,
   private val storageManager: StorageManager
-) : ClassDescriptorImpl(containingDescriptor, name, Modality.FINAL, ClassKind.CLASS, superTypes, sourceElement, false, storageManager) {
+) :
+  ClassDescriptorImpl(
+    containingDescriptor,
+    name,
+    Modality.FINAL,
+    ClassKind.CLASS,
+    superTypes,
+    sourceElement,
+    false,
+    storageManager
+  ) {
 
   private val _primaryConstructor = storageManager.createLazyValue { computePrimaryConstructor() }
   private val _companionObject = storageManager.createLazyValue { computeCompanionObject() }
   private val scope = storageManager.createLazyValue { ArgsClassScope() }
 
   override fun getUnsubstitutedMemberScope(): MemberScope = scope()
-  override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): MemberScope = unsubstitutedMemberScope
+  override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): MemberScope =
+    unsubstitutedMemberScope
 
   override fun getConstructors() = listOf(_primaryConstructor())
   override fun getUnsubstitutedPrimaryConstructor() = _primaryConstructor()
@@ -106,20 +113,37 @@
 
   private fun computePrimaryConstructor(): ClassConstructorDescriptor {
     val valueParametersProvider = { constructor: ClassConstructorDescriptor ->
-      val resolvedArguments = if (navInfo.navVersion >= SafeArgsFeatureVersions.ADJUST_PARAMS_WITH_DEFAULTS)
-        destination.arguments.sortedBy { it.defaultValue != null }
-      else
-        destination.arguments
+      val resolvedArguments =
+        if (navInfo.navVersion >= SafeArgsFeatureVersions.ADJUST_PARAMS_WITH_DEFAULTS)
+          destination.arguments.sortedBy { it.defaultValue != null }
+        else destination.arguments
 
       var index = 0
       resolvedArguments
         .asSequence()
         .map { arg ->
           val pName = Name.identifier(arg.name.toCamelCase())
-          val pType = this.builtIns.getKotlinType(arg.type, arg.defaultValue, containingDeclaration.module, arg.isNonNull())
+          val pType =
+            this.builtIns.getKotlinType(
+              arg.type,
+              arg.defaultValue,
+              containingDeclaration.module,
+              arg.isNonNull()
+            )
           val hasDefaultValue = arg.defaultValue != null
-          ValueParameterDescriptorImpl(constructor, null, index++, Annotations.EMPTY, pName, pType, hasDefaultValue,
-                                       false, false, null, SourceElement.NO_SOURCE)
+          ValueParameterDescriptorImpl(
+            constructor,
+            null,
+            index++,
+            Annotations.EMPTY,
+            pName,
+            pType,
+            hasDefaultValue,
+            false,
+            false,
+            null,
+            SourceElement.NO_SOURCE
+          )
         }
         .toList()
     }
@@ -128,8 +152,17 @@
 
   private fun computeCompanionObject(): ClassDescriptor {
     val argsClassDescriptor = this@LightArgsKtClass
-    return object : ClassDescriptorImpl(argsClassDescriptor, Name.identifier("Companion"), Modality.FINAL,
-                                        ClassKind.OBJECT, emptyList(), argsClassDescriptor.source, false, storageManager) {
+    return object :
+      ClassDescriptorImpl(
+        argsClassDescriptor,
+        Name.identifier("Companion"),
+        Modality.FINAL,
+        ClassKind.OBJECT,
+        emptyList(),
+        argsClassDescriptor.source,
+        false,
+        storageManager
+      ) {
 
       private val companionObjectScope = storageManager.createLazyValue { CompanionScope() }
       private val companionObject = this
@@ -137,54 +170,96 @@
       override fun getUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor? = null
       override fun getConstructors(): Collection<ClassConstructorDescriptor> = emptyList()
       override fun getUnsubstitutedMemberScope() = companionObjectScope()
-      override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): MemberScope = unsubstitutedMemberScope
+      override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): MemberScope =
+        unsubstitutedMemberScope
 
       private inner class CompanionScope : MemberScopeImpl() {
-        private val companionMethods = storageManager.createLazyValue {
-          val methods = mutableListOf<SimpleFunctionDescriptor>()
+        private val companionMethods =
+          storageManager.createLazyValue {
+            val methods = mutableListOf<SimpleFunctionDescriptor>()
 
-          val fromBundleParametersProvider = { method: SimpleFunctionDescriptorImpl ->
-            val bundleType = argsClassDescriptor.builtIns.getKotlinType("android.os.Bundle", null, argsClassDescriptor.module)
-            val bundleParam = ValueParameterDescriptorImpl(
-              method, null, 0, Annotations.EMPTY, Name.identifier("bundle"), bundleType,
-              false, false, false, null, SourceElement.NO_SOURCE
-            )
-            listOf(bundleParam)
-          }
-
-          methods.add(companionObject.createMethod(
-            name = "fromBundle",
-            returnType = argsClassDescriptor.getDefaultType(),
-            valueParametersProvider = fromBundleParametersProvider
-          ))
-
-          if (navInfo.navVersion >= SafeArgsFeatureVersions.FROM_SAVED_STATE_HANDLE) {
-            val fromSavedStateHandleParametersProvider = { method: SimpleFunctionDescriptorImpl ->
-              val handleType =
-                argsClassDescriptor.builtIns.getKotlinType("androidx.lifecycle.SavedStateHandle", null, argsClassDescriptor.module)
-              val handleParam = ValueParameterDescriptorImpl(
-                method, null, 0, Annotations.EMPTY, Name.identifier("savedStateHandle"), handleType,
-                false, false, false, null, SourceElement.NO_SOURCE
-              )
-              listOf(handleParam)
+            val fromBundleParametersProvider = { method: SimpleFunctionDescriptorImpl ->
+              val bundleType =
+                argsClassDescriptor.builtIns.getKotlinType(
+                  "android.os.Bundle",
+                  null,
+                  argsClassDescriptor.module
+                )
+              val bundleParam =
+                ValueParameterDescriptorImpl(
+                  method,
+                  null,
+                  0,
+                  Annotations.EMPTY,
+                  Name.identifier("bundle"),
+                  bundleType,
+                  false,
+                  false,
+                  false,
+                  null,
+                  SourceElement.NO_SOURCE
+                )
+              listOf(bundleParam)
             }
 
-            methods.add(companionObject.createMethod(
-              name = "fromSavedStateHandle",
-              returnType = argsClassDescriptor.getDefaultType(),
-              valueParametersProvider = fromSavedStateHandleParametersProvider
-            ))
+            methods.add(
+              companionObject.createMethod(
+                name = "fromBundle",
+                returnType = argsClassDescriptor.getDefaultType(),
+                valueParametersProvider = fromBundleParametersProvider
+              )
+            )
+
+            if (navInfo.navVersion >= SafeArgsFeatureVersions.FROM_SAVED_STATE_HANDLE) {
+              val fromSavedStateHandleParametersProvider = { method: SimpleFunctionDescriptorImpl ->
+                val handleType =
+                  argsClassDescriptor.builtIns.getKotlinType(
+                    "androidx.lifecycle.SavedStateHandle",
+                    null,
+                    argsClassDescriptor.module
+                  )
+                val handleParam =
+                  ValueParameterDescriptorImpl(
+                    method,
+                    null,
+                    0,
+                    Annotations.EMPTY,
+                    Name.identifier("savedStateHandle"),
+                    handleType,
+                    false,
+                    false,
+                    false,
+                    null,
+                    SourceElement.NO_SOURCE
+                  )
+                listOf(handleParam)
+              }
+
+              methods.add(
+                companionObject.createMethod(
+                  name = "fromSavedStateHandle",
+                  returnType = argsClassDescriptor.getDefaultType(),
+                  valueParametersProvider = fromSavedStateHandleParametersProvider
+                )
+              )
+            }
+
+            methods
           }
 
-          methods
+        override fun getContributedDescriptors(
+          kindFilter: DescriptorKindFilter,
+          nameFilter: (Name) -> Boolean
+        ): Collection<DeclarationDescriptor> {
+          return companionMethods().filter {
+            kindFilter.acceptsKinds(DescriptorKindFilter.FUNCTIONS_MASK) && nameFilter(it.name)
+          }
         }
 
-        override fun getContributedDescriptors(kindFilter: DescriptorKindFilter,
-                                               nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> {
-          return companionMethods().filter { kindFilter.acceptsKinds(DescriptorKindFilter.FUNCTIONS_MASK) && nameFilter(it.name) }
-        }
-
-        override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> {
+        override fun getContributedFunctions(
+          name: Name,
+          location: LookupLocation
+        ): Collection<SimpleFunctionDescriptor> {
           return companionMethods().filter { it.name == name }
         }
 
@@ -197,98 +272,123 @@
 
   private inner class ArgsClassScope : MemberScopeImpl() {
     private val argsClassDescriptor = this@LightArgsKtClass
-    private val methods = storageManager.createLazyValue {
-      val methods = mutableListOf<SimpleFunctionDescriptor>()
+    private val methods =
+      storageManager.createLazyValue {
+        val methods = mutableListOf<SimpleFunctionDescriptor>()
 
-      val bundleType = argsClassDescriptor.builtIns.getKotlinType("android.os.Bundle", null, argsClassDescriptor.module)
-      val savedStateHandleType = argsClassDescriptor.builtIns.getKotlinType(
-        "androidx.lifecycle.SavedStateHandle",
-        null,
-        argsClassDescriptor.module
-      )
-
-      // Add toBundle method.
-      methods.add(
-        argsClassDescriptor.createMethod(
-          name = "toBundle",
-          returnType = bundleType,
-        )
-      )
-
-      // Add copy method.
-      methods.add(
-        argsClassDescriptor.createMethod(
-          name = "copy",
-          returnType = argsClassDescriptor.getDefaultType(),
-          valueParametersProvider = { argsClassDescriptor.unsubstitutedPrimaryConstructor.valueParameters }
-        )
-      )
-
-      // Add component functions.
-      var index = 1
-      destination.arguments
-        .asSequence()
-        .map { arg ->
-          val methodName = "component" + index++
-          val returnType = argsClassDescriptor.builtIns
-            .getKotlinType(arg.type, arg.defaultValue, argsClassDescriptor.module, arg.isNonNull())
-          val xmlTag = argsClassDescriptor.source.getPsi() as? XmlTag
-          val resolvedSourceElement = xmlTag?.findChildTagElementByNameAttr(SdkConstants.TAG_ARGUMENT, arg.name)?.let {
-            XmlSourceElement(
-              SafeArgsXmlTag(
-                it as XmlTagImpl,
-                IconManager.getInstance().getPlatformIcon(PlatformIcons.Function),
-                methodName,
-                argsClassDescriptor.fqNameSafe.asString()
-              )
-            )
-          } ?: argsClassDescriptor.source
-
-          argsClassDescriptor.createMethod(
-            name = methodName,
-            returnType = returnType,
-            isOperator = true,
-            sourceElement = resolvedSourceElement
+        val bundleType =
+          argsClassDescriptor.builtIns.getKotlinType(
+            "android.os.Bundle",
+            null,
+            argsClassDescriptor.module
           )
-        }
-        .map { methods.add(it) }
-        .toList()
+        val savedStateHandleType =
+          argsClassDescriptor.builtIns.getKotlinType(
+            "androidx.lifecycle.SavedStateHandle",
+            null,
+            argsClassDescriptor.module
+          )
 
-      // Add on version specific methods since the navigation library side is keeping introducing new methods.
-      if (navInfo.navVersion >= SafeArgsFeatureVersions.TO_SAVED_STATE_HANDLE) {
+        // Add toBundle method.
         methods.add(
           argsClassDescriptor.createMethod(
-            name = "toSavedStateHandle",
-            returnType = savedStateHandleType
+            name = "toBundle",
+            returnType = bundleType,
           )
         )
+
+        // Add copy method.
+        methods.add(
+          argsClassDescriptor.createMethod(
+            name = "copy",
+            returnType = argsClassDescriptor.getDefaultType(),
+            valueParametersProvider = {
+              argsClassDescriptor.unsubstitutedPrimaryConstructor.valueParameters
+            }
+          )
+        )
+
+        // Add component functions.
+        var index = 1
+        destination.arguments
+          .asSequence()
+          .map { arg ->
+            val methodName = "component" + index++
+            val returnType =
+              argsClassDescriptor.builtIns.getKotlinType(
+                arg.type,
+                arg.defaultValue,
+                argsClassDescriptor.module,
+                arg.isNonNull()
+              )
+            val xmlTag = argsClassDescriptor.source.getPsi() as? XmlTag
+            val resolvedSourceElement =
+              xmlTag?.findChildTagElementByNameAttr(SdkConstants.TAG_ARGUMENT, arg.name)?.let {
+                XmlSourceElement(
+                  SafeArgsXmlTag(
+                    it as XmlTagImpl,
+                    IconManager.getInstance().getPlatformIcon(PlatformIcons.Function),
+                    methodName,
+                    argsClassDescriptor.fqNameSafe.asString()
+                  )
+                )
+              }
+                ?: argsClassDescriptor.source
+
+            argsClassDescriptor.createMethod(
+              name = methodName,
+              returnType = returnType,
+              isOperator = true,
+              sourceElement = resolvedSourceElement
+            )
+          }
+          .map { methods.add(it) }
+          .toList()
+
+        // Add on version specific methods since the navigation library side is keeping introducing
+        // new methods.
+        if (navInfo.navVersion >= SafeArgsFeatureVersions.TO_SAVED_STATE_HANDLE) {
+          methods.add(
+            argsClassDescriptor.createMethod(
+              name = "toSavedStateHandle",
+              returnType = savedStateHandleType
+            )
+          )
+        }
+
+        methods
       }
 
-      methods
-    }
-
-    private val properties = storageManager.createLazyValue {
-      destination.arguments
-        .asSequence()
-        .map { arg ->
-          val pName = arg.name.toCamelCase()
-          val pType = argsClassDescriptor.builtIns
-            .getKotlinType(arg.type, arg.defaultValue, argsClassDescriptor.module, arg.isNonNull())
-          val xmlTag = argsClassDescriptor.source.getPsi() as? XmlTag
-          val resolvedSourceElement = xmlTag?.findChildTagElementByNameAttr(SdkConstants.TAG_ARGUMENT, arg.name)?.let {
-            XmlSourceElement(
-              SafeArgsXmlTag(
-                it as XmlTagImpl,
-                KotlinIcons.FIELD_VAL,
-                arg.name,
-                argsClassDescriptor.fqNameSafe.asString()
+    private val properties =
+      storageManager.createLazyValue {
+        destination.arguments
+          .asSequence()
+          .map { arg ->
+            val pName = arg.name.toCamelCase()
+            val pType =
+              argsClassDescriptor.builtIns.getKotlinType(
+                arg.type,
+                arg.defaultValue,
+                argsClassDescriptor.module,
+                arg.isNonNull()
               )
-            )
-          } ?: argsClassDescriptor.source
-          argsClassDescriptor.createProperty(pName, pType, resolvedSourceElement)
-        }
-        .toList()
-    }
+            val xmlTag = argsClassDescriptor.source.getPsi() as? XmlTag
+            val resolvedSourceElement =
+              xmlTag?.findChildTagElementByNameAttr(SdkConstants.TAG_ARGUMENT, arg.name)?.let {
+                XmlSourceElement(
+                  SafeArgsXmlTag(
+                    it as XmlTagImpl,
+                    KotlinIcons.FIELD_VAL,
+                    arg.name,
+                    argsClassDescriptor.fqNameSafe.asString()
+                  )
+                )
+              }
+                ?: argsClassDescriptor.source
+            argsClassDescriptor.createProperty(pName, pType, resolvedSourceElement)
+          }
+          .toList()
+      }
 
     private val classifiers = storageManager.createLazyValue { listOf(companionObjectDescriptor) }
 
@@ -296,20 +396,36 @@
       kindFilter: DescriptorKindFilter,
       nameFilter: (Name) -> Boolean
     ): Collection<DeclarationDescriptor> {
-      return methods().filter { kindFilter.acceptsKinds(DescriptorKindFilter.FUNCTIONS_MASK) && nameFilter(it.name) } +
-             properties().filter { kindFilter.acceptsKinds(DescriptorKindFilter.VARIABLES_MASK) && nameFilter(it.name) } +
-             classifiers().filter { kindFilter.acceptsKinds(DescriptorKindFilter.SINGLETON_CLASSIFIERS_MASK) && nameFilter(it.name) }
+      return methods().filter {
+        kindFilter.acceptsKinds(DescriptorKindFilter.FUNCTIONS_MASK) && nameFilter(it.name)
+      } +
+        properties().filter {
+          kindFilter.acceptsKinds(DescriptorKindFilter.VARIABLES_MASK) && nameFilter(it.name)
+        } +
+        classifiers().filter {
+          kindFilter.acceptsKinds(DescriptorKindFilter.SINGLETON_CLASSIFIERS_MASK) &&
+            nameFilter(it.name)
+        }
     }
 
-    override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
+    override fun getContributedClassifier(
+      name: Name,
+      location: LookupLocation
+    ): ClassifierDescriptor? {
       return classifiers().firstOrNull { it.name == name }
     }
 
-    override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> {
+    override fun getContributedFunctions(
+      name: Name,
+      location: LookupLocation
+    ): Collection<SimpleFunctionDescriptor> {
       return methods().filter { it.name == name }
     }
 
-    override fun getContributedVariables(name: Name, location: LookupLocation): List<PropertyDescriptor> {
+    override fun getContributedVariables(
+      name: Name,
+      location: LookupLocation
+    ): List<PropertyDescriptor> {
       return properties().filter { it.name == name }
     }
 
diff --git a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/LightDirectionsKtClass.kt b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/LightDirectionsKtClass.kt
index 6827ce6..05e2555 100644
--- a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/LightDirectionsKtClass.kt
+++ b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/LightDirectionsKtClass.kt
@@ -60,7 +60,6 @@
  * A "Direction" represents functionality that takes you away from one destination to another.
  *
  * For example, if you had the following "nav.xml":
- *
  * ```
  *  <navigation>
  *    <fragment id="@+id/mainMenu">
@@ -79,7 +78,6 @@
  * ```
  *
  * This would generate a class like the following:
- *
  * ```
  *  class MainMenuDirections {
  *    companion object {
@@ -103,14 +101,26 @@
   sourceElement: SourceElement,
   containingDescriptor: DeclarationDescriptor,
   private val storageManager: StorageManager
-) : ClassDescriptorImpl(containingDescriptor, name, Modality.FINAL, ClassKind.CLASS, emptyList(), sourceElement, false, storageManager) {
+) :
+  ClassDescriptorImpl(
+    containingDescriptor,
+    name,
+    Modality.FINAL,
+    ClassKind.CLASS,
+    emptyList(),
+    sourceElement,
+    false,
+    storageManager
+  ) {
 
-  private val LOG get() = Logger.getInstance(LightDirectionsKtClass::class.java)
+  private val LOG
+    get() = Logger.getInstance(LightDirectionsKtClass::class.java)
   private val _companionObject = storageManager.createLazyValue { computeCompanionObject() }
   private val scope = storageManager.createLazyValue { DirectionsClassScope() }
 
   override fun getUnsubstitutedMemberScope(): MemberScope = scope()
-  override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): MemberScope = unsubstitutedMemberScope
+  override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): MemberScope =
+    unsubstitutedMemberScope
 
   override fun getConstructors(): Collection<ClassConstructorDescriptor> = emptyList()
   override fun getUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor? = null
@@ -118,82 +128,115 @@
 
   private fun computeCompanionObject(): ClassDescriptor {
     val directionsClassDescriptor = this@LightDirectionsKtClass
-    return object : ClassDescriptorImpl(
-      directionsClassDescriptor,
-      Name.identifier("Companion"),
-      Modality.FINAL,
-      ClassKind.OBJECT,
-      emptyList(),
-      directionsClassDescriptor.source, false, storageManager
-    ) {
+    return object :
+      ClassDescriptorImpl(
+        directionsClassDescriptor,
+        Name.identifier("Companion"),
+        Modality.FINAL,
+        ClassKind.OBJECT,
+        emptyList(),
+        directionsClassDescriptor.source,
+        false,
+        storageManager
+      ) {
       private val companionScope = storageManager.createLazyValue { CompanionObjectScope() }
       private val companionObject = this
       override fun isCompanionObject() = true
       override fun getUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor? = null
       override fun getConstructors(): Collection<ClassConstructorDescriptor> = emptyList()
       override fun getUnsubstitutedMemberScope() = companionScope()
-      override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): MemberScope = unsubstitutedMemberScope
+      override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): MemberScope =
+        unsubstitutedMemberScope
 
       private inner class CompanionObjectScope : MemberScopeImpl() {
-        private val companionMethods = storageManager.createLazyValue {
-          // action methods
-          val navDirectionType = directionsClassDescriptor.builtIns.getKotlinType("androidx.navigation.NavDirections", null,
-                                                                                  directionsClassDescriptor.module)
-          destination.getActionsWithResolvedArguments(
-              navEntry.data,
-              navInfo.packageName,
-              adjustArgumentsWithDefaults = (navInfo.navVersion >= SafeArgsFeatureVersions.ADJUST_PARAMS_WITH_DEFAULTS))
-            .asSequence()
-            .mapNotNull { action ->
-              val valueParametersProvider = { method: SimpleFunctionDescriptorImpl ->
-                var index = 0
-                action.arguments
-                  .asSequence()
-                  .map { arg ->
-                    val pName = Name.identifier(arg.name.toCamelCase())
-                    val pType = directionsClassDescriptor.builtIns
-                      .getKotlinType(arg.type, arg.defaultValue, directionsClassDescriptor.module, arg.isNonNull())
-                    val hasDefaultValue = arg.defaultValue != null
-                    ValueParameterDescriptorImpl(method, null, index++, Annotations.EMPTY, pName, pType,
-                                                 hasDefaultValue, false, false, null,
-                                                 SourceElement.NO_SOURCE)
-                  }
-                  .toList()
-              }
-
-              val methodName = action.id.toCamelCase()
-              val resolvedSourceElement = (directionsClassDescriptor.source.getPsi() as? XmlTag)
-                                            ?.findFirstMatchingElementByTraversingUp(SdkConstants.TAG_ACTION, action.id)
-                                            ?.let {
-                                              XmlSourceElement(
-                                                SafeArgsXmlTag(
-                                                  it as XmlTagImpl,
-                                                  IconManager.getInstance().getPlatformIcon(PlatformIcons.Function),
-                                                  methodName,
-                                                  companionObject.fqNameSafe.asString()
-                                                )
-                                              )
-                                            }
-                                          ?: directionsClassDescriptor.source
-
-              companionObject.createMethod(
-                name = methodName,
-                returnType = navDirectionType,
-                valueParametersProvider = valueParametersProvider,
-                sourceElement = resolvedSourceElement
+        private val companionMethods =
+          storageManager.createLazyValue {
+            // action methods
+            val navDirectionType =
+              directionsClassDescriptor.builtIns.getKotlinType(
+                "androidx.navigation.NavDirections",
+                null,
+                directionsClassDescriptor.module
               )
-            }
-            .toList()
-        }
+            destination
+              .getActionsWithResolvedArguments(
+                navEntry.data,
+                navInfo.packageName,
+                adjustArgumentsWithDefaults =
+                  (navInfo.navVersion >= SafeArgsFeatureVersions.ADJUST_PARAMS_WITH_DEFAULTS)
+              )
+              .asSequence()
+              .mapNotNull { action ->
+                val valueParametersProvider = { method: SimpleFunctionDescriptorImpl ->
+                  var index = 0
+                  action.arguments
+                    .asSequence()
+                    .map { arg ->
+                      val pName = Name.identifier(arg.name.toCamelCase())
+                      val pType =
+                        directionsClassDescriptor.builtIns.getKotlinType(
+                          arg.type,
+                          arg.defaultValue,
+                          directionsClassDescriptor.module,
+                          arg.isNonNull()
+                        )
+                      val hasDefaultValue = arg.defaultValue != null
+                      ValueParameterDescriptorImpl(
+                        method,
+                        null,
+                        index++,
+                        Annotations.EMPTY,
+                        pName,
+                        pType,
+                        hasDefaultValue,
+                        false,
+                        false,
+                        null,
+                        SourceElement.NO_SOURCE
+                      )
+                    }
+                    .toList()
+                }
+
+                val methodName = action.id.toCamelCase()
+                val resolvedSourceElement =
+                  (directionsClassDescriptor.source.getPsi() as? XmlTag)
+                    ?.findFirstMatchingElementByTraversingUp(SdkConstants.TAG_ACTION, action.id)
+                    ?.let {
+                      XmlSourceElement(
+                        SafeArgsXmlTag(
+                          it as XmlTagImpl,
+                          IconManager.getInstance().getPlatformIcon(PlatformIcons.Function),
+                          methodName,
+                          companionObject.fqNameSafe.asString()
+                        )
+                      )
+                    }
+                    ?: directionsClassDescriptor.source
+
+                companionObject.createMethod(
+                  name = methodName,
+                  returnType = navDirectionType,
+                  valueParametersProvider = valueParametersProvider,
+                  sourceElement = resolvedSourceElement
+                )
+              }
+              .toList()
+          }
 
         override fun getContributedDescriptors(
           kindFilter: DescriptorKindFilter,
           nameFilter: (Name) -> Boolean
         ): Collection<DeclarationDescriptor> {
-          return companionMethods().filter { kindFilter.acceptsKinds(DescriptorKindFilter.FUNCTIONS_MASK) && nameFilter(it.name) }
+          return companionMethods().filter {
+            kindFilter.acceptsKinds(DescriptorKindFilter.FUNCTIONS_MASK) && nameFilter(it.name)
+          }
         }
 
-        override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> {
+        override fun getContributedFunctions(
+          name: Name,
+          location: LookupLocation
+        ): Collection<SimpleFunctionDescriptor> {
           return companionMethods().filter { it.name == name }
         }
 
@@ -211,10 +254,16 @@
       kindFilter: DescriptorKindFilter,
       nameFilter: (Name) -> Boolean
     ): Collection<DeclarationDescriptor> {
-      return classifiers().filter { kindFilter.acceptsKinds(DescriptorKindFilter.SINGLETON_CLASSIFIERS_MASK) && nameFilter(it.name) }
+      return classifiers().filter {
+        kindFilter.acceptsKinds(DescriptorKindFilter.SINGLETON_CLASSIFIERS_MASK) &&
+          nameFilter(it.name)
+      }
     }
 
-    override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
+    override fun getContributedClassifier(
+      name: Name,
+      location: LookupLocation
+    ): ClassifierDescriptor? {
       return classifiers().firstOrNull { it.name == name }
     }
 
@@ -222,4 +271,4 @@
       p.println(this::class.java.simpleName)
     }
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgSyntheticDescriptorGenerator.kt b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgSyntheticDescriptorGenerator.kt
index 339b105..33ee58c 100644
--- a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgSyntheticDescriptorGenerator.kt
+++ b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgSyntheticDescriptorGenerator.kt
@@ -33,41 +33,58 @@
 import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
 import org.jetbrains.kotlin.types.KotlinType
 
-/**
- *  Class, method and property descriptors generator
- */
+/** Class, method and property descriptors generator */
 internal fun ClassDescriptorImpl.createMethod(
   name: String,
   returnType: KotlinType,
   isOperator: Boolean = false,
-  valueParametersProvider: (SimpleFunctionDescriptorImpl) -> List<ValueParameterDescriptor> = { emptyList() },
+  valueParametersProvider: (SimpleFunctionDescriptorImpl) -> List<ValueParameterDescriptor> = {
+    emptyList()
+  },
   sourceElement: SourceElement = this.source.withFunctionIcon(name, this.fqNameSafe.asString())
 ): SimpleFunctionDescriptorImpl {
 
-  val method = object : SimpleFunctionDescriptorImpl(
-    this,
-    null,
-    Annotations.EMPTY,
-    Name.identifier(name),
-    CallableMemberDescriptor.Kind.SYNTHESIZED,
-    sourceElement
-  ) {
-    override fun isOperator(): Boolean {
-      return isOperator
+  val method =
+    object :
+      SimpleFunctionDescriptorImpl(
+        this,
+        null,
+        Annotations.EMPTY,
+        Name.identifier(name),
+        CallableMemberDescriptor.Kind.SYNTHESIZED,
+        sourceElement
+      ) {
+      override fun isOperator(): Boolean {
+        return isOperator
+      }
     }
-  }
 
-  return method.initialize(null, this.thisAsReceiverParameter, emptyList(),
-                           valueParametersProvider(method), returnType, Modality.FINAL, DescriptorVisibilities.PUBLIC)
+  return method.initialize(
+    null,
+    this.thisAsReceiverParameter,
+    emptyList(),
+    valueParametersProvider(method),
+    returnType,
+    Modality.FINAL,
+    DescriptorVisibilities.PUBLIC
+  )
 }
 
 internal fun ClassDescriptorImpl.createConstructor(
-  valueParameterProvider: (ClassConstructorDescriptor) -> List<ValueParameterDescriptor> = { emptyList() }
-): ClassConstructorDescriptor {
-  return ClassConstructorDescriptorImpl.createSynthesized(this, Annotations.EMPTY, true, this.source).apply {
-    this.initialize(valueParameterProvider(this), DescriptorVisibilities.PUBLIC)
-    this.returnType = this@createConstructor.defaultType
+  valueParameterProvider: (ClassConstructorDescriptor) -> List<ValueParameterDescriptor> = {
+    emptyList()
   }
+): ClassConstructorDescriptor {
+  return ClassConstructorDescriptorImpl.createSynthesized(
+      this,
+      Annotations.EMPTY,
+      true,
+      this.source
+    )
+    .apply {
+      this.initialize(valueParameterProvider(this), DescriptorVisibilities.PUBLIC)
+      this.returnType = this@createConstructor.defaultType
+    }
 }
 
 internal fun ClassDescriptorImpl.createProperty(
@@ -75,39 +92,43 @@
   type: KotlinType,
   sourceElement: SourceElement = SourceElement.NO_SOURCE
 ): PropertyDescriptor {
-  val property = object : PropertyDescriptorImpl(
-    this,
-    null,
-    Annotations.EMPTY,
-    Modality.FINAL,
-    DescriptorVisibilities.PUBLIC,
-    false,
-    Name.identifier(name),
-    CallableMemberDescriptor.Kind.SYNTHESIZED,
-    sourceElement, // todo: refined navigation element
-    false,
-    false,
-    false,
-    false,
-    false,
-    false) {}
+  val property =
+    object :
+      PropertyDescriptorImpl(
+        this,
+        null,
+        Annotations.EMPTY,
+        Modality.FINAL,
+        DescriptorVisibilities.PUBLIC,
+        false,
+        Name.identifier(name),
+        CallableMemberDescriptor.Kind.SYNTHESIZED,
+        sourceElement, // todo: refined navigation element
+        false,
+        false,
+        false,
+        false,
+        false,
+        false
+      ) {}
 
   property.setType(type, emptyList<TypeParameterDescriptor>(), this.thisAsReceiverParameter, null)
 
-  val getter = PropertyGetterDescriptorImpl(
-    property,
-    Annotations.EMPTY,
-    Modality.FINAL,
-    DescriptorVisibilities.PUBLIC,
-    false,
-    false,
-    false,
-    CallableMemberDescriptor.Kind.SYNTHESIZED,
-    null,
-    sourceElement
-  )
+  val getter =
+    PropertyGetterDescriptorImpl(
+      property,
+      Annotations.EMPTY,
+      Modality.FINAL,
+      DescriptorVisibilities.PUBLIC,
+      false,
+      false,
+      false,
+      CallableMemberDescriptor.Kind.SYNTHESIZED,
+      null,
+      sourceElement
+    )
   getter.initialize(type)
 
   property.initialize(getter, null)
   return property
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsImportKtResolver.kt b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsImportKtResolver.kt
index 24a9319..3b57d70 100644
--- a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsImportKtResolver.kt
+++ b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsImportKtResolver.kt
@@ -31,6 +31,9 @@
 import com.intellij.psi.PsiFile
 import com.intellij.ui.popup.list.ListPopupImpl
 import com.intellij.ui.popup.list.PopupListElementRenderer
+import java.awt.BorderLayout
+import javax.swing.JPanel
+import javax.swing.ListCellRenderer
 import org.jetbrains.android.util.AndroidBundle
 import org.jetbrains.kotlin.descriptors.ClassDescriptor
 import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
@@ -54,12 +57,10 @@
 import org.jetbrains.kotlin.resolve.asImportedFromObject
 import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
 import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
-import java.awt.BorderLayout
-import javax.swing.JPanel
-import javax.swing.ListCellRenderer
 
 /**
- * Registers an unresolved reference resolver in Kotlin files which recognizes classes from Safe Args kotlin classes
+ * Registers an unresolved reference resolver in Kotlin files which recognizes classes from Safe
+ * Args kotlin classes
  */
 class SafeArgsImportKtResolver : QuickFixContributor {
   override fun registerQuickFixes(quickFixes: QuickFixes) {
@@ -112,38 +113,47 @@
 
     // Copied from KotlinAddImportAction
     object : ListPopupImpl(project, getVariantSelectionPopup(project, file, suggestions)) {
-      override fun getListElementRenderer(): ListCellRenderer<AutoImportVariant> {
-        val baseRenderer = super.getListElementRenderer() as PopupListElementRenderer<AutoImportVariant>
-        val psiRenderer = SafeArgsPsiElementCellRenderer()
-        return ListCellRenderer { list, value, index, isSelected, cellHasFocus ->
-          JPanel(BorderLayout()).apply {
-            baseRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus)
-            add(baseRenderer.nextStepLabel, BorderLayout.EAST)
-            add(
-              psiRenderer.getListCellRendererComponent(
+        override fun getListElementRenderer(): ListCellRenderer<AutoImportVariant> {
+          val baseRenderer =
+            super.getListElementRenderer() as PopupListElementRenderer<AutoImportVariant>
+          val psiRenderer = SafeArgsPsiElementCellRenderer()
+          return ListCellRenderer { list, value, index, isSelected, cellHasFocus ->
+            JPanel(BorderLayout()).apply {
+              baseRenderer.getListCellRendererComponent(
                 list,
-                value.declarationToImport(project),
+                value,
                 index,
                 isSelected,
                 cellHasFocus
               )
-            )
+              add(baseRenderer.nextStepLabel, BorderLayout.EAST)
+              add(
+                psiRenderer.getListCellRendererComponent(
+                  list,
+                  value.declarationToImport(project),
+                  index,
+                  isSelected,
+                  cellHasFocus
+                )
+              )
+            }
           }
         }
       }
-    }.showInBestPositionFor(editor)
+      .showInBestPositionFor(editor)
   }
 
   private fun collectSuggestions(file: PsiFile): List<AutoImportVariant> {
     val module = ModuleUtil.findModuleForFile(file) ?: return emptyList()
     val nameIdentifier = Name.identifier(referenceName)
-    return module.getDescriptorsByModulesWithDependencies()
+    return module
+      .getDescriptorsByModulesWithDependencies()
       .values
       .flatten()
       .asSequence()
       .flatMap { descriptor ->
         descriptor.findVisibleClassesBySimpleName(nameIdentifier) +
-        descriptor.findVisibleFunctionsBySimpleName(nameIdentifier)
+          descriptor.findVisibleFunctionsBySimpleName(nameIdentifier)
       }
       .map { AutoImportVariant(it) }
       .filter { it.importFqName != null }
@@ -151,21 +161,33 @@
       .toList()
   }
 
-  private fun PackageFragmentDescriptor.findVisibleClassesBySimpleName(name: Name): Sequence<DeclarationDescriptor> {
-    return getMemberScope().getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS) { it == name }.asSequence() +
-           getMemberScope().getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS).asSequence()
-             .filterIsInstance<ClassDescriptor>()
-             .mapNotNull { it.companionObjectDescriptor }
-             .filter { it.name == name }
+  private fun PackageFragmentDescriptor.findVisibleClassesBySimpleName(
+    name: Name
+  ): Sequence<DeclarationDescriptor> {
+    return getMemberScope()
+      .getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS) { it == name }
+      .asSequence() +
+      getMemberScope()
+        .getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS)
+        .asSequence()
+        .filterIsInstance<ClassDescriptor>()
+        .mapNotNull { it.companionObjectDescriptor }
+        .filter { it.name == name }
   }
 
-  private fun PackageFragmentDescriptor.findVisibleFunctionsBySimpleName(name: Name): Sequence<DeclarationDescriptor> {
-    return getMemberScope().getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS).asSequence()
+  private fun PackageFragmentDescriptor.findVisibleFunctionsBySimpleName(
+    name: Name
+  ): Sequence<DeclarationDescriptor> {
+    return getMemberScope()
+      .getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS)
+      .asSequence()
       .filterIsInstance<ClassDescriptor>()
       .mapNotNull { it.companionObjectDescriptor }
       .flatMap {
-        ProgressManager.checkCanceled();
-        it.unsubstitutedMemberScope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS).asSequence()
+        ProgressManager.checkCanceled()
+        it.unsubstitutedMemberScope
+          .getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)
+          .asSequence()
       }
       .filterIsInstance<FunctionDescriptor>()
       .map { it.asImportedFromObject() }
@@ -174,7 +196,8 @@
 
   private fun addImport(project: Project, file: KtFile, import: FqName) {
     project.executeWriteCommand(QuickFixBundle.message("add.import")) {
-      val descriptor = file.resolveImportReference(import).firstOrNull() ?: return@executeWriteCommand
+      val descriptor =
+        file.resolveImportReference(import).firstOrNull() ?: return@executeWriteCommand
       ImportInsertHelper.getInstance(project).importDescriptor(file, descriptor)
     }
   }
@@ -184,12 +207,20 @@
     file: KtFile,
     suggestions: List<AutoImportVariant>
   ): BaseListPopupStep<AutoImportVariant> {
-    return object : BaseListPopupStep<AutoImportVariant>(KotlinBundle.message("action.add.import.chooser.title"), suggestions) {
+    return object :
+      BaseListPopupStep<AutoImportVariant>(
+        KotlinBundle.message("action.add.import.chooser.title"),
+        suggestions
+      ) {
       override fun isAutoSelectionEnabled() = false
 
       override fun isSpeedSearchEnabled() = true
-      override fun onChosen(selectedValue: AutoImportVariant?, finalChoice: Boolean): PopupStep<String>? {
-        if (selectedValue == null || project.isDisposed || selectedValue.importFqName == null) return null
+      override fun onChosen(
+        selectedValue: AutoImportVariant?,
+        finalChoice: Boolean
+      ): PopupStep<String>? {
+        if (selectedValue == null || project.isDisposed || selectedValue.importFqName == null)
+          return null
 
         if (finalChoice) {
           addImport(project, file, selectedValue.importFqName)
@@ -210,4 +241,4 @@
 
     return if (addOnText.isEmpty()) baseText else "(in $addOnText) $baseText"
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsKtCompletionContributor.kt b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsKtCompletionContributor.kt
index db11d4b..70c5ea9 100644
--- a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsKtCompletionContributor.kt
+++ b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsKtCompletionContributor.kt
@@ -44,70 +44,96 @@
 import org.jetbrains.kotlin.resolve.source.getPsi
 
 /**
- * This provides completions for generated [LightArgsKtClass] and [LightDirectionsKtClass] from modules with dependencies.
+ * This provides completions for generated [LightArgsKtClass] and [LightDirectionsKtClass] from
+ * modules with dependencies.
  *
  * This comes after [KotlinCompletionContributor]
  */
 class SafeArgsKtCompletionContributor : CompletionContributor() {
   init {
-    extend(CompletionType.BASIC, PlatformPatterns.psiElement(), object : CompletionProvider<CompletionParameters>() {
-      override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, result: CompletionResultSet) {
+    extend(
+      CompletionType.BASIC,
+      PlatformPatterns.psiElement(),
+      object : CompletionProvider<CompletionParameters>() {
+        override fun addCompletions(
+          parameters: CompletionParameters,
+          context: ProcessingContext,
+          result: CompletionResultSet
+        ) {
 
-        val position = parameters.position
-        val facet = position.androidFacet ?: return
+          val position = parameters.position
+          val facet = position.androidFacet ?: return
 
-        val element = position.parent as? KtSimpleNameExpression ?: return
-        if (element.isImportDirectiveExpression()) return
-        if (element.getReceiverExpression() != null) return
+          val element = position.parent as? KtSimpleNameExpression ?: return
+          if (element.isImportDirectiveExpression()) return
+          if (element.getReceiverExpression() != null) return
 
-        val importedDirectives = getImportedDirectives(element)
+          val importedDirectives = getImportedDirectives(element)
 
-        val lookupElements = facet.module.getDescriptorsByModulesWithDependencies().values.asSequence()
-          .flatten()
-          .map { ProgressManager.checkCanceled(); it }
-          .filter { element.containingKtFile.packageFqName != it.fqName }
-          .mapNotNull { it.getMemberScope().getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS) { true }.firstOrNull() }
-          .filterIsInstance<ClassDescriptor>()
-          .filter { it.importableFqName != null }
-          .filter { descriptor ->
-            // Classes in imported packages are already autocompleted, and we don't want to add duplicate results.
-            importedDirectives.none { importPath -> descriptor.importableFqName!!.isImported(importPath) }
-          }
-          .mapNotNull { createLookUpElement(it) }
-          .toList()
+          val lookupElements =
+            facet.module
+              .getDescriptorsByModulesWithDependencies()
+              .values
+              .asSequence()
+              .flatten()
+              .map {
+                ProgressManager.checkCanceled()
+                it
+              }
+              .filter { element.containingKtFile.packageFqName != it.fqName }
+              .mapNotNull {
+                it
+                  .getMemberScope()
+                  .getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS) { true }
+                  .firstOrNull()
+              }
+              .filterIsInstance<ClassDescriptor>()
+              .filter { it.importableFqName != null }
+              .filter { descriptor ->
+                // Classes in imported packages are already autocompleted, and we don't want to add
+                // duplicate results.
+                importedDirectives.none { importPath ->
+                  descriptor.importableFqName!!.isImported(importPath)
+                }
+              }
+              .mapNotNull { createLookUpElement(it) }
+              .toList()
 
-        result.addAllElements(lookupElements)
-      }
-
-      private fun createLookUpElement(classDescriptor: ClassDescriptor): LookupElement? {
-        val lookupObject = object : DeclarationLookupObjectImpl(classDescriptor) {
-          override val psiElement = classDescriptor.source.getPsi()
-          override fun getIcon(flags: Int) = KotlinDescriptorIconProvider.getIcon(classDescriptor, psiElement, flags)
+          result.addAllElements(lookupElements)
         }
 
-        var element = LookupElementBuilder.create(lookupObject, classDescriptor.name.asString())
-          .withInsertHandler(KotlinClassifierInsertHandler)
+        private fun createLookUpElement(classDescriptor: ClassDescriptor): LookupElement? {
+          val lookupObject =
+            object : DeclarationLookupObjectImpl(classDescriptor) {
+              override val psiElement = classDescriptor.source.getPsi()
+              override fun getIcon(flags: Int) =
+                KotlinDescriptorIconProvider.getIcon(classDescriptor, psiElement, flags)
+            }
 
-        val classFqName = classDescriptor.fqNameSafe.takeUnless { it.isRoot } ?: return null
+          var element =
+            LookupElementBuilder.create(lookupObject, classDescriptor.name.asString())
+              .withInsertHandler(KotlinClassifierInsertHandler)
 
-        val containerName = classFqName.parent()
-        element = element.appendTailText(" ($containerName)", true)
-        return element.withIconFromLookupObject()
+          val classFqName = classDescriptor.fqNameSafe.takeUnless { it.isRoot } ?: return null
+
+          val containerName = classFqName.parent()
+          element = element.appendTailText(" ($containerName)", true)
+          return element.withIconFromLookupObject()
+        }
+
+        private fun getImportedDirectives(element: KtSimpleNameExpression): Set<ImportPath> {
+          return element.containingKtFile.importDirectives.mapNotNull { it.importPath }.toSet()
+        }
       }
-
-      private fun getImportedDirectives(element: KtSimpleNameExpression): Set<ImportPath> {
-        return element.containingKtFile.importDirectives
-          .mapNotNull { it.importPath }
-          .toSet()
-      }
-    })
+    )
   }
 }
 
 // Copy from BasicLookupElementFactory
-private fun LookupElement.withIconFromLookupObject(): LookupElement = object : LookupElementDecorator<LookupElement>(this) {
-  override fun renderElement(presentation: LookupElementPresentation) {
-    super.renderElement(presentation)
-    presentation.icon = DefaultLookupItemRenderer.getRawIcon(this@withIconFromLookupObject)
+private fun LookupElement.withIconFromLookupObject(): LookupElement =
+  object : LookupElementDecorator<LookupElement>(this) {
+    override fun renderElement(presentation: LookupElementPresentation) {
+      super.renderElement(presentation)
+      presentation.icon = DefaultLookupItemRenderer.getRawIcon(this@withIconFromLookupObject)
+    }
   }
-}
\ No newline at end of file
diff --git a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsKtDescriptorUtils.kt b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsKtDescriptorUtils.kt
index 1d30ec5..f1c69b5 100644
--- a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsKtDescriptorUtils.kt
+++ b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsKtDescriptorUtils.kt
@@ -33,18 +33,25 @@
 import org.jetbrains.kotlin.resolve.source.PsiSourceElement
 import org.jetbrains.kotlin.resolve.source.getPsi
 
-internal fun Module.getDescriptorsByModulesWithDependencies(): Map<FqName, List<PackageFragmentDescriptor>> {
+internal fun Module.getDescriptorsByModulesWithDependencies():
+  Map<FqName, List<PackageFragmentDescriptor>> {
   val moduleDescriptor = this.toDescriptor() ?: return emptyMap()
-  val descriptorsFromThisModule = KtDescriptorCacheModuleService.getInstance(this).getDescriptors(moduleDescriptor).toMutableMap()
-  return ModuleRootManager.getInstance(this).getDependencies(false)
+  val descriptorsFromThisModule =
+    KtDescriptorCacheModuleService.getInstance(this).getDescriptors(moduleDescriptor).toMutableMap()
+  return ModuleRootManager.getInstance(this)
+    .getDependencies(false)
     .asSequence()
-    .map { ProgressManager.checkCanceled(); it }
+    .map {
+      ProgressManager.checkCanceled()
+      it
+    }
     .mapNotNull {
       val descriptor = it?.toDescriptor() ?: return@mapNotNull null
       KtDescriptorCacheModuleService.getInstance(it).getDescriptors(descriptor)
     }
     .fold(descriptorsFromThisModule) { acc, curr ->
-      // TODO(b/159954452): duplications(e.g Same fragment class declared across multiple nav resource files) need to be
+      // TODO(b/159954452): duplications(e.g Same fragment class declared across multiple nav
+      // resource files) need to be
       //  resolved.
       curr.entries.forEach { entry -> acc.merge(entry.key, entry.value) { old, new -> old + new } }
       acc
@@ -61,8 +68,19 @@
 
 class XmlSourceElement(override val psi: PsiElement) : PsiSourceElement
 
-internal fun SourceElement.withFunctionIcon(name: String, containingClassName: String): SourceElement {
+internal fun SourceElement.withFunctionIcon(
+  name: String,
+  containingClassName: String
+): SourceElement {
   return (this.getPsi() as? SafeArgsXmlTag)?.let {
-    XmlSourceElement(SafeArgsXmlTag(it.getOriginal(), IconManager.getInstance().getPlatformIcon(com.intellij.ui.PlatformIcons.Function), name, containingClassName))
-  } ?: this
+    XmlSourceElement(
+      SafeArgsXmlTag(
+        it.getOriginal(),
+        IconManager.getInstance().getPlatformIcon(com.intellij.ui.PlatformIcons.Function),
+        name,
+        containingClassName
+      )
+    )
+  }
+    ?: this
 }
diff --git a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsKtPackageProviderExtension.kt b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsKtPackageProviderExtension.kt
index 337d337..bbf8c99a 100644
--- a/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsKtPackageProviderExtension.kt
+++ b/nav/safeargs/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsKtPackageProviderExtension.kt
@@ -31,21 +31,24 @@
 import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension
 import org.jetbrains.kotlin.storage.StorageManager
 
-/**
- * Safe Args Kotlin Synthetic module package provider
- */
+/** Safe Args Kotlin Synthetic module package provider */
 class SafeArgsKtPackageProviderExtension(val project: Project) : PackageFragmentProviderExtension {
-  override fun getPackageFragmentProvider(project: Project,
-                                          module: ModuleDescriptor,
-                                          storageManager: StorageManager,
-                                          trace: BindingTrace,
-                                          moduleInfo: ModuleInfo?,
-                                          lookupTracker: LookupTracker): PackageFragmentProvider? {
+  override fun getPackageFragmentProvider(
+    project: Project,
+    module: ModuleDescriptor,
+    storageManager: StorageManager,
+    trace: BindingTrace,
+    moduleInfo: ModuleInfo?,
+    lookupTracker: LookupTracker
+  ): PackageFragmentProvider? {
     val facet = moduleInfo?.toModule()?.let { AndroidFacet.getInstance(it) } ?: return null
     if (facet.safeArgsMode != SafeArgsMode.KOTLIN) return null
 
-    val packageDescriptors = KtDescriptorCacheModuleService.getInstance(facet.module).getDescriptors(module).takeIf { it.isNotEmpty() }
-                             ?: return null
+    val packageDescriptors =
+      KtDescriptorCacheModuleService.getInstance(facet.module).getDescriptors(module).takeIf {
+        it.isNotEmpty()
+      }
+        ?: return null
     return SafeArgsSyntheticPackageProvider(packageDescriptors)
   }
 }
@@ -53,7 +56,10 @@
 class SafeArgsSyntheticPackageProvider(
   private val packageDescriptorProvider: Map<FqName, List<PackageFragmentDescriptor>>
 ) : PackageFragmentProviderOptimized {
-  override fun collectPackageFragments(fqName: FqName, packageFragments: MutableCollection<PackageFragmentDescriptor>) {
+  override fun collectPackageFragments(
+    fqName: FqName,
+    packageFragments: MutableCollection<PackageFragmentDescriptor>
+  ) {
     val descriptors = packageDescriptorProvider[fqName] ?: return
     packageFragments.addAll(descriptors)
   }
@@ -63,7 +69,8 @@
   }
 
   override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean): List<FqName> {
-    return packageDescriptorProvider.asSequence()
+    return packageDescriptorProvider
+      .asSequence()
       .filter { (k, _) -> !k.isRoot && k.parent() == fqName }
       .mapTo(mutableListOf()) { it.key }
   }
@@ -71,4 +78,4 @@
   override fun isEmpty(fqName: FqName): Boolean {
     return packageDescriptorProvider[fqName].isNullOrEmpty()
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/testData/projects/SimpleKotlinProject/app/src/main/java/com/example/myapplication/FirstFragment.kt b/nav/safeargs/testData/projects/SimpleKotlinProject/app/src/main/java/com/example/myapplication/FirstFragment.kt
index f3e604d..01d8df5 100644
--- a/nav/safeargs/testData/projects/SimpleKotlinProject/app/src/main/java/com/example/myapplication/FirstFragment.kt
+++ b/nav/safeargs/testData/projects/SimpleKotlinProject/app/src/main/java/com/example/myapplication/FirstFragment.kt
@@ -17,4 +17,4 @@
 
 import androidx.fragment.app.Fragment
 
-class FirstFragment : Fragment()
\ No newline at end of file
+class FirstFragment : Fragment()
diff --git a/nav/safeargs/testData/projects/SimpleKotlinProject/app/src/main/java/com/example/myapplication/SecondFragment.kt b/nav/safeargs/testData/projects/SimpleKotlinProject/app/src/main/java/com/example/myapplication/SecondFragment.kt
index 77410f0..dac09c9 100644
--- a/nav/safeargs/testData/projects/SimpleKotlinProject/app/src/main/java/com/example/myapplication/SecondFragment.kt
+++ b/nav/safeargs/testData/projects/SimpleKotlinProject/app/src/main/java/com/example/myapplication/SecondFragment.kt
@@ -17,4 +17,4 @@
 
 import androidx.fragment.app.Fragment
 
-class SecondFragment : Fragment()
\ No newline at end of file
+class SecondFragment : Fragment()
diff --git a/nav/safeargs/testData/projects/SimpleKotlinProject/mylibrary/src/main/java/com/example/mylibrary/FirstFragment.kt b/nav/safeargs/testData/projects/SimpleKotlinProject/mylibrary/src/main/java/com/example/mylibrary/FirstFragment.kt
index 1277755..d49f55c 100644
--- a/nav/safeargs/testData/projects/SimpleKotlinProject/mylibrary/src/main/java/com/example/mylibrary/FirstFragment.kt
+++ b/nav/safeargs/testData/projects/SimpleKotlinProject/mylibrary/src/main/java/com/example/mylibrary/FirstFragment.kt
@@ -17,4 +17,4 @@
 
 import androidx.fragment.app.Fragment
 
-class FirstFragment : Fragment()
\ No newline at end of file
+class FirstFragment : Fragment()
diff --git a/nav/safeargs/testData/projects/SimpleKotlinProject/mylibrary/src/main/java/com/example/mylibrary/SecondFragment.kt b/nav/safeargs/testData/projects/SimpleKotlinProject/mylibrary/src/main/java/com/example/mylibrary/SecondFragment.kt
index 21dab25..d1c8076 100644
--- a/nav/safeargs/testData/projects/SimpleKotlinProject/mylibrary/src/main/java/com/example/mylibrary/SecondFragment.kt
+++ b/nav/safeargs/testData/projects/SimpleKotlinProject/mylibrary/src/main/java/com/example/mylibrary/SecondFragment.kt
@@ -17,4 +17,4 @@
 
 import androidx.fragment.app.Fragment
 
-class SecondFragment : Fragment()
\ No newline at end of file
+class SecondFragment : Fragment()
diff --git a/nav/safeargs/testData/projects/SimpleKotlinProject/mylibraryexcluded/src/main/java/com/example/mylibrary/FirstFragment.kt b/nav/safeargs/testData/projects/SimpleKotlinProject/mylibraryexcluded/src/main/java/com/example/mylibrary/FirstFragment.kt
index 1277755..d49f55c 100644
--- a/nav/safeargs/testData/projects/SimpleKotlinProject/mylibraryexcluded/src/main/java/com/example/mylibrary/FirstFragment.kt
+++ b/nav/safeargs/testData/projects/SimpleKotlinProject/mylibraryexcluded/src/main/java/com/example/mylibrary/FirstFragment.kt
@@ -17,4 +17,4 @@
 
 import androidx.fragment.app.Fragment
 
-class FirstFragment : Fragment()
\ No newline at end of file
+class FirstFragment : Fragment()
diff --git a/nav/safeargs/testData/projects/SimpleKotlinProject/mylibraryexcluded/src/main/java/com/example/mylibrary/SecondFragment.kt b/nav/safeargs/testData/projects/SimpleKotlinProject/mylibraryexcluded/src/main/java/com/example/mylibrary/SecondFragment.kt
index 21dab25..d1c8076 100644
--- a/nav/safeargs/testData/projects/SimpleKotlinProject/mylibraryexcluded/src/main/java/com/example/mylibrary/SecondFragment.kt
+++ b/nav/safeargs/testData/projects/SimpleKotlinProject/mylibraryexcluded/src/main/java/com/example/mylibrary/SecondFragment.kt
@@ -17,4 +17,4 @@
 
 import androidx.fragment.app.Fragment
 
-class SecondFragment : Fragment()
\ No newline at end of file
+class SecondFragment : Fragment()
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/SafeArgsRule.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/SafeArgsRule.kt
index a35f52b..8dd2e5e 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/SafeArgsRule.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/SafeArgsRule.kt
@@ -58,34 +58,49 @@
 
   override fun before() {
     fixture.testDataPath = TestDataPaths.TEST_DATA_ROOT
-    fixture.addFileToProject("AndroidManifest.xml", """
+    fixture.addFileToProject(
+      "AndroidManifest.xml",
+      """
       <?xml version="1.0" encoding="utf-8"?>
       <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="test.safeargs">
         <application />
       </manifest>
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
 
     androidFacet.safeArgsMode = mode
 
     // Add fake "NavArgs" interface to this project so the args class can resolve its interface
-    with(fixture.addFileToProject("src/androidx/navigation/NavArgs.java",
-      // language=java
-      """
+    with(
+      fixture.addFileToProject(
+        "src/androidx/navigation/NavArgs.java",
+        // language=java
+        """
         package androidx.navigation;
 
         public interface NavArgs {}
-      """.trimIndent())) {
+      """
+          .trimIndent()
+      )
+    ) {
       fixture.allowTreeAccessForFile(this.virtualFile)
     }
 
-    // Add fake "NavDirections" interface to this project so the args class can resolve its interface
-    with(fixture.addFileToProject("src/androidx/navigation/NavDirections.java",
-      // language=java
-      """
+    // Add fake "NavDirections" interface to this project so the args class can resolve its
+    // interface
+    with(
+      fixture.addFileToProject(
+        "src/androidx/navigation/NavDirections.java",
+        // language=java
+        """
         package androidx.navigation;
 
         public interface NavDirections {}
-      """.trimIndent())) {
+      """
+          .trimIndent()
+      )
+    ) {
       fixture.allowTreeAccessForFile(this.virtualFile)
     }
   }
@@ -93,7 +108,9 @@
   override fun apply(base: Statement, description: Description): Statement {
     // We want to run tests on the EDT thread, but we also need to make sure the project rule is not
     // initialized on the EDT.
-    return RuleChain.outerRule(projectRule).around(EdtRule()).apply(super.apply(base, description), description)
+    return RuleChain.outerRule(projectRule)
+      .around(EdtRule())
+      .apply(super.apply(base, description), description)
   }
 
   /**
@@ -106,7 +123,11 @@
    */
   fun addFakeNavigationDependency(version: Version) {
     val projectSystem = TestProjectSystem(module.project)
-    projectSystem.addDependency(GoogleMavenArtifactId.ANDROIDX_NAVIGATION_COMMON, module, GradleVersion.parse(version.toString()))
+    projectSystem.addDependency(
+      GoogleMavenArtifactId.ANDROIDX_NAVIGATION_COMMON,
+      module,
+      GradleVersion.parse(version.toString())
+    )
     projectSystem.useInTests()
   }
 }
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/TestDataPaths.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/TestDataPaths.kt
index 4e706a5..9dba789 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/TestDataPaths.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/TestDataPaths.kt
@@ -17,11 +17,10 @@
 
 import com.android.testutils.TestUtils.resolveWorkspacePath
 
-/**
- * Constants for safe args test project paths.
- */
+/** Constants for safe args test project paths. */
 object TestDataPaths {
-  val TEST_DATA_ROOT: String = resolveWorkspacePath("tools/adt/idea/nav/safeargs/testData").toString()
+  val TEST_DATA_ROOT: String =
+    resolveWorkspacePath("tools/adt/idea/nav/safeargs/testData").toString()
 
   const val PROJECT_WITHOUT_SAFE_ARGS = "projects/projectWithoutSafeArgs"
   const val PROJECT_USING_JAVA_PLUGIN = "projects/safeArgsWithJavaPlugin"
@@ -29,4 +28,4 @@
   const val MULTI_MODULE_PROJECT = "projects/safeArgsMultiModuleProject"
   const val SIMPLE_JAVA_PROJECT = "projects/SimpleJavaProject"
   const val SIMPLE_KOTLIN_PROJECT = "projects/SimpleKotlinProject"
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/cache/gradle/ShortNamesCacheTestMultiJavaModules.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/cache/gradle/ShortNamesCacheTestMultiJavaModules.kt
index e39653f..46090cc 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/cache/gradle/ShortNamesCacheTestMultiJavaModules.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/cache/gradle/ShortNamesCacheTestMultiJavaModules.kt
@@ -34,10 +34,10 @@
   private val projectRule = AndroidGradleProjectRule()
 
   // The tests need to run on the EDT thread but we must initialize the project rule off of it
-  @get:Rule
-  val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
+  @get:Rule val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
 
-  private val fixture get() = projectRule.fixture as JavaCodeInsightTestFixture
+  private val fixture
+    get() = projectRule.fixture as JavaCodeInsightTestFixture
 
   @Before
   fun setUp() {
@@ -47,10 +47,11 @@
   }
 
   /**
-   *  Project structure:
-   *  base app module --> lib1 dep module(safe arg mode is off) --> lib2 dep module(safe arg mode is on)
+   * Project structure: base app module --> lib1 dep module(safe arg mode is off) --> lib2 dep
+   * module(safe arg mode is on)
    *
-   *  So light classes from lib2 module should be exposed, but light classes from lib1 should not be exposed.
+   * So light classes from lib2 module should be exposed, but light classes from lib1 should not be
+   * exposed.
    */
   @Test
   fun multiModuleTest() {
@@ -58,34 +59,33 @@
     val cache = PsiShortNamesCache.getInstance(fixture.project)
 
     // Check light arg classes
-    assertThat(cache.getContents("FirstFragmentArgs", fixture.project)).containsExactly(
-      "com.example.myapplication.FirstFragmentArgs",
-      "com.example.mylibrary2.FirstFragmentArgs"
-    )
+    assertThat(cache.getContents("FirstFragmentArgs", fixture.project))
+      .containsExactly(
+        "com.example.myapplication.FirstFragmentArgs",
+        "com.example.mylibrary2.FirstFragmentArgs"
+      )
 
-    assertThat(cache.getContents("SecondFragmentArgs", fixture.project)).containsExactly(
-      "com.example.myapplication.SecondFragmentArgs"
-    )
-
+    assertThat(cache.getContents("SecondFragmentArgs", fixture.project))
+      .containsExactly("com.example.myapplication.SecondFragmentArgs")
 
     // Check light direction classes
-    assertThat(cache.getContents("FirstFragmentDirections", fixture.project)).containsExactly(
-      "com.example.myapplication.FirstFragmentDirections",
-      "com.example.mylibrary2.FirstFragmentDirections"
-    )
+    assertThat(cache.getContents("FirstFragmentDirections", fixture.project))
+      .containsExactly(
+        "com.example.myapplication.FirstFragmentDirections",
+        "com.example.mylibrary2.FirstFragmentDirections"
+      )
 
-    assertThat(cache.getContents("SecondFragmentDirections", fixture.project)).containsExactly(
-      "com.example.myapplication.SecondFragmentDirections"
-    )
+    assertThat(cache.getContents("SecondFragmentDirections", fixture.project))
+      .containsExactly("com.example.myapplication.SecondFragmentDirections")
 
     // Check light builder classes
-    assertThat(cache.getContents("Builder", fixture.project)).containsAllOf(
-      "com.example.myapplication.FirstFragmentArgs.Builder",
-      "com.example.mylibrary2.FirstFragmentArgs.Builder"
-    )
+    assertThat(cache.getContents("Builder", fixture.project))
+      .containsAllOf(
+        "com.example.myapplication.FirstFragmentArgs.Builder",
+        "com.example.mylibrary2.FirstFragmentArgs.Builder"
+      )
 
-    assertThat(cache.getContents("Builder", fixture.project)).contains(
-      "com.example.myapplication.SecondFragmentArgs.Builder"
-    )
+    assertThat(cache.getContents("Builder", fixture.project))
+      .contains("com.example.myapplication.SecondFragmentArgs.Builder")
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/cache/gradle/ShortNamesCacheTestSingleJavaModule.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/cache/gradle/ShortNamesCacheTestSingleJavaModule.kt
index 59d3366..e465b49 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/cache/gradle/ShortNamesCacheTestSingleJavaModule.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/cache/gradle/ShortNamesCacheTestSingleJavaModule.kt
@@ -25,14 +25,13 @@
 
 @RunsInEdt
 class ShortNamesCacheTestSingleJavaModule {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule()
+  @get:Rule val safeArgsRule = SafeArgsRule()
 
   @Test
   fun getShortNamesCache() {
     val project = safeArgsRule.project
     val xmlContent =
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -53,23 +52,20 @@
                   app:destination="@id/main" />                  
           </fragment>
         </navigation>
-      """.trimIndent()
+      """
+        .trimIndent()
     safeArgsRule.fixture.addFileToProject("res/navigation/main.xml", xmlContent)
     val cache = PsiShortNamesCache.getInstance(project)
 
     // Check light arg classes
-    assertThat(cache.getContents("FragmentArgs", project)).containsExactly(
-      "test.safeargs.FragmentArgs"
-    )
+    assertThat(cache.getContents("FragmentArgs", project))
+      .containsExactly("test.safeargs.FragmentArgs")
 
     // Check light direction classes
-    assertThat(cache.getContents("FragmentDirections", project)).containsExactly(
-      "test.safeargs.FragmentDirections"
-    )
+    assertThat(cache.getContents("FragmentDirections", project))
+      .containsExactly("test.safeargs.FragmentDirections")
 
     // Check light builder classes
-    assertThat(cache.getContents("Builder", project)).contains(
-      "test.safeargs.FragmentArgs.Builder"
-    )
+    assertThat(cache.getContents("Builder", project)).contains("test.safeargs.FragmentArgs.Builder")
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/codegen/gradle/SafeArgsGeneratedJavaCodeMatchTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/codegen/gradle/SafeArgsGeneratedJavaCodeMatchTest.kt
index 0192a5c..fbbca1d 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/codegen/gradle/SafeArgsGeneratedJavaCodeMatchTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/codegen/gradle/SafeArgsGeneratedJavaCodeMatchTest.kt
@@ -36,6 +36,7 @@
 import com.intellij.testFramework.EdtRule
 import com.intellij.testFramework.RunsInEdt
 import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
+import java.io.File
 import org.jetbrains.uast.UClass
 import org.jetbrains.uast.toUElement
 import org.jetbrains.uast.visitor.AbstractUastVisitor
@@ -45,39 +46,42 @@
 import org.junit.Test
 import org.junit.rules.RuleChain
 import org.junit.rules.TemporaryFolder
-import java.io.File
 
 @RunsInEdt
 class SafeArgsGeneratedJavaCodeMatchTest {
   private val moduleName = "javaapp"
   private val projectRule = AndroidGradleProjectRule()
-  private val fixture get() = projectRule.fixture as JavaCodeInsightTestFixture
-  //TODO (b/162520387): Do not ignore these methods when testing.
-  private val IGNORED_METHODS = setOf("equals", "hashCode", "toString", "getActionId", "getArguments")
+  private val fixture
+    get() = projectRule.fixture as JavaCodeInsightTestFixture
+  // TODO (b/162520387): Do not ignore these methods when testing.
+  private val IGNORED_METHODS =
+    setOf("equals", "hashCode", "toString", "getActionId", "getArguments")
 
-  @get:Rule
-  val expect: Expect = Expect.create()
+  @get:Rule val expect: Expect = Expect.create()
 
-  @get:Rule
-  val temporaryFolder = TemporaryFolder()
+  @get:Rule val temporaryFolder = TemporaryFolder()
 
-  @get:Rule
-  val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
+  @get:Rule val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
 
   @Before
   fun initProject() {
     // to be able to change the project before import, we copy it into a temp folder
-    val testSrc = resolveWorkspacePath("tools/adt/idea/nav/safeargs/testData/projects/SafeArgsTestApp")
+    val testSrc =
+      resolveWorkspacePath("tools/adt/idea/nav/safeargs/testData/projects/SafeArgsTestApp")
     val container = temporaryFolder.newFile("TestApp")
     testSrc.toFile().copyRecursively(container, overwrite = true)
 
-    val settingsFile = container.resolve("settings.gradle").also {
-      assertWithMessage("settings file should exist").that(it.exists()).isTrue()
-    }
+    val settingsFile =
+      container.resolve("settings.gradle").also {
+        assertWithMessage("settings file should exist").that(it.exists()).isTrue()
+      }
     // update settings to only include the desired module
-    settingsFile.writeText("""
+    settingsFile.writeText(
+      """
       include ':$moduleName'
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
 
     projectRule.fixture.testDataPath = temporaryFolder.root.absolutePath
     projectRule.load("TestApp") { projectRoot ->
@@ -89,7 +93,9 @@
           // language=java
           """
             class FooClass
-          """.trimIndent())
+          """
+            .trimIndent()
+        )
       }
     }
 
@@ -101,9 +107,12 @@
     assertThat(assembleDebug.isBuildSuccessful).isTrue()
 
     LocalFileSystem.getInstance().refresh(false)
-    val codeOutDir = File(projectRule.project.basePath, "$moduleName/$PLUGIN_OUT_DIR").also {
-      assertWithMessage("should be able to find generated navigation code").that(it.exists()).isTrue()
-    }
+    val codeOutDir =
+      File(projectRule.project.basePath, "$moduleName/$PLUGIN_OUT_DIR").also {
+        assertWithMessage("should be able to find generated navigation code")
+          .that(it.exists())
+          .isTrue()
+      }
     // parse generated code
     val allGeneratedCode = listOf(codeOutDir).flatMap(::loadClasses).toSet()
     // delete generated code
@@ -127,14 +136,24 @@
       val psiClass = psiFacade.findClass(generated.qualifiedName, scope)!!
       val psiDescription = psiClass.toDescription()
 
-      expect.withMessage(generated.qualifiedName).that(psiDescription.qualifiedName).isEqualTo(generated.qualifiedName)
-      expect.withMessage(generated.qualifiedName).that(psiDescription.methods).containsExactlyElementsIn(generated.methods)
-      expect.withMessage(generated.qualifiedName).that(psiDescription.fields).containsExactlyElementsIn(generated.fields)
+      expect
+        .withMessage(generated.qualifiedName)
+        .that(psiDescription.qualifiedName)
+        .isEqualTo(generated.qualifiedName)
+      expect
+        .withMessage(generated.qualifiedName)
+        .that(psiDescription.methods)
+        .containsExactlyElementsIn(generated.methods)
+      expect
+        .withMessage(generated.qualifiedName)
+        .that(psiDescription.fields)
+        .containsExactlyElementsIn(generated.fields)
     }
   }
 
   private fun loadClasses(classesOut: File): List<ClassDescription> {
-    return classesOut.walkTopDown()
+    return classesOut
+      .walkTopDown()
       .filter { it.name.endsWith(".java") }
       .toList()
       .flatMap { generatedSourceFile -> generatedSourceFile.loadClassesDescriptions() }
@@ -143,58 +162,67 @@
   private fun File.loadClassesDescriptions(): List<ClassDescription> {
     val descriptions = mutableListOf<ClassDescription>()
 
-    val virtual = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(this) ?: throw IllegalArgumentException("cannot find $this")
+    val virtual =
+      LocalFileSystem.getInstance().refreshAndFindFileByIoFile(this)
+        ?: throw IllegalArgumentException("cannot find $this")
     val psi = PsiManager.getInstance(projectRule.project).findFile(virtual)
     val uast = psi.toUElement()!!
-    uast.accept(object : AbstractUastVisitor() {
-      override fun visitClass(node: UClass): Boolean {
-        node.javaPsi.takeIf { it.modifierSet().contains(JvmModifier.PUBLIC) }
-          ?.toDescription()
-          ?.let { descriptions.add(it) }
-        return super.visitClass(node)
+    uast.accept(
+      object : AbstractUastVisitor() {
+        override fun visitClass(node: UClass): Boolean {
+          node.javaPsi
+            .takeIf { it.modifierSet().contains(JvmModifier.PUBLIC) }
+            ?.toDescription()
+            ?.let { descriptions.add(it) }
+          return super.visitClass(node)
+        }
       }
-    })
+    )
     return descriptions
   }
 
-  private fun PsiClass.toDescription() = ClassDescription(
-    qualifiedName = this.qualifiedName!!,
-    methods = (methods + constructors)
-      .filter { it.modifierSet().contains(JvmModifier.PUBLIC) }
-      .map { it.toDescription() }
-      .filter { !IGNORED_METHODS.contains(it.name) }
-      .sortedBy { it.name }
-      .toSet(),
-    fields = fields
-      .filter { it.modifierSet().contains(JvmModifier.PUBLIC) }
-      .map { it.toDescription() }
-      .sortedBy { it.name }
-      .toSet()
-  )
+  private fun PsiClass.toDescription() =
+    ClassDescription(
+      qualifiedName = this.qualifiedName!!,
+      methods =
+        (methods + constructors)
+          .filter { it.modifierSet().contains(JvmModifier.PUBLIC) }
+          .map { it.toDescription() }
+          .filter { !IGNORED_METHODS.contains(it.name) }
+          .sortedBy { it.name }
+          .toSet(),
+      fields =
+        fields
+          .filter { it.modifierSet().contains(JvmModifier.PUBLIC) }
+          .map { it.toDescription() }
+          .sortedBy { it.name }
+          .toSet()
+    )
 
-  private fun PsiMethod.toDescription() = MethodDescription(
-    name = this.name,
-    type = this.returnType?.toDescription(),
-    params = this.parameters
-      .filterIsInstance<PsiParameter>()
-      .map { it.toDescription() }
-      .toSet(),
-    modifiers = this.modifierSet()
-  )
+  private fun PsiMethod.toDescription() =
+    MethodDescription(
+      name = this.name,
+      type = this.returnType?.toDescription(),
+      params = this.parameters.filterIsInstance<PsiParameter>().map { it.toDescription() }.toSet(),
+      modifiers = this.modifierSet()
+    )
 
-  private fun PsiParameter.toDescription() = ParamDescription(
-    name = this.name,
-    type = this.type.toDescription(),
-    modifiers = this.modifierSet().filter { it != JvmModifier.PACKAGE_LOCAL }.toSet()
-  )
+  private fun PsiParameter.toDescription() =
+    ParamDescription(
+      name = this.name,
+      type = this.type.toDescription(),
+      modifiers = this.modifierSet().filter { it != JvmModifier.PACKAGE_LOCAL }.toSet()
+    )
 
-  private fun PsiField.toDescription() = FieldDescription(
-    name = this.name,
-    type = this.type.toDescription(),
-    modifiers = this.modifierSet()
-  )
+  private fun PsiField.toDescription() =
+    FieldDescription(
+      name = this.name,
+      type = this.type.toDescription(),
+      modifiers = this.modifierSet()
+    )
 
-  private fun PsiType.toDescription() = this.canonicalText.substringAfterLast('.').substringAfterLast('$')
+  private fun PsiType.toDescription() =
+    this.canonicalText.substringAfterLast('.').substringAfterLast('$')
 
   private data class ClassDescription(
     val qualifiedName: String,
@@ -206,22 +234,26 @@
     val name: String,
     val type: String?,
     val modifiers: Set<JvmModifier>,
-    val params: Set<ParamDescription>)
+    val params: Set<ParamDescription>
+  )
 
   private data class FieldDescription(
     val name: String,
     val type: String,
-    val modifiers: Set<JvmModifier>)
+    val modifiers: Set<JvmModifier>
+  )
 
   private data class ParamDescription(
     val name: String,
     val type: String,
-    val modifiers: Set<JvmModifier>)
+    val modifiers: Set<JvmModifier>
+  )
 
-  private fun PsiModifierListOwner.modifierSet() = JvmModifier.values().filter { hasModifier(it) }.toSet()
+  private fun PsiModifierListOwner.modifierSet() =
+    JvmModifier.values().filter { hasModifier(it) }.toSet()
 
   companion object {
     const val PLUGIN_OUT_DIR = "build/generated/source/navigation-args/debug"
     const val GENERATE_TASK = "generateSafeArgsDebug"
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/extensions/PsiMethodUtils.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/extensions/PsiMethodUtils.kt
index 037a43c..225effa 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/extensions/PsiMethodUtils.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/extensions/PsiMethodUtils.kt
@@ -25,9 +25,7 @@
 import com.intellij.psi.PsiType
 import com.intellij.psi.PsiTypes
 
-/**
- * A simple sanity check helper for [PsiMethod] instances using String checks.
- */
+/** A simple sanity check helper for [PsiMethod] instances using String checks. */
 fun PsiMethod.checkSignaturesAndReturnType(
   name: String,
   returnType: String,
@@ -38,8 +36,7 @@
 
   if (returnType == PsiTypes.nullType().presentableText) {
     assertThat(getTypeName(this.returnType)).isNull()
-  }
-  else {
+  } else {
     assertThat(getTypeName(this.returnType)).isEqualTo(returnType)
 
     val nullabilityManager = NullableNotNullManager.getInstance(this.project)
@@ -48,11 +45,13 @@
 
   assertThat(this.parameters.size).isEqualTo(parameters.size)
 
-  this.parameters.map { parameter ->
-    val pName = parameter.name!!
-    val pType = getTypeName((parameter as PsiParameter).type)!!
-    Parameter(pName, pType)
-  }.containsAll(parameters)
+  this.parameters
+    .map { parameter ->
+      val pName = parameter.name!!
+      val pType = getTypeName((parameter as PsiParameter).type)!!
+      Parameter(pName, pType)
+    }
+    .containsAll(parameters)
 }
 
 private fun getTypeName(type: PsiType?): String? {
@@ -67,8 +66,4 @@
   }
 }
 
-data class Parameter(
-  val name: String,
-  val type: String
-)
-
+data class Parameter(val name: String, val type: String)
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/extensions/PsiShortNamesCacheUtils.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/extensions/PsiShortNamesCacheUtils.kt
index d7e469e..f0767ba 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/extensions/PsiShortNamesCacheUtils.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/extensions/PsiShortNamesCacheUtils.kt
@@ -24,4 +24,4 @@
     .asSequence()
     .mapNotNull { it.qualifiedName }
     .toSortedSet()
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/extensions/VirtualFileUtils.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/extensions/VirtualFileUtils.kt
index 7e01dc6..2f4837b 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/extensions/VirtualFileUtils.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/extensions/VirtualFileUtils.kt
@@ -43,4 +43,4 @@
     PsiDocumentManager.getInstance(project).commitDocument(this)
     FileDocumentManager.getInstance().saveDocument(this)
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/gradle/SafeArgsModeSyncGradlePluginTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/gradle/SafeArgsModeSyncGradlePluginTest.kt
index 1930276..51b7f3d 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/gradle/SafeArgsModeSyncGradlePluginTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/gradle/SafeArgsModeSyncGradlePluginTest.kt
@@ -34,9 +34,7 @@
 import org.junit.runners.Parameterized
 import org.mockito.Mockito.verify
 
-/**
- * Verify that we can sync a Gradle project that applies the safe args plugin.
- */
+/** Verify that we can sync a Gradle project that applies the safe args plugin. */
 @RunsInEdt
 @RunWith(Parameterized::class)
 class SafeArgsModeSyncGradlePluginTest(val params: TestParams) {
@@ -46,19 +44,20 @@
     @Suppress("unused") // Accessed via reflection by JUnit
     @JvmStatic
     @get:Parameterized.Parameters(name = "{0}")
-    val parameters = listOf(
-      TestParams(TestDataPaths.PROJECT_USING_JAVA_PLUGIN, SafeArgsMode.JAVA),
-      TestParams(TestDataPaths.PROJECT_USING_KOTLIN_PLUGIN, SafeArgsMode.KOTLIN)
-    )
+    val parameters =
+      listOf(
+        TestParams(TestDataPaths.PROJECT_USING_JAVA_PLUGIN, SafeArgsMode.JAVA),
+        TestParams(TestDataPaths.PROJECT_USING_KOTLIN_PLUGIN, SafeArgsMode.KOTLIN)
+      )
   }
 
   private val projectRule = AndroidGradleProjectRule()
 
   // The tests need to run on the EDT thread but we must initialize the project rule off of it
-  @get:Rule
-  val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
+  @get:Rule val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
 
-  private val fixture get() = projectRule.fixture as JavaCodeInsightTestFixture
+  private val fixture
+    get() = projectRule.fixture as JavaCodeInsightTestFixture
   private var modificationCountBaseline = Long.MIN_VALUE
 
   @Before
@@ -71,18 +70,22 @@
   @Test
   fun verifyExpectedSafeMode() {
     val listener = mock<SafeArgsModeModuleService.SafeArgsModeChangedListener>()
-    projectRule.project.messageBus.connect(fixture.projectDisposable).subscribe(
-      SafeArgsModeModuleService.MODE_CHANGED,
-      SafeArgsModeModuleService.SafeArgsModeChangedListener { module, mode ->
-        listener.onSafeArgsModeChanged(module, mode)
-      })
+    projectRule.project.messageBus
+      .connect(fixture.projectDisposable)
+      .subscribe(
+        SafeArgsModeModuleService.MODE_CHANGED,
+        SafeArgsModeModuleService.SafeArgsModeChangedListener { module, mode ->
+          listener.onSafeArgsModeChanged(module, mode)
+        }
+      )
 
     projectRule.load(params.project)
     projectRule.requestSyncAndWait()
 
     val facet = projectRule.androidFacet(":app")
     assertThat(facet.safeArgsMode).isEqualTo(params.mode)
-    assertThat(projectRule.project.safeArgsModeTracker.modificationCount).isGreaterThan(modificationCountBaseline)
+    assertThat(projectRule.project.safeArgsModeTracker.modificationCount)
+      .isGreaterThan(modificationCountBaseline)
     verify(listener).onSafeArgsModeChanged(facet.module, params.mode)
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/index/NavXmlIndexTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/index/NavXmlIndexTest.kt
index 9590086..118cc6a 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/index/NavXmlIndexTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/index/NavXmlIndexTest.kt
@@ -20,26 +20,27 @@
 import com.intellij.openapi.application.runReadAction
 import com.intellij.util.indexing.FileContentImpl
 import com.intellij.util.io.DataExternalizer
-import org.junit.Rule
-import org.junit.Test
 import java.io.ByteArrayInputStream
 import java.io.ByteArrayOutputStream
 import java.io.DataInputStream
 import java.io.DataOutputStream
+import org.junit.Rule
+import org.junit.Test
 
 class NavXmlIndexTest {
-  @get:Rule
-  val projectRule = AndroidProjectRule.onDisk()
+  @get:Rule val projectRule = AndroidProjectRule.onDisk()
 
   private val fixture by lazy { projectRule.fixture }
   private val project by lazy { projectRule.project }
 
   @Test
   fun indexNavigationLayout() {
-    val file = fixture.addFileToProject(
-      "navigation/main.xml",
-      //language=XML
-      """
+    val file =
+      fixture
+        .addFileToProject(
+          "navigation/main.xml",
+          // language=XML
+          """
       <navigation xmlns:android="http://schemas.android.com/apk/res/android"
                   xmlns:app="http://schemas.android.com/apk/res-auto"
                   xmlns:tools="http://schemas.android.com/tools"
@@ -133,7 +134,10 @@
           </navigation>
 
       </navigation>
-    """.trimIndent()).virtualFile
+    """
+            .trimIndent()
+        )
+        .virtualFile
 
     val navXmlIndex = NavXmlIndex()
     assertThat(navXmlIndex.inputFilter.acceptInput(file)).isEqualTo(true)
@@ -271,18 +275,29 @@
 
     // Verify all three destinations can be found from the root
     assertThat(data.resolvedDestinations.map { it.id })
-      .containsExactly("top_level_nav", "activity1", "fragment1", "fragment2", "nested_nav", "activity2", "fragment3", "double_nested_nav",
-                       "dialog1")
+      .containsExactly(
+        "top_level_nav",
+        "activity1",
+        "fragment1",
+        "fragment2",
+        "nested_nav",
+        "activity2",
+        "fragment3",
+        "double_nested_nav",
+        "dialog1"
+      )
 
     verifySerializationLogic(navXmlIndex.valueExternalizer, data)
   }
 
   @Test
   fun navigationIdIsOptional() {
-    val file = fixture.addFileToProject(
-      "navigation/main.xml",
-      //language=XML
-      """
+    val file =
+      fixture
+        .addFileToProject(
+          "navigation/main.xml",
+          // language=XML
+          """
       <navigation xmlns:android="http://schemas.android.com/apk/res/android"
                   xmlns:app="http://schemas.android.com/apk/res-auto"
                   xmlns:tools="http://schemas.android.com/tools"
@@ -292,7 +307,10 @@
                     android:name="test.safeargs.Fragment1"
                     tools:layout="@layout/fragment1" />
       </navigation>
-    """.trimIndent()).virtualFile
+    """
+            .trimIndent()
+        )
+        .virtualFile
 
     val navXmlIndex = NavXmlIndex()
     val map = navXmlIndex.indexer.map(FileContentImpl.createByFile(file))
@@ -308,10 +326,12 @@
 
   @Test
   fun customTagsAreTreatedAsPotentialDestinations() {
-    val file = fixture.addFileToProject(
-      "navigation/main.xml",
-      //language=XML
-      """
+    val file =
+      fixture
+        .addFileToProject(
+          "navigation/main.xml",
+          // language=XML
+          """
       <navigation xmlns:android="http://schemas.android.com/apk/res/android"
                   xmlns:app="http://schemas.android.com/apk/res-auto"
                   xmlns:tools="http://schemas.android.com/tools"
@@ -328,7 +348,10 @@
           <unknownTag /> <!-- Probably breaks compiling but shouldn't break indexing -->
           
       </navigation>
-    """.trimIndent()).virtualFile
+    """
+            .trimIndent()
+        )
+        .virtualFile
 
     val navXmlIndex = NavXmlIndex()
     val map = navXmlIndex.indexer.map(FileContentImpl.createByFile(file))
@@ -337,18 +360,22 @@
 
     val data = map.values.first()
     assertThat(data.root.potentialDestinations).hasSize(3)
-    // unknownTag, though potential, doesn't meet destination requirements, so it is stripped out at this time
-    assertThat(data.root.potentialDestinations.mapNotNull { it.toDestination()?.id }).containsExactly("fragment1", "custom1")
+    // unknownTag, though potential, doesn't meet destination requirements, so it is stripped out at
+    // this time
+    assertThat(data.root.potentialDestinations.mapNotNull { it.toDestination()?.id })
+      .containsExactly("fragment1", "custom1")
 
     verifySerializationLogic(navXmlIndex.valueExternalizer, data)
   }
 
   @Test
   fun camelCaseIdsInNavigationTagAreSupported() {
-    val file = fixture.addFileToProject(
-      "navigation/main.xml",
-      //language=XML
-      """
+    val file =
+      fixture
+        .addFileToProject(
+          "navigation/main.xml",
+          // language=XML
+          """
       <!-- Recommend syntax is "camel_case_graph" but "camelCaseGraph" works too -->
       <navigation xmlns:android="http://schemas.android.com/apk/res/android"
                   xmlns:app="http://schemas.android.com/apk/res-auto"
@@ -361,7 +388,10 @@
                     tools:layout="@layout/fragment" />
 
       </navigation>
-    """.trimIndent()).virtualFile
+    """
+            .trimIndent()
+        )
+        .virtualFile
 
     val navXmlIndex = NavXmlIndex()
     val map = navXmlIndex.indexer.map(FileContentImpl.createByFile(file))
@@ -378,16 +408,21 @@
 
   @Test
   fun indexRecoversFromUnrelatedXml() {
-    val file = fixture.addFileToProject(
-      "navigation/main.xml",
-      //language=XML
-      """
+    val file =
+      fixture
+        .addFileToProject(
+          "navigation/main.xml",
+          // language=XML
+          """
         <?xml version="1.0" encoding="utf-8"?>
         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
               package="com.example.nav.safeargs">
             <application android:label="Safe Args Test" />
         </manifest>
-    """.trimIndent()).virtualFile
+    """
+            .trimIndent()
+        )
+        .virtualFile
 
     val navXmlIndex = NavXmlIndex()
     assertThat(navXmlIndex.inputFilter.acceptInput(file)).isEqualTo(true)
@@ -399,10 +434,12 @@
   @Test
   fun xmlWithOpeningCommentIsParsed() {
     // Regression test for b/300221546
-    val file = fixture.addFileToProject(
-      "navigation/main.xml",
-      //language=XML
-      """
+    val file =
+      fixture
+        .addFileToProject(
+          "navigation/main.xml",
+          // language=XML
+          """
       <?xml version="1.0" encoding="utf-8"?>
       <!-- Comment `1234567890-=~!@#$%^&*()_+,./;'[]<>?:"{}\| -->
       <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -415,7 +452,10 @@
                     android:name="test.safeargs.Fragment1"
                     tools:layout="@layout/fragment1" />
       </navigation>
-    """.trimIndent()).virtualFile
+    """
+            .trimIndent()
+        )
+        .virtualFile
 
     val navXmlIndex = NavXmlIndex()
     val map = navXmlIndex.indexer.map(FileContentImpl.createByFile(file))
@@ -432,10 +472,12 @@
   @Test
   fun navigationFileOutsideResourcesDirIsNotReturnedFromIndex() {
     // Valid navigation file in correct resource directory.
-    val navigationFile = fixture.addFileToProject(
-      "navigation/main.xml",
-      //language=XML
-      """
+    val navigationFile =
+      fixture
+        .addFileToProject(
+          "navigation/main.xml",
+          // language=XML
+          """
       <?xml version="1.0" encoding="utf-8"?>
       <navigation xmlns:android="http://schemas.android.com/apk/res/android"
                   xmlns:app="http://schemas.android.com/apk/res-auto"
@@ -447,13 +489,18 @@
                     android:name="test.safeargs.Fragment1"
                     tools:layout="@layout/fragment1" />
       </navigation>
-    """.trimIndent()).virtualFile
+    """
+            .trimIndent()
+        )
+        .virtualFile
 
     // Valid navigation file, but in non-resource directory.
-    val otherFile = fixture.addFileToProject(
-      "otherDir/main.xml",
-      //language=XML
-      """
+    val otherFile =
+      fixture
+        .addFileToProject(
+          "otherDir/main.xml",
+          // language=XML
+          """
       <?xml version="1.0" encoding="utf-8"?>
       <navigation xmlns:android="http://schemas.android.com/apk/res/android"
                   xmlns:app="http://schemas.android.com/apk/res-auto"
@@ -465,7 +512,10 @@
                     android:name="test.safeargs.Fragment1"
                     tools:layout="@layout/fragment1" />
       </navigation>
-    """.trimIndent()).virtualFile
+    """
+            .trimIndent()
+        )
+        .virtualFile
 
     runReadAction {
       assertThat(NavXmlIndex.getDataForFile(project, navigationFile)).isNotNull()
@@ -473,7 +523,10 @@
     }
   }
 
-  private fun verifySerializationLogic(valueExternalizer: DataExternalizer<NavXmlData>, data: NavXmlData) {
+  private fun verifySerializationLogic(
+    valueExternalizer: DataExternalizer<NavXmlData>,
+    data: NavXmlData
+  ) {
     val bytesOut = ByteArrayOutputStream()
     DataOutputStream(bytesOut).use { valueExternalizer.save(it, data) }
 
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/module/DumbModeTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/module/DumbModeTest.kt
index bb731a3..f7055cd 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/module/DumbModeTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/module/DumbModeTest.kt
@@ -30,8 +30,7 @@
 
 @RunsInEdt
 class DumbModeTest {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule()
+  @get:Rule val safeArgsRule = SafeArgsRule()
 
   @Before
   fun setUp() {
@@ -42,7 +41,7 @@
   fun indexWhenDumbMode() {
     val project = safeArgsRule.project
     val xmlContent =
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -59,7 +58,8 @@
                   app:argType="string" />
           </fragment>
         </navigation>
-      """.trimIndent()
+      """
+        .trimIndent()
     val navFile = safeArgsRule.fixture.addFileToProject("res/navigation/main.xml", xmlContent)
     safeArgsRule.waitForResourceRepositoryUpdates()
     val moduleCache = SafeArgsCacheModuleService.getInstance(safeArgsRule.androidFacet)
@@ -74,7 +74,8 @@
               android:name="arg2"
               app:argType="integer" />
         </fragment>
-      """.trimIndent()
+      """
+        .trimIndent()
     WriteCommandAction.runWriteCommandAction(project) {
       navFile.virtualFile.replaceWithSaving("</fragment>", replaceXmlContent, project)
     }
@@ -86,20 +87,22 @@
     assertThat(getNumberOfArgs(moduleCache.args)).isEqualTo(2)
   }
 
-  private fun getNumberOfArgs(args: List<LightArgsClass>) = args.sumOf { it.destination.arguments.size }
+  private fun getNumberOfArgs(args: List<LightArgsClass>) =
+    args.sumOf { it.destination.arguments.size }
 
   @Test
   fun scopeDoesNotCacheStaleValuesInDumbMode() {
     val dumbService = DumbServiceImpl.getInstance(safeArgsRule.project)
     assertThat(dumbService.isDumb).isFalse()
 
-    // In dumb mode, add a resource and then request the current scope. In the past, this would cause
+    // In dumb mode, add a resource and then request the current scope. In the past, this would
+    // cause
     // the scope enlarger to internally cache stale values (because the service that the enlarger
     // queries into aborts early in dumb mode).
     dumbService.isDumb = true
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/nav_main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -116,7 +119,9 @@
                 app:destination="@id/main" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
     safeArgsRule.waitForResourceRepositoryUpdates()
     val fragmentClass = safeArgsRule.fixture.addClass("public class MainFragment {}")
 
@@ -135,4 +140,4 @@
       assertThat(PsiSearchScopeUtil.isInScope(enlargedScope, directionsClass)).isTrue()
     }
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/module/NavStatusCacheTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/module/NavStatusCacheTest.kt
index 228ef4e..d957a1c 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/module/NavStatusCacheTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/module/NavStatusCacheTest.kt
@@ -1,4 +1,5 @@
-// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the
+// Apache 2.0 license.
 package com.android.tools.idea.nav.safeargs.module
 
 import com.android.testutils.MockitoKt.mock
@@ -7,15 +8,16 @@
 import com.android.tools.idea.nav.safeargs.SafeArgsRule
 import com.android.tools.idea.nav.safeargs.psi.SafeArgsFeatureVersions
 import com.google.common.truth.Truth.assertThat
+import java.util.EnumSet
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
-import java.util.EnumSet
 
 class NavStatusCacheTest {
   @get:Rule val safeArgsRule = SafeArgsRule(SafeArgsMode.KOTLIN)
 
-  private val changeReasons: MutableSet<NavInfoChangeReason> = EnumSet.noneOf(NavInfoChangeReason::class.java)
+  private val changeReasons: MutableSet<NavInfoChangeReason> =
+    EnumSet.noneOf(NavInfoChangeReason::class.java)
   private val fetcher = mock<NavInfoFetcherBase>()
   private lateinit var invalidate: (NavInfoChangeReason) -> Unit
   private lateinit var computeStatus: (NavInfo) -> Any
@@ -24,14 +26,15 @@
   @Before
   fun setUp() {
     whenever(fetcher.isEnabled).thenReturn(true)
-    cache = NavStatusCache(
-      onCacheInvalidate = { changeReasons.add(it) },
-      update = { computeStatus(it) },
-      navInfoFetcherFactory = factory@{
-        invalidate = it
-        return@factory fetcher
-      }
-    )
+    cache =
+      NavStatusCache(
+        onCacheInvalidate = { changeReasons.add(it) },
+        update = { computeStatus(it) },
+        navInfoFetcherFactory = factory@{
+            invalidate = it
+            return@factory fetcher
+          }
+      )
     setNavInfo(0L)
   }
 
@@ -103,15 +106,16 @@
 
   private fun setNavInfo(modificationCount: Long) {
     whenever(fetcher.modificationCount).thenReturn(modificationCount)
-    whenever(fetcher.getCurrentNavInfo()).thenReturn(
-      NavInfo(
-        facet = safeArgsRule.androidFacet,
-        packageName = "foo.bar",
-        entries = emptyList(),
-        navVersion = SafeArgsFeatureVersions.TO_SAVED_STATE_HANDLE,
-        modificationCount = modificationCount,
+    whenever(fetcher.getCurrentNavInfo())
+      .thenReturn(
+        NavInfo(
+          facet = safeArgsRule.androidFacet,
+          packageName = "foo.bar",
+          entries = emptyList(),
+          navVersion = SafeArgsFeatureVersions.TO_SAVED_STATE_HANDLE,
+          modificationCount = modificationCount,
+        )
       )
-    )
     assertThat(cache.modificationTracker.modificationCount).isEqualTo(modificationCount)
   }
 }
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/module/gradle/NavInfoFetcherTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/module/gradle/NavInfoFetcherTest.kt
index 1535112..1a0a026 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/module/gradle/NavInfoFetcherTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/module/gradle/NavInfoFetcherTest.kt
@@ -1,4 +1,5 @@
-// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the
+// Apache 2.0 license.
 package com.android.tools.idea.nav.safeargs.module.gradle
 
 import com.android.tools.idea.nav.safeargs.SafeArgsMode
@@ -19,12 +20,12 @@
 import com.intellij.openapi.project.DumbServiceImpl
 import com.intellij.testFramework.EdtRule
 import com.intellij.testFramework.RunsInEdt
+import java.util.EnumSet
 import kotlinx.coroutines.runBlocking
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.rules.RuleChain
-import java.util.EnumSet
 
 @RunsInEdt
 class NavInfoFetcherTest {
@@ -32,7 +33,8 @@
 
   @get:Rule val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
 
-  private val changeReasons: MutableSet<NavInfoChangeReason> = EnumSet.noneOf(NavInfoChangeReason::class.java)
+  private val changeReasons: MutableSet<NavInfoChangeReason> =
+    EnumSet.noneOf(NavInfoChangeReason::class.java)
   private var baselineModificationCount = 0L
   private lateinit var module: Module
   private lateinit var fetcher: NavInfoFetcher
@@ -44,9 +46,11 @@
     NavigationResourcesModificationListener.ensureSubscribed(projectRule.project)
 
     module = projectRule.getModule("app.main")
-    fetcher = NavInfoFetcher(projectRule.fixture.testRootDisposable, module, SafeArgsMode.KOTLIN) { changeReason ->
-      changeReasons.add(changeReason)
-    }
+    fetcher =
+      NavInfoFetcher(projectRule.fixture.testRootDisposable, module, SafeArgsMode.KOTLIN) {
+        changeReason ->
+        changeReasons.add(changeReason)
+      }
     baselineModificationCount = fetcher.modificationCount
     changeReasons.clear()
   }
@@ -75,12 +79,12 @@
 
       val destinations = potentialDestinations.mapNotNull { it.toDestination() }
       assertThat(destinations).hasSize(2)
-      val (firstDest, secondDest) = if (destinations[0].id == "FirstFragment") {
-        destinations
-      }
-      else {
-        destinations.reversed()
-      }
+      val (firstDest, secondDest) =
+        if (destinations[0].id == "FirstFragment") {
+          destinations
+        } else {
+          destinations.reversed()
+        }
 
       firstDest.apply {
         assertThat(id).isEqualTo("FirstFragment")
@@ -130,23 +134,18 @@
   @Test
   fun updatesOnNavFileChange() {
     WriteCommandAction.runWriteCommandAction(projectRule.project) {
-      module.fileUnderGradleRoot("src/main/res/navigation/nav_graph.xml")!!.replaceWithoutSaving(
-        "@+id/FirstFragment",
-        "@+id/FirstFragmentChanged",
-        module.project
-      )
+      module
+        .fileUnderGradleRoot("src/main/res/navigation/nav_graph.xml")!!
+        .replaceWithoutSaving("@+id/FirstFragment", "@+id/FirstFragmentChanged", module.project)
     }
 
     assertModified(NavInfoChangeReason.NAVIGATION_RESOURCE_CHANGED)
     assertThat(
-      fetcher
-        .getCurrentNavInfo()!!
-        .entries
-        .single()
-        .data
-        .resolvedDestinations
-        .singleOrNull { it.id == "FirstFragmentChanged" }
-    ).isNotNull()
+        fetcher.getCurrentNavInfo()!!.entries.single().data.resolvedDestinations.singleOrNull {
+          it.id == "FirstFragmentChanged"
+        }
+      )
+      .isNotNull()
   }
 
   @Test
@@ -166,7 +165,8 @@
 
   @Test
   fun updatesOnProjectSync() {
-    module.project.messageBus.syncPublisher(PROJECT_SYSTEM_SYNC_TOPIC)
+    module.project.messageBus
+      .syncPublisher(PROJECT_SYSTEM_SYNC_TOPIC)
       .syncEnded(ProjectSystemSyncManager.SyncResult.SUCCESS)
 
     assertModified(NavInfoChangeReason.GRADLE_SYNC)
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/project/NavigationResourcesModificationListenerTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/project/NavigationResourcesModificationListenerTest.kt
index 514ac0f..d80fdb9 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/project/NavigationResourcesModificationListenerTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/project/NavigationResourcesModificationListenerTest.kt
@@ -32,8 +32,7 @@
 import org.mockito.Mockito.verifyNoMoreInteractions
 
 class NavigationResourcesModificationListenerTest {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule()
+  @get:Rule val safeArgsRule = SafeArgsRule()
 
   private lateinit var myModuleNavResourcesTracker: ModuleNavigationResourcesModificationTracker
   private lateinit var myProjectNavResourcesTracker: ProjectNavigationResourceModificationTracker
@@ -45,14 +44,17 @@
 
   @Before
   fun setUp() {
-    // Ensure that the resource repository is initialized before we start testing, since NavigationResourcesModificationListener will only
-    // used an already-cached version of the repository and won't trigger creation if it doesn't already exist.
+    // Ensure that the resource repository is initialized before we start testing, since
+    // NavigationResourcesModificationListener will only
+    // used an already-cached version of the repository and won't trigger creation if it doesn't
+    // already exist.
     safeArgsRule.fixture.addFileToProject("res/values/strings.xml", "")
     safeArgsRule.waitForResourceRepositoryUpdates()
 
     project.messageBus.connect().subscribe(NAVIGATION_RESOURCES_CHANGED, listener)
     NavigationResourcesModificationListener.ensureSubscribed(project)
-    myModuleNavResourcesTracker = ModuleNavigationResourcesModificationTracker.getInstance(safeArgsRule.module)
+    myModuleNavResourcesTracker =
+      ModuleNavigationResourcesModificationTracker.getInstance(safeArgsRule.module)
     myProjectNavResourcesTracker = ProjectNavigationResourceModificationTracker.getInstance(project)
     assertThat(myModuleNavResourcesTracker.modificationCount).isEqualTo(0L)
     assertThat(myProjectNavResourcesTracker.modificationCount).isEqualTo(0L)
@@ -62,7 +64,7 @@
   fun addFilesToNavigationResourcesFolder() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -78,7 +80,9 @@
                 app:argType="string" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     safeArgsRule.waitForResourceRepositoryUpdates()
     // picked up 1 document change and 1 vfs change
@@ -86,7 +90,7 @@
 
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/other.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -102,7 +106,9 @@
                 app:argType="integer" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     safeArgsRule.waitForResourceRepositoryUpdates()
     // picked up 1 document change and 1 vfs change
@@ -111,10 +117,11 @@
 
   @Test
   fun deleteNavigationResourceFolder() {
-    val navFile = safeArgsRule.fixture.addFileToProject(
-      "res/navigation/main.xml",
-      //language=XML
-      """
+    val navFile =
+      safeArgsRule.fixture.addFileToProject(
+        "res/navigation/main.xml",
+        // language=XML
+        """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/main"
@@ -129,15 +136,15 @@
                 app:argType="string" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+          .trimIndent()
+      )
 
     safeArgsRule.waitForResourceRepositoryUpdates()
     // picked up 1 document change and 1 vfs change
     verifyModuleChangeEventsFired(2)
 
-    WriteCommandAction.runWriteCommandAction(project) {
-      navFile.virtualFile.parent.delete(this)
-    }
+    WriteCommandAction.runWriteCommandAction(project) { navFile.virtualFile.parent.delete(this) }
     safeArgsRule.waitForResourceRepositoryUpdates()
     // picked up 1 vfs change
     verifyModuleChangeEventsFired(1)
@@ -145,10 +152,11 @@
 
   @Test
   fun modifyNavResourceFile() {
-    val navFile = safeArgsRule.fixture.addFileToProject(
-      "res/navigation/main.xml",
-      //language=XML
-      """
+    val navFile =
+      safeArgsRule.fixture.addFileToProject(
+        "res/navigation/main.xml",
+        // language=XML
+        """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/main"
@@ -163,7 +171,9 @@
                 app:argType="string" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+          .trimIndent()
+      )
     safeArgsRule.waitForResourceRepositoryUpdates()
     // picked up 1 document change and 1 vfs change
     verifyModuleChangeEventsFired(2)
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/project/gradle/ProjectNavigationResourceModificationTrackerTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/project/gradle/ProjectNavigationResourceModificationTrackerTest.kt
index c8097c6..d3b6cd7 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/project/gradle/ProjectNavigationResourceModificationTrackerTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/project/gradle/ProjectNavigationResourceModificationTrackerTest.kt
@@ -38,17 +38,18 @@
 /**
  * Test that our project-wide modification tracker works across multiple modules.
  *
- * This needs to be a gradle test because that's the only way right now we can support multi-module configurations
+ * This needs to be a gradle test because that's the only way right now we can support multi-module
+ * configurations
  */
 @RunsInEdt
 class ProjectNavigationResourceModificationTrackerTest {
   private val projectRule = AndroidGradleProjectRule()
 
   // The tests need to run on the EDT thread but we must initialize the project rule off of it
-  @get:Rule
-  val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
+  @get:Rule val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
 
-  private val fixture get() = projectRule.fixture as JavaCodeInsightTestFixture
+  private val fixture
+    get() = projectRule.fixture as JavaCodeInsightTestFixture
 
   @Before
   fun setUp() {
@@ -58,38 +59,57 @@
   }
 
   /**
-   *  Project structure:
-   *  base app module --> lib1 dep module(safe arg mode is off) --> lib2 dep module(safe arg mode is on)
+   * Project structure: base app module --> lib1 dep module(safe arg mode is off) --> lib2 dep
+   * module(safe arg mode is on)
    */
   @Test
   fun multiModuleModificationTrackerTest() {
     projectRule.requestSyncAndWait()
-    val baseLineNumber = ProjectNavigationResourceModificationTracker.getInstance(fixture.project).modificationCount
+    val baseLineNumber =
+      ProjectNavigationResourceModificationTracker.getInstance(fixture.project).modificationCount
     val listener = mock<NavigationResourcesChangeListener>()
     projectRule.project.messageBus.connect().subscribe(NAVIGATION_RESOURCES_CHANGED, listener)
 
-    val navFileInBaseAppModule = projectRule.project.baseDir.findFileByRelativePath(
-      "app/src/main/res/navigation/nav_graph.xml")!!
+    val navFileInBaseAppModule =
+      projectRule.project.baseDir.findFileByRelativePath(
+        "app/src/main/res/navigation/nav_graph.xml"
+      )!!
     val appModule = navFileInBaseAppModule.getModule(projectRule.project)!!
 
-    val navFileInDepModule = projectRule.project.baseDir.findFileByRelativePath(
-      "mylibrary2/src/main/res/navigation/libnav_graph.xml")!!
+    val navFileInDepModule =
+      projectRule.project.baseDir.findFileByRelativePath(
+        "mylibrary2/src/main/res/navigation/libnav_graph.xml"
+      )!!
     val depModule = navFileInDepModule.getModule(projectRule.project)!!
 
     // modify a nav file in base-app module without saving
     WriteCommandAction.runWriteCommandAction(fixture.project) {
-      navFileInBaseAppModule.replaceWithoutSaving("FirstFragment", "FirstFragmentChanged", fixture.project)
+      navFileInBaseAppModule.replaceWithoutSaving(
+        "FirstFragment",
+        "FirstFragmentChanged",
+        fixture.project
+      )
     }
     // picked up 1 document change
-    assertThat(ProjectNavigationResourceModificationTracker.getInstance(fixture.project).modificationCount).isEqualTo(baseLineNumber + 1)
+    assertThat(
+        ProjectNavigationResourceModificationTracker.getInstance(fixture.project).modificationCount
+      )
+      .isEqualTo(baseLineNumber + 1)
     verify(listener).onNavigationResourcesChanged(appModule)
 
     // modify a nav file in dep module without saving
     WriteCommandAction.runWriteCommandAction(fixture.project) {
-      navFileInDepModule.replaceWithoutSaving("FirstFragment", "FirstFragmentChanged", fixture.project)
+      navFileInDepModule.replaceWithoutSaving(
+        "FirstFragment",
+        "FirstFragmentChanged",
+        fixture.project
+      )
     }
     // picked up 1 document change
-    assertThat(ProjectNavigationResourceModificationTracker.getInstance(fixture.project).modificationCount).isEqualTo(baseLineNumber + 2)
+    assertThat(
+        ProjectNavigationResourceModificationTracker.getInstance(fixture.project).modificationCount
+      )
+      .isEqualTo(baseLineNumber + 2)
     verify(listener).onNavigationResourcesChanged(depModule)
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightActionBuilderClassTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightActionBuilderClassTest.kt
index d1483b5..b7c2136 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightActionBuilderClassTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightActionBuilderClassTest.kt
@@ -28,14 +28,13 @@
 
 @RunsInEdt
 class LightActionBuilderClassTest {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule()
+  @get:Rule val safeArgsRule = SafeArgsRule()
 
   @Test
   fun canFindActionBuilderClasses() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -65,17 +64,29 @@
               app:destination="@id/main" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
 
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment1 {}")
 
-    Truth.assertThat(safeArgsRule.fixture.findClass("test.safeargs.Fragment2Directions.ActionFragment2ToMain", context)).isNull()
+    Truth.assertThat(
+        safeArgsRule.fixture.findClass(
+          "test.safeargs.Fragment2Directions.ActionFragment2ToMain",
+          context
+        )
+      )
+      .isNull()
 
     // Classes can be found with context
-    val actionBuilderClass = safeArgsRule.fixture.findClass("test.safeargs.Fragment1Directions.ActionFragment1ToFragment2", context)
+    val actionBuilderClass =
+      safeArgsRule.fixture.findClass(
+        "test.safeargs.Fragment1Directions.ActionFragment1ToFragment2",
+        context
+      )
     Truth.assertThat(actionBuilderClass).isInstanceOf(LightActionBuilderClass::class.java)
 
     // Check supers
@@ -91,15 +102,10 @@
       methods[0].checkSignaturesAndReturnType(
         name = "setArgOne",
         returnType = "ActionFragment1ToFragment2",
-        parameters = listOf(
-          Parameter("arg", "String")
-        )
+        parameters = listOf(Parameter("arg", "String"))
       )
 
-      methods[1].checkSignaturesAndReturnType(
-        name = "getArgOne",
-        returnType = "String"
-      )
+      methods[1].checkSignaturesAndReturnType(name = "getArgOne", returnType = "String")
     }
   }
 
@@ -107,7 +113,7 @@
   fun testOverriddenArguments() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -149,7 +155,9 @@
               app:destination="@id/main" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -157,10 +165,20 @@
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment1 {}")
 
     // All resolved arguments are with default values, so it falls back to NavDirections.
-    Truth.assertThat(safeArgsRule.fixture.findClass("test.safeargs.Fragment2Directions.ActionFragment2ToMain", context)).isNull()
+    Truth.assertThat(
+        safeArgsRule.fixture.findClass(
+          "test.safeargs.Fragment2Directions.ActionFragment2ToMain",
+          context
+        )
+      )
+      .isNull()
 
     // Classes can be found with context
-    val actionBuilderClass = safeArgsRule.fixture.findClass("test.safeargs.Fragment1Directions.ActionFragment1ToFragment2", context)
+    val actionBuilderClass =
+      safeArgsRule.fixture.findClass(
+        "test.safeargs.Fragment1Directions.ActionFragment1ToFragment2",
+        context
+      )
     Truth.assertThat(actionBuilderClass).isInstanceOf(LightActionBuilderClass::class.java)
 
     // Check supers
@@ -176,22 +194,15 @@
       methods[0].checkSignaturesAndReturnType(
         name = "setOverriddenArg",
         returnType = "ActionFragment1ToFragment2",
-        parameters = listOf(
-          Parameter("overriddenArg", "String")
-        )
+        parameters = listOf(Parameter("overriddenArg", "String"))
       )
 
-      methods[1].checkSignaturesAndReturnType(
-        name = "getOverriddenArg",
-        returnType = "String"
-      )
+      methods[1].checkSignaturesAndReturnType(name = "getOverriddenArg", returnType = "String")
 
       methods[2].checkSignaturesAndReturnType(
         name = "setOverriddenArgWithDefaultValue",
         returnType = "ActionFragment1ToFragment2",
-        parameters = listOf(
-          Parameter("overriddenArgWithDefaultValue", "int")
-        )
+        parameters = listOf(Parameter("overriddenArgWithDefaultValue", "int"))
       )
 
       methods[3].checkSignaturesAndReturnType(
@@ -202,15 +213,10 @@
       methods[4].checkSignaturesAndReturnType(
         name = "setArg",
         returnType = "ActionFragment1ToFragment2",
-        parameters = listOf(
-          Parameter("arg", "String")
-        )
+        parameters = listOf(Parameter("arg", "String"))
       )
 
-      methods[5].checkSignaturesAndReturnType(
-        name = "getArg",
-        returnType = "String"
-      )
+      methods[5].checkSignaturesAndReturnType(name = "getArg", returnType = "String")
     }
 
     // Check private constructor
@@ -219,11 +225,8 @@
       constructors[0].checkSignaturesAndReturnType(
         name = "ActionFragment1ToFragment2",
         returnType = PsiTypes.nullType().presentableText,
-        parameters = listOf(
-          Parameter("overriddenArg", "String"),
-          Parameter("arg", "String")
-        )
+        parameters = listOf(Parameter("overriddenArg", "String"), Parameter("arg", "String"))
       )
     }
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsAndBuilderClassInferredTypeTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsAndBuilderClassInferredTypeTest.kt
index 42314ab..c5e056b 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsAndBuilderClassInferredTypeTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsAndBuilderClassInferredTypeTest.kt
@@ -22,7 +22,6 @@
 import com.android.tools.idea.res.StudioResourceRepositoryManager
 import com.android.tools.idea.testing.findClass
 import com.google.common.truth.Truth.assertThat
-import com.intellij.psi.PsiType
 import com.intellij.psi.PsiTypes
 import com.intellij.testFramework.RunsInEdt
 import org.junit.Rule
@@ -31,39 +30,39 @@
 import org.junit.runners.Parameterized
 
 /**
- * Tests that would normally go in [LightArgsBuilderClassTest] and [LightArgsClass] but are related to
- * a bunch of arguments types that we want to test with parametrization.
+ * Tests that would normally go in [LightArgsBuilderClassTest] and [LightArgsClass] but are related
+ * to a bunch of arguments types that we want to test with parametrization.
  */
 @RunsInEdt
 @RunWith(Parameterized::class)
 class LightArgsAndBuilderClassInferredTypeTest(
   private val defaultValueTypeMapping: DefaultValueTypeMapping
 ) {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule()
+  @get:Rule val safeArgsRule = SafeArgsRule()
 
   companion object {
     @JvmStatic
     @Parameterized.Parameters(name = "{0}")
-    fun data() = listOf(
-      DefaultValueTypeMapping("1", PsiTypes.intType().name),
-      DefaultValueTypeMapping("0x21", PsiTypes.intType().name),
-      DefaultValueTypeMapping("1f", PsiTypes.floatType().name),
-      DefaultValueTypeMapping("1L", PsiTypes.longType().name),
-      DefaultValueTypeMapping("true", PsiTypes.booleanType().name),
-      DefaultValueTypeMapping("someString", "String"),
-      DefaultValueTypeMapping("@null", "String"),
-      DefaultValueTypeMapping("@resourceType/resourceName", PsiTypes.intType().name),
-      DefaultValueTypeMapping("someCustomType", "String"), // custom type can't be recognized
-      DefaultValueTypeMapping("someEnumType", "String") // custom type can't be recognized
-    )
+    fun data() =
+      listOf(
+        DefaultValueTypeMapping("1", PsiTypes.intType().name),
+        DefaultValueTypeMapping("0x21", PsiTypes.intType().name),
+        DefaultValueTypeMapping("1f", PsiTypes.floatType().name),
+        DefaultValueTypeMapping("1L", PsiTypes.longType().name),
+        DefaultValueTypeMapping("true", PsiTypes.booleanType().name),
+        DefaultValueTypeMapping("someString", "String"),
+        DefaultValueTypeMapping("@null", "String"),
+        DefaultValueTypeMapping("@resourceType/resourceName", PsiTypes.intType().name),
+        DefaultValueTypeMapping("someCustomType", "String"), // custom type can't be recognized
+        DefaultValueTypeMapping("someEnumType", "String") // custom type can't be recognized
+      )
   }
 
   @Test
   fun expectedBuilderConstructorsAndMethodsAreCreated_inferredType() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -79,7 +78,9 @@
                 android:defaultValue="${defaultValueTypeMapping.defaultValue}"/>
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -87,7 +88,9 @@
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment {}")
 
     // Classes can be found with context
-    val builderClass = safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs.Builder", context) as LightArgsBuilderClass
+    val builderClass =
+      safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs.Builder", context)
+        as LightArgsBuilderClass
 
     // We expect two constructors - a copy constructor (which is initialized with the parent args
     builderClass.constructors.let { constructors ->
@@ -95,9 +98,7 @@
       constructors[0].checkSignaturesAndReturnType(
         name = "Builder",
         returnType = PsiTypes.nullType().presentableText,
-        parameters = listOf(
-          Parameter("original", "FragmentArgs")
-        )
+        parameters = listOf(Parameter("original", "FragmentArgs"))
       )
 
       constructors[1].checkSignaturesAndReturnType(
@@ -114,9 +115,7 @@
       methods[0].checkSignaturesAndReturnType(
         name = "setArg1",
         returnType = "Builder",
-        parameters = listOf(
-          Parameter("arg1", defaultValueTypeMapping.inferredTypeStr)
-        )
+        parameters = listOf(Parameter("arg1", defaultValueTypeMapping.inferredTypeStr))
       )
 
       methods[1].checkSignaturesAndReturnType(
@@ -125,21 +124,19 @@
         isReturnTypeNullable = defaultValueTypeMapping.defaultValue == "@null"
       )
 
-      methods[2].checkSignaturesAndReturnType(
-        name = "build",
-        returnType = "FragmentArgs"
-      )
+      methods[2].checkSignaturesAndReturnType(name = "build", returnType = "FragmentArgs")
     }
   }
 
   @Test
   fun expectedMethodsAreCreated_inferredType_fromSavedStateHandle() {
-    // Use version [SafeArgsFeatureVersions.FROM_SAVED_STATE_HANDLE] and check the corresponding methods and field.
+    // Use version [SafeArgsFeatureVersions.FROM_SAVED_STATE_HANDLE] and check the corresponding
+    // methods and field.
     safeArgsRule.addFakeNavigationDependency(SafeArgsFeatureVersions.FROM_SAVED_STATE_HANDLE)
 
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -155,7 +152,9 @@
                 android:defaultValue="${defaultValueTypeMapping.defaultValue}" />
           </fragment>
         </navigation>
-        """.trimIndent())
+        """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -163,7 +162,8 @@
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment {}")
 
     // Classes can be found with context
-    val argClass = safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs", context) as LightArgsClass
+    val argClass =
+      safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs", context) as LightArgsClass
 
     argClass.methods.let { methods ->
       assertThat(methods.size).isEqualTo(4)
@@ -176,34 +176,28 @@
       methods[1].checkSignaturesAndReturnType(
         name = "fromBundle",
         returnType = "FragmentArgs",
-        parameters = listOf(
-          Parameter("bundle", "Bundle")
-        )
+        parameters = listOf(Parameter("bundle", "Bundle"))
       )
 
       methods[2].checkSignaturesAndReturnType(
         name = "fromSavedStateHandle",
         returnType = "FragmentArgs",
-        parameters = listOf(
-          Parameter("savedStateHandle", "SavedStateHandle")
-        )
+        parameters = listOf(Parameter("savedStateHandle", "SavedStateHandle"))
       )
 
-      methods[3].checkSignaturesAndReturnType(
-        name = "toBundle",
-        returnType = "Bundle"
-      )
+      methods[3].checkSignaturesAndReturnType(name = "toBundle", returnType = "Bundle")
     }
   }
 
   @Test
   fun expectedMethodsAreCreated_inferredType_toSavedStateHandle() {
-    // Use version [SafeArgsFeatureVersions.TO_SAVED_STATE_HANDLE] and check the corresponding methods and field.
+    // Use version [SafeArgsFeatureVersions.TO_SAVED_STATE_HANDLE] and check the corresponding
+    // methods and field.
     safeArgsRule.addFakeNavigationDependency(SafeArgsFeatureVersions.TO_SAVED_STATE_HANDLE)
 
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -219,7 +213,9 @@
                 android:defaultValue="${defaultValueTypeMapping.defaultValue}" />
           </fragment>
         </navigation>
-        """.trimIndent())
+        """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -227,7 +223,8 @@
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment {}")
 
     // Classes can be found with context
-    val argClass = safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs", context) as LightArgsClass
+    val argClass =
+      safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs", context) as LightArgsClass
 
     argClass.methods.let { methods ->
       assertThat(methods.size).isEqualTo(5)
@@ -240,17 +237,13 @@
       methods[1].checkSignaturesAndReturnType(
         name = "fromBundle",
         returnType = "FragmentArgs",
-        parameters = listOf(
-          Parameter("bundle", "Bundle")
-        )
+        parameters = listOf(Parameter("bundle", "Bundle"))
       )
 
       methods[2].checkSignaturesAndReturnType(
         name = "fromSavedStateHandle",
         returnType = "FragmentArgs",
-        parameters = listOf(
-          Parameter("savedStateHandle", "SavedStateHandle")
-        )
+        parameters = listOf(Parameter("savedStateHandle", "SavedStateHandle"))
       )
 
       methods[3].checkSignaturesAndReturnType(
@@ -258,12 +251,9 @@
         returnType = "SavedStateHandle"
       )
 
-      methods[4].checkSignaturesAndReturnType(
-        name = "toBundle",
-        returnType = "Bundle"
-      )
+      methods[4].checkSignaturesAndReturnType(name = "toBundle", returnType = "Bundle")
     }
   }
 }
 
-data class DefaultValueTypeMapping(val defaultValue: String, val inferredTypeStr: String)
\ No newline at end of file
+data class DefaultValueTypeMapping(val defaultValue: String, val inferredTypeStr: String)
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsAndBuilderClassNullabilityAnnotationTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsAndBuilderClassNullabilityAnnotationTest.kt
index ba25640..e258d5d 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsAndBuilderClassNullabilityAnnotationTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsAndBuilderClassNullabilityAnnotationTest.kt
@@ -29,36 +29,40 @@
 import org.junit.runners.Parameterized
 
 /**
- * Tests that would normally go in [LightArgsBuilderClassTest] and [LightArgsClass] but are related to
- * a bunch of arguments types that we want to test with parametrization.
+ * Tests that would normally go in [LightArgsBuilderClassTest] and [LightArgsClass] but are related
+ * to a bunch of arguments types that we want to test with parametrization.
  */
 @RunsInEdt
 @RunWith(Parameterized::class)
 class LightArgsAndBuilderClassNullabilityAnnotationTest(
   private val typeNullabilityMapping: TypeNullabilityMapping
 ) {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule()
+  @get:Rule val safeArgsRule = SafeArgsRule()
 
   companion object {
     @JvmStatic
     @Parameterized.Parameters(name = "{0}")
-    fun data() = listOf(
-      TypeNullabilityMapping("integer", PsiTypes.intType().name, false),
-      TypeNullabilityMapping(PsiTypes.floatType().name, false),
-      TypeNullabilityMapping(PsiTypes.longType().name, false),
-      TypeNullabilityMapping(PsiTypes.booleanType().name, false),
-      TypeNullabilityMapping("string", "String", true),
-      TypeNullabilityMapping("reference", PsiTypes.intType().name, false),
-      TypeNullabilityMapping("test.safeargs.MyCustomType", "MyCustomType", true) // e.g Parcelable, Serializable
-    )
+    fun data() =
+      listOf(
+        TypeNullabilityMapping("integer", PsiTypes.intType().name, false),
+        TypeNullabilityMapping(PsiTypes.floatType().name, false),
+        TypeNullabilityMapping(PsiTypes.longType().name, false),
+        TypeNullabilityMapping(PsiTypes.booleanType().name, false),
+        TypeNullabilityMapping("string", "String", true),
+        TypeNullabilityMapping("reference", PsiTypes.intType().name, false),
+        TypeNullabilityMapping(
+          "test.safeargs.MyCustomType",
+          "MyCustomType",
+          true
+        ) // e.g Parcelable, Serializable
+      )
   }
 
   @Test
   fun expectedBuilderConstructorsAndMethodsAreCreated_withNullabilityAnnotations() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -75,7 +79,9 @@
                 app:nullable="true"/>
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -83,7 +89,9 @@
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment {}")
 
     // Classes can be found with context
-    val builderClass = safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs.Builder", context) as LightArgsBuilderClass
+    val builderClass =
+      safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs.Builder", context)
+        as LightArgsBuilderClass
 
     // For the above xml, we expect a getter and setter for each <argument> tag as well as a final
     // `build()` method that generates its parent args class.
@@ -93,9 +101,7 @@
       methods[0].checkSignaturesAndReturnType(
         name = "setArg1",
         returnType = "Builder",
-        parameters = listOf(
-          Parameter("arg1", typeNullabilityMapping.after)
-        )
+        parameters = listOf(Parameter("arg1", typeNullabilityMapping.after))
       )
 
       methods[1].checkSignaturesAndReturnType(
@@ -104,10 +110,7 @@
         isReturnTypeNullable = typeNullabilityMapping.isReturnTypeNullable
       )
 
-      methods[2].checkSignaturesAndReturnType(
-        name = "build",
-        returnType = "FragmentArgs"
-      )
+      methods[2].checkSignaturesAndReturnType(name = "build", returnType = "FragmentArgs")
     }
   }
 
@@ -115,7 +118,7 @@
   fun expectedGettersAndFromBundleMethodsAreCreated_withNullabilityAnnotations() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -132,7 +135,9 @@
                 app:nullable="true"/>
           </fragment>
         </navigation>
-        """.trimIndent())
+        """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -140,7 +145,8 @@
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment {}")
 
     // Classes can be found with context
-    val argClass = safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs", context) as LightArgsClass
+    val argClass =
+      safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs", context) as LightArgsClass
 
     argClass.methods.let { methods ->
       assertThat(methods.size).isEqualTo(3)
@@ -153,19 +159,21 @@
       methods[1].checkSignaturesAndReturnType(
         name = "fromBundle",
         returnType = "FragmentArgs",
-        parameters = listOf(
-          Parameter("bundle", "Bundle")
-        )
+        parameters = listOf(Parameter("bundle", "Bundle"))
       )
 
-      methods[2].checkSignaturesAndReturnType(
-        name = "toBundle",
-        returnType = "Bundle"
-      )
+      methods[2].checkSignaturesAndReturnType(name = "toBundle", returnType = "Bundle")
     }
   }
 }
 
-data class TypeNullabilityMapping(val before: String, val after: String, val isReturnTypeNullable: Boolean) {
-  constructor(beforeAndAfter: String, nullability: Boolean) : this(beforeAndAfter, beforeAndAfter, nullability)
-}
\ No newline at end of file
+data class TypeNullabilityMapping(
+  val before: String,
+  val after: String,
+  val isReturnTypeNullable: Boolean
+) {
+  constructor(
+    beforeAndAfter: String,
+    nullability: Boolean
+  ) : this(beforeAndAfter, beforeAndAfter, nullability)
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsBuilderClassConstructorsAndMethodsTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsBuilderClassConstructorsAndMethodsTest.kt
index 44e9129..5597bac 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsBuilderClassConstructorsAndMethodsTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsBuilderClassConstructorsAndMethodsTest.kt
@@ -29,36 +29,36 @@
 import org.junit.runners.Parameterized
 
 /**
- * Tests that would normally go in [LightArgsBuilderClassTest] but are related to
- * a bunch of arguments types that we want to test with parametrization.
+ * Tests that would normally go in [LightArgsBuilderClassTest] but are related to a bunch of
+ * arguments types that we want to test with parametrization.
  */
 @RunsInEdt
 @RunWith(Parameterized::class)
 class LightArgsBuilderClassConstructorsAndMethodsTest(private val typeMapping: TypeMapping) {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule()
+  @get:Rule val safeArgsRule = SafeArgsRule()
 
   companion object {
     @JvmStatic
     @Parameterized.Parameters(name = "{0}")
-    fun data() = listOf(
-      TypeMapping("integer", PsiTypes.intType().name),
-      TypeMapping(PsiTypes.floatType().name),
-      TypeMapping(PsiTypes.longType().name),
-      TypeMapping(PsiTypes.booleanType().name),
-      TypeMapping("string", "String"),
-      TypeMapping("reference", PsiTypes.intType().name),
-      TypeMapping("test.safeargs.MyCustomType", "MyCustomType"), // e.g Parcelable, Serializable
-      TypeMapping("test.safeargs.MyEnum", "MyEnum"),
-      TypeMapping("test.safeargs.Outer\$Inner", "Inner"),
-    )
+    fun data() =
+      listOf(
+        TypeMapping("integer", PsiTypes.intType().name),
+        TypeMapping(PsiTypes.floatType().name),
+        TypeMapping(PsiTypes.longType().name),
+        TypeMapping(PsiTypes.booleanType().name),
+        TypeMapping("string", "String"),
+        TypeMapping("reference", PsiTypes.intType().name),
+        TypeMapping("test.safeargs.MyCustomType", "MyCustomType"), // e.g Parcelable, Serializable
+        TypeMapping("test.safeargs.MyEnum", "MyEnum"),
+        TypeMapping("test.safeargs.Outer\$Inner", "Inner"),
+      )
   }
 
   @Test
   fun expectedBuilderConstructorsAndMethodsAreCreated() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -86,7 +86,9 @@
                 android:defaultValue="@null"/>
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -94,7 +96,9 @@
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment {}")
 
     // Classes can be found with context
-    val builderClass = safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs.Builder", context) as LightArgsBuilderClass
+    val builderClass =
+      safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs.Builder", context)
+        as LightArgsBuilderClass
 
     // We expect two constructors - a copy constructor (which is initialized with the parent args
     builderClass.constructors.let { constructors ->
@@ -102,18 +106,17 @@
       constructors[0].checkSignaturesAndReturnType(
         name = "Builder",
         returnType = PsiTypes.nullType().presentableText,
-        parameters = listOf(
-          Parameter("original", "FragmentArgs")
-        )
+        parameters = listOf(Parameter("original", "FragmentArgs"))
       )
 
       constructors[1].checkSignaturesAndReturnType(
         name = "Builder",
         returnType = PsiTypes.nullType().presentableText,
-        parameters = listOf(
-          Parameter("argOne", typeMapping.after),
-          Parameter("argThree", "${typeMapping.after}[]")
-        )
+        parameters =
+          listOf(
+            Parameter("argOne", typeMapping.after),
+            Parameter("argThree", "${typeMapping.after}[]")
+          )
       )
     }
 
@@ -125,35 +128,23 @@
       methods[0].checkSignaturesAndReturnType(
         name = "setArgOne",
         returnType = "Builder",
-        parameters = listOf(
-          Parameter("argOne", typeMapping.after)
-        )
+        parameters = listOf(Parameter("argOne", typeMapping.after))
       )
 
-      methods[1].checkSignaturesAndReturnType(
-        name = "getArgOne",
-        returnType = typeMapping.after
-      )
+      methods[1].checkSignaturesAndReturnType(name = "getArgOne", returnType = typeMapping.after)
 
       methods[2].checkSignaturesAndReturnType(
         name = "setArgTwo",
         returnType = "Builder",
-        parameters = listOf(
-          Parameter("argTwo", typeMapping.after)
-        )
+        parameters = listOf(Parameter("argTwo", typeMapping.after))
       )
 
-      methods[3].checkSignaturesAndReturnType(
-        name = "getArgTwo",
-        returnType = typeMapping.after
-      )
+      methods[3].checkSignaturesAndReturnType(name = "getArgTwo", returnType = typeMapping.after)
 
       methods[4].checkSignaturesAndReturnType(
         name = "setArgThree",
         returnType = "Builder",
-        parameters = listOf(
-          Parameter("argThree", "${typeMapping.after}[]")
-        )
+        parameters = listOf(Parameter("argThree", "${typeMapping.after}[]"))
       )
 
       methods[5].checkSignaturesAndReturnType(
@@ -164,9 +155,7 @@
       methods[6].checkSignaturesAndReturnType(
         name = "setArgFour",
         returnType = "Builder",
-        parameters = listOf(
-          Parameter("argFour", "${typeMapping.after}[]")
-        )
+        parameters = listOf(Parameter("argFour", "${typeMapping.after}[]"))
       )
 
       methods[7].checkSignaturesAndReturnType(
@@ -175,10 +164,7 @@
         returnType = "${typeMapping.after}[]"
       )
 
-      methods[8].checkSignaturesAndReturnType(
-        name = "build",
-        returnType = "FragmentArgs"
-      )
+      methods[8].checkSignaturesAndReturnType(name = "build", returnType = "FragmentArgs")
     }
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsBuilderClassTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsBuilderClassTest.kt
index 880d054..b50c05e 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsBuilderClassTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsBuilderClassTest.kt
@@ -25,14 +25,13 @@
 
 @RunsInEdt
 class LightArgsBuilderClassTest {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule()
+  @get:Rule val safeArgsRule = SafeArgsRule()
 
   @Test
   fun canFindArgsBuilderClasses() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -56,7 +55,9 @@
                 app:argType="string" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -64,9 +65,9 @@
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment1 {}")
 
     // Classes can be found with context
-    assertThat(safeArgsRule.fixture.findClass("test.safeargs.Fragment1Args.Builder", context)).isInstanceOf(
-      LightArgsBuilderClass::class.java)
-    assertThat(safeArgsRule.fixture.findClass("test.safeargs.Fragment2Args.Builder", context)).isInstanceOf(
-      LightArgsBuilderClass::class.java)
+    assertThat(safeArgsRule.fixture.findClass("test.safeargs.Fragment1Args.Builder", context))
+      .isInstanceOf(LightArgsBuilderClass::class.java)
+    assertThat(safeArgsRule.fixture.findClass("test.safeargs.Fragment2Args.Builder", context))
+      .isInstanceOf(LightArgsBuilderClass::class.java)
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsClassArgMethodsTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsClassArgMethodsTest.kt
index cae7f7d..af00ec5 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsClassArgMethodsTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsClassArgMethodsTest.kt
@@ -30,35 +30,35 @@
 import org.junit.runners.Parameterized
 
 /**
- * Tests that would normally go in [LightArgsClassTest] but are related to
- * a bunch of arguments types that we want to test with parametrization.
+ * Tests that would normally go in [LightArgsClassTest] but are related to a bunch of arguments
+ * types that we want to test with parametrization.
  */
 @RunsInEdt
 @RunWith(Parameterized::class)
 class LightArgsClassArgMethodsTest(private val typeMapping: TypeMapping) {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule()
+  @get:Rule val safeArgsRule = SafeArgsRule()
 
   companion object {
     @JvmStatic
     @Parameterized.Parameters(name = "{0}")
-    fun data() = listOf(
-      TypeMapping("integer", PsiTypes.intType().name),
-      TypeMapping(PsiTypes.floatType().name),
-      TypeMapping(PsiTypes.longType().name),
-      TypeMapping(PsiTypes.booleanType().name),
-      TypeMapping("string", "String"),
-      TypeMapping("reference", PsiTypes.intType().name),
-      TypeMapping("test.safeargs.MyCustomType", "MyCustomType"), // e.g Parcelable, Serializable
-      TypeMapping("test.safeargs.MyEnum", "MyEnum")
-    )
+    fun data() =
+      listOf(
+        TypeMapping("integer", PsiTypes.intType().name),
+        TypeMapping(PsiTypes.floatType().name),
+        TypeMapping(PsiTypes.longType().name),
+        TypeMapping(PsiTypes.booleanType().name),
+        TypeMapping("string", "String"),
+        TypeMapping("reference", PsiTypes.intType().name),
+        TypeMapping("test.safeargs.MyCustomType", "MyCustomType"), // e.g Parcelable, Serializable
+        TypeMapping("test.safeargs.MyEnum", "MyEnum")
+      )
   }
 
   @Test
   fun expectedMethodsAreCreated() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -77,7 +77,9 @@
                 app:argType="${typeMapping.before}[]" />
           </fragment>
         </navigation>
-        """.trimIndent())
+        """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -85,7 +87,8 @@
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment {}")
 
     // Classes can be found with context
-    val argClass = safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs", context) as LightArgsClass
+    val argClass =
+      safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs", context) as LightArgsClass
 
     // Check supers
     argClass.supers.asList().let {
@@ -96,10 +99,7 @@
     // Check methods
     argClass.methods.let { methods ->
       assertThat(methods.size).isEqualTo(4)
-      methods[0].checkSignaturesAndReturnType(
-        name = "getArgOne",
-        returnType = typeMapping.after
-      )
+      methods[0].checkSignaturesAndReturnType(name = "getArgOne", returnType = typeMapping.after)
 
       methods[1].checkSignaturesAndReturnType(
         name = "getArgTwo",
@@ -109,15 +109,10 @@
       methods[2].checkSignaturesAndReturnType(
         name = "fromBundle",
         returnType = "FragmentArgs",
-        parameters = listOf(
-          Parameter("bundle", "Bundle")
-        )
+        parameters = listOf(Parameter("bundle", "Bundle"))
       )
 
-      methods[3].checkSignaturesAndReturnType(
-        name = "toBundle",
-        returnType = "Bundle"
-      )
+      methods[3].checkSignaturesAndReturnType(name = "toBundle", returnType = "Bundle")
     }
   }
 
@@ -127,7 +122,7 @@
 
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -146,7 +141,9 @@
                 app:argType="${typeMapping.before}[]" />
           </fragment>
         </navigation>
-        """.trimIndent())
+        """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -154,7 +151,8 @@
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment {}")
 
     // Classes can be found with context
-    val argClass = safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs", context) as LightArgsClass
+    val argClass =
+      safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs", context) as LightArgsClass
 
     // Check supers
     argClass.supers.asList().let {
@@ -165,10 +163,7 @@
     // Check methods
     argClass.methods.let { methods ->
       assertThat(methods.size).isEqualTo(5)
-      methods[0].checkSignaturesAndReturnType(
-        name = "getArgOne",
-        returnType = typeMapping.after
-      )
+      methods[0].checkSignaturesAndReturnType(name = "getArgOne", returnType = typeMapping.after)
 
       methods[1].checkSignaturesAndReturnType(
         name = "getArgTwo",
@@ -178,23 +173,16 @@
       methods[2].checkSignaturesAndReturnType(
         name = "fromBundle",
         returnType = "FragmentArgs",
-        parameters = listOf(
-          Parameter("bundle", "Bundle")
-        )
+        parameters = listOf(Parameter("bundle", "Bundle"))
       )
 
       methods[3].checkSignaturesAndReturnType(
         name = "fromSavedStateHandle",
         returnType = "FragmentArgs",
-        parameters = listOf(
-          Parameter("savedStateHandle", "SavedStateHandle")
-        )
+        parameters = listOf(Parameter("savedStateHandle", "SavedStateHandle"))
       )
 
-      methods[4].checkSignaturesAndReturnType(
-        name = "toBundle",
-        returnType = "Bundle"
-      )
+      methods[4].checkSignaturesAndReturnType(name = "toBundle", returnType = "Bundle")
     }
   }
 
@@ -204,7 +192,7 @@
 
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -223,7 +211,9 @@
                 app:argType="${typeMapping.before}[]" />
           </fragment>
         </navigation>
-        """.trimIndent())
+        """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -231,7 +221,8 @@
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment {}")
 
     // Classes can be found with context
-    val argClass = safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs", context) as LightArgsClass
+    val argClass =
+      safeArgsRule.fixture.findClass("test.safeargs.FragmentArgs", context) as LightArgsClass
 
     // Check supers
     argClass.supers.asList().let {
@@ -242,10 +233,7 @@
     // Check methods
     argClass.methods.let { methods ->
       assertThat(methods.size).isEqualTo(6)
-      methods[0].checkSignaturesAndReturnType(
-        name = "getArgOne",
-        returnType = typeMapping.after
-      )
+      methods[0].checkSignaturesAndReturnType(name = "getArgOne", returnType = typeMapping.after)
 
       methods[1].checkSignaturesAndReturnType(
         name = "getArgTwo",
@@ -255,17 +243,13 @@
       methods[2].checkSignaturesAndReturnType(
         name = "fromBundle",
         returnType = "FragmentArgs",
-        parameters = listOf(
-          Parameter("bundle", "Bundle")
-        )
+        parameters = listOf(Parameter("bundle", "Bundle"))
       )
 
       methods[3].checkSignaturesAndReturnType(
         name = "fromSavedStateHandle",
         returnType = "FragmentArgs",
-        parameters = listOf(
-          Parameter("savedStateHandle", "SavedStateHandle")
-        )
+        parameters = listOf(Parameter("savedStateHandle", "SavedStateHandle"))
       )
 
       methods[4].checkSignaturesAndReturnType(
@@ -273,10 +257,7 @@
         returnType = "SavedStateHandle"
       )
 
-      methods[5].checkSignaturesAndReturnType(
-        name = "toBundle",
-        returnType = "Bundle"
-      )
+      methods[5].checkSignaturesAndReturnType(name = "toBundle", returnType = "Bundle")
     }
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsClassTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsClassTest.kt
index 2924eee..1b486ad 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsClassTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightArgsClassTest.kt
@@ -25,14 +25,13 @@
 
 @RunsInEdt
 class LightArgsClassTest {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule()
+  @get:Rule val safeArgsRule = SafeArgsRule()
 
   @Test
   fun canFindArgsClasses() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -57,7 +56,9 @@
               android:name="test.safeargs.Fragment2"
               android:label="Fragment2" />
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -65,10 +66,12 @@
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment1 {}")
 
     // Classes can be found with context
-    assertThat(safeArgsRule.fixture.findClass("test.safeargs.MainArgs", context)).isInstanceOf(LightArgsClass::class.java)
-    assertThat(safeArgsRule.fixture.findClass("test.safeargs.Fragment1Args", context)).isInstanceOf(LightArgsClass::class.java)
+    assertThat(safeArgsRule.fixture.findClass("test.safeargs.MainArgs", context))
+      .isInstanceOf(LightArgsClass::class.java)
+    assertThat(safeArgsRule.fixture.findClass("test.safeargs.Fragment1Args", context))
+      .isInstanceOf(LightArgsClass::class.java)
 
     // ... but not generated if no arguments
     assertThat(safeArgsRule.fixture.findClass("test.safeargs.Fragment2Args", context)).isNull()
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightDirectionsClassTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightDirectionsClassTest.kt
index c0bc66c..a39b36f 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightDirectionsClassTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/LightDirectionsClassTest.kt
@@ -29,14 +29,13 @@
 
 @RunsInEdt
 class LightDirectionsClassTest {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule()
+  @get:Rule val safeArgsRule = SafeArgsRule()
 
   @Test
   fun canFindDirectionsClasses() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -69,7 +68,9 @@
           <!-- Sample action -->
           <action android:id="@+id/action_without_destination" />
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -77,16 +78,19 @@
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment1 {}")
 
     // Classes can be found with context
-    assertThat(safeArgsRule.fixture.findClass("test.safeargs.Fragment1Directions", context)).isInstanceOf(LightDirectionsClass::class.java)
-    assertThat(safeArgsRule.fixture.findClass("test.safeargs.Fragment2Directions", context)).isInstanceOf(LightDirectionsClass::class.java)
-    assertThat(safeArgsRule.fixture.findClass("test.safeargs.MainDirections", context)).isInstanceOf(LightDirectionsClass::class.java)
+    assertThat(safeArgsRule.fixture.findClass("test.safeargs.Fragment1Directions", context))
+      .isInstanceOf(LightDirectionsClass::class.java)
+    assertThat(safeArgsRule.fixture.findClass("test.safeargs.Fragment2Directions", context))
+      .isInstanceOf(LightDirectionsClass::class.java)
+    assertThat(safeArgsRule.fixture.findClass("test.safeargs.MainDirections", context))
+      .isInstanceOf(LightDirectionsClass::class.java)
   }
 
   @Test
   fun actionMethodsGeneratedWithArgs() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -136,15 +140,21 @@
 
           </navigation>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
 
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment1 {}")
 
-    val mainDirections = safeArgsRule.fixture.findClass("test.safeargs.MainDirections", context) as LightDirectionsClass
-    val fragment1directions = safeArgsRule.fixture.findClass("test.safeargs.Fragment1Directions", context) as LightDirectionsClass
+    val mainDirections =
+      safeArgsRule.fixture.findClass("test.safeargs.MainDirections", context)
+        as LightDirectionsClass
+    val fragment1directions =
+      safeArgsRule.fixture.findClass("test.safeargs.Fragment1Directions", context)
+        as LightDirectionsClass
 
     mainDirections.findMethodsByName("actionToNested").first().let { action ->
       (action as PsiMethod).checkSignaturesAndReturnType(
@@ -157,19 +167,15 @@
       (action as PsiMethod).checkSignaturesAndReturnType(
         name = "actionFragment1ToFragment2",
         returnType = "ActionFragment1ToFragment2",
-        parameters = listOf(
-          Parameter("argOne", "String"),
-          Parameter("argTwo", PsiTypes.floatType().name)
-        )
+        parameters =
+          listOf(Parameter("argOne", "String"), Parameter("argTwo", PsiTypes.floatType().name))
       )
     }
     fragment1directions.findMethodsByName("actionFragment1ToFragment3").first().let { action ->
       (action as PsiMethod).checkSignaturesAndReturnType(
         name = "actionFragment1ToFragment3",
         returnType = "ActionFragment1ToFragment3",
-        parameters = listOf(
-          Parameter("arg", PsiTypes.intType().name)
-        )
+        parameters = listOf(Parameter("arg", PsiTypes.intType().name))
       )
     }
   }
@@ -178,7 +184,7 @@
   fun testIncludedNavigationCase() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -195,7 +201,9 @@
                   app:destination="@id/included_graph" />                  
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -203,7 +211,9 @@
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment1 {}")
 
     // Class can be found with context
-    val fragment2Directions = safeArgsRule.fixture.findClass("test.safeargs.Fragment2Directions", context) as LightDirectionsClass
+    val fragment2Directions =
+      safeArgsRule.fixture.findClass("test.safeargs.Fragment2Directions", context)
+        as LightDirectionsClass
 
     // Check method
     fragment2Directions.findMethodsByName("actionFragment2ToIncludedGraph").first().let { action ->
@@ -218,7 +228,7 @@
   fun testGlobalActionCase() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -254,7 +264,9 @@
                 
           </navigation>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -262,7 +274,9 @@
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment1 {}")
 
     // Class can be found with context
-    val fragment2Directions = safeArgsRule.fixture.findClass("test.safeargs.Fragment2Directions", context) as LightDirectionsClass
+    val fragment2Directions =
+      safeArgsRule.fixture.findClass("test.safeargs.Fragment2Directions", context)
+        as LightDirectionsClass
     // Check methods of Fragment2Directions
     fragment2Directions.methods.let { methods ->
       assertThat(methods.size).isEqualTo(3)
@@ -282,8 +296,9 @@
       )
     }
 
-    val innerNavigationDirections = safeArgsRule.fixture.findClass("test.safeargs.InnerNavigationDirections",
-                                                                   context) as LightDirectionsClass
+    val innerNavigationDirections =
+      safeArgsRule.fixture.findClass("test.safeargs.InnerNavigationDirections", context)
+        as LightDirectionsClass
     // Check methods of InnerNavigationDirections
     innerNavigationDirections.methods.let { methods ->
       assertThat(methods.size).isEqualTo(2)
@@ -298,7 +313,9 @@
       )
     }
 
-    val mainDirections = safeArgsRule.fixture.findClass("test.safeargs.MainDirections", context) as LightDirectionsClass
+    val mainDirections =
+      safeArgsRule.fixture.findClass("test.safeargs.MainDirections", context)
+        as LightDirectionsClass
     // Check methods of InnerNavigationDirections
     mainDirections.methods.let { methods ->
       assertThat(methods.size).isEqualTo(1)
@@ -313,7 +330,7 @@
   fun testNoDestinationDefined() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -342,7 +359,9 @@
                   app:popUpTo="@id/fragment1" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -350,21 +369,24 @@
     val context = safeArgsRule.fixture.addClass("package test.safeargs; public class Fragment1 {}")
 
     // Classes can be found with context
-    val fragment1DirectionsClass = safeArgsRule.fixture.findClass("test.safeargs.Fragment1Directions", context) as LightDirectionsClass
-    val fragment2DirectionsClass = safeArgsRule.fixture.findClass("test.safeargs.Fragment2Directions", context) as LightDirectionsClass
+    val fragment1DirectionsClass =
+      safeArgsRule.fixture.findClass("test.safeargs.Fragment1Directions", context)
+        as LightDirectionsClass
+    val fragment2DirectionsClass =
+      safeArgsRule.fixture.findClass("test.safeargs.Fragment2Directions", context)
+        as LightDirectionsClass
 
-    // Because we don't have destination defined, no arguments are supposed to be passed. This means no inner builder
-    // action classes are created. NavDirections class(`ActionOnlyNavDirections` as the implementation under the hood)
+    // Because we don't have destination defined, no arguments are supposed to be passed. This means
+    // no inner builder
+    // action classes are created. NavDirections class(`ActionOnlyNavDirections` as the
+    // implementation under the hood)
     // is being used here.
     assertThat(fragment1DirectionsClass.innerClasses).isEmpty()
     assertThat(fragment2DirectionsClass.innerClasses).isEmpty()
 
     fragment1DirectionsClass.methods.let { methods ->
       assertThat(methods.size).isEqualTo(1)
-      methods[0].checkSignaturesAndReturnType(
-        name = "actionToMain",
-        returnType = "NavDirections"
-      )
+      methods[0].checkSignaturesAndReturnType(name = "actionToMain", returnType = "NavDirections")
     }
 
     fragment2DirectionsClass.methods.let { methods ->
@@ -375,4 +397,4 @@
       )
     }
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/SafeArgNavigationTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/SafeArgNavigationTest.kt
index d144723..319e2ba 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/SafeArgNavigationTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/SafeArgNavigationTest.kt
@@ -27,14 +27,13 @@
 
 @RunsInEdt
 class SafeArgNavigationTest {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule()
+  @get:Rule val safeArgsRule = SafeArgsRule()
 
   @Test
   fun canNavigateToXmlTagFromArgClass() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -58,7 +57,9 @@
                 app:argType="string" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -69,7 +70,8 @@
     assertThat(editors.selectedFiles).isEmpty()
 
     // check Fragment1Args class navigation
-    val arg1Class = safeArgsRule.fixture.findClass("test.safeargs.Fragment1Args", context) as LightArgsClass
+    val arg1Class =
+      safeArgsRule.fixture.findClass("test.safeargs.Fragment1Args", context) as LightArgsClass
     arg1Class.let {
       it.navigate(true)
       assertThat(editors.selectedFiles[0].name).isEqualTo("main.xml")
@@ -78,7 +80,8 @@
     }
 
     // check Fragment2Args class navigation
-    val arg2Class = safeArgsRule.fixture.findClass("test.safeargs.Fragment2Args", context) as LightArgsClass
+    val arg2Class =
+      safeArgsRule.fixture.findClass("test.safeargs.Fragment2Args", context) as LightArgsClass
     arg2Class.let {
       it.navigate(true)
       assertThat(editors.selectedFiles[0].name).isEqualTo("main.xml")
@@ -94,14 +97,16 @@
 
       // check getter method
       if (it.name == "getArgOne") {
-        assertThat(it.navigationElement.text).isEqualTo(
-          """
+        assertThat(it.navigationElement.text)
+          .isEqualTo(
+            """
           <argument
                   android:name="arg_one"
                   app:argType="string" />
-          """.trimIndent())
-      }
-      else {
+          """
+              .trimIndent()
+          )
+      } else {
         assertThat(it.navigationElement.text).contains("id=\"@+id/fragment1\"")
       }
     }
@@ -114,14 +119,16 @@
 
       // check getter method
       if (it.name == "getArgTwo") {
-        assertThat(it.navigationElement.text).isEqualTo(
-          """
+        assertThat(it.navigationElement.text)
+          .isEqualTo(
+            """
           <argument
                   android:name="arg_two"
                   app:argType="string" />
-          """.trimIndent())
-      }
-      else {
+          """
+              .trimIndent()
+          )
+      } else {
         assertThat(it.navigationElement.text).contains("id=\"@+id/fragment2\"")
       }
     }
@@ -131,7 +138,7 @@
   fun canNavigateToXmlTagFromInnerArgsBuilderClass() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -151,7 +158,9 @@
               android:name="test.safeargs.Fragment2"
               android:label="Fragment2" />
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -162,7 +171,9 @@
     assertThat(editors.selectedFiles).isEmpty()
 
     // check class navigation
-    val innerBuilderClass = safeArgsRule.fixture.findClass("test.safeargs.Fragment1Args.Builder", context) as LightArgsBuilderClass
+    val innerBuilderClass =
+      safeArgsRule.fixture.findClass("test.safeargs.Fragment1Args.Builder", context)
+        as LightArgsBuilderClass
     innerBuilderClass.navigate(true)
     assertThat(editors.selectedFiles[0].name).isEqualTo("main.xml")
     assertThat(innerBuilderClass.navigationElement).isInstanceOf(XmlTag::class.java)
@@ -184,14 +195,16 @@
 
       // check getter and setter method
       if (it.name == "getArgOne" || it.name == "setArgOne") {
-        assertThat(it.navigationElement.text).isEqualTo(
-          """
+        assertThat(it.navigationElement.text)
+          .isEqualTo(
+            """
           <argument
                   android:name="arg_one"
                   app:argType="string" />
-          """.trimIndent())
-      }
-      else {
+          """
+              .trimIndent()
+          )
+      } else {
         assertThat(it.navigationElement.text).contains("id=\"@+id/fragment1\"")
       }
     }
@@ -201,7 +214,7 @@
   fun canNavigateToXmlTagFromDirectionClass() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -242,7 +255,9 @@
 
           </navigation>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -253,7 +268,9 @@
     assertThat(editors.selectedFiles).isEmpty()
 
     // check mainDirections class navigation
-    val mainDirections = safeArgsRule.fixture.findClass("test.safeargs.MainDirections", context) as LightDirectionsClass
+    val mainDirections =
+      safeArgsRule.fixture.findClass("test.safeargs.MainDirections", context)
+        as LightDirectionsClass
     mainDirections.let {
       it.navigate(true)
       assertThat(editors.selectedFiles[0].name).isEqualTo("main.xml")
@@ -262,7 +279,9 @@
     }
 
     // check fragment1directions class navigation
-    val fragment1directions = safeArgsRule.fixture.findClass("test.safeargs.Fragment1Directions", context) as LightDirectionsClass
+    val fragment1directions =
+      safeArgsRule.fixture.findClass("test.safeargs.Fragment1Directions", context)
+        as LightDirectionsClass
     fragment1directions.let {
       it.navigate(true)
       assertThat(editors.selectedFiles[0].name).isEqualTo("main.xml")
@@ -275,12 +294,15 @@
       it.navigate(true)
       assertThat(editors.selectedFiles[0].name).isEqualTo("main.xml")
       assertThat(it.navigationElement).isInstanceOf(XmlTag::class.java)
-      assertThat(it.navigationElement.text).isEqualTo(
-        """
+      assertThat(it.navigationElement.text)
+        .isEqualTo(
+          """
         <action
             android:id="@+id/action_to_nested"
             app:destination="@id/nested" />
-        """.trimIndent())
+        """
+            .trimIndent()
+        )
     }
 
     // check methods navigation of fragment1directions
@@ -290,20 +312,26 @@
       assertThat(it.navigationElement).isInstanceOf(XmlTag::class.java)
       when (it.name) {
         "actionFragment1ToFragment2" -> {
-          assertThat(it.navigationElement.text).isEqualTo(
-            """
+          assertThat(it.navigationElement.text)
+            .isEqualTo(
+              """
             <action
                   android:id="@+id/action_fragment1_to_fragment2"
                   app:destination="@id/fragment2" />
-            """.trimIndent())
+            """
+                .trimIndent()
+            )
         }
         "actionFragment1ToFragment3" -> {
-          assertThat(it.navigationElement.text).isEqualTo(
-            """
+          assertThat(it.navigationElement.text)
+            .isEqualTo(
+              """
             <action
                   android:id="@+id/action_fragment1_to_fragment3"
                   app:destination="@id/fragment3" />
-            """.trimIndent())
+            """
+                .trimIndent()
+            )
         }
       }
     }
@@ -313,7 +341,7 @@
   fun canNavigateToXmlTagFromInnerActionsBuilderClass() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -349,7 +377,9 @@
                 app:argType="string" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
@@ -360,14 +390,18 @@
     assertThat(editors.selectedFiles).isEmpty()
 
     // check actionBuilderClass navigation
-    val actionBuilderClass = safeArgsRule.fixture
-      .findClass("test.safeargs.Fragment1Directions.ActionFragment1ToFragment2", context) as LightActionBuilderClass
+    val actionBuilderClass =
+      safeArgsRule.fixture.findClass(
+        "test.safeargs.Fragment1Directions.ActionFragment1ToFragment2",
+        context
+      ) as LightActionBuilderClass
     actionBuilderClass.let {
       it.navigate(true)
       assertThat(editors.selectedFiles[0].name).isEqualTo("main.xml")
       assertThat(it.navigationElement).isInstanceOf(XmlTag::class.java)
-      assertThat(it.navigationElement.text).isEqualTo(
-        """
+      assertThat(it.navigationElement.text)
+        .isEqualTo(
+          """
           <action
                   android:id="@+id/action_fragment1_to_fragment2"
                   app:destination="@id/fragment2" >
@@ -379,7 +413,9 @@
                     android:name="arg_in_action"
                     app:argType="string" />
               </action>
-        """.trimIndent())
+        """
+            .trimIndent()
+        )
     }
 
     // check methods navigation of actionBuilderClass
@@ -390,33 +426,45 @@
 
       // check getters and setters
       when (it.name) {
-        "getArg", "setArg" -> {
-          assertThat(it.navigationElement.text).isEqualTo(
-            """
+        "getArg",
+        "setArg" -> {
+          assertThat(it.navigationElement.text)
+            .isEqualTo(
+              """
               <argument
                         android:name="arg"
                         app:argType="string"
                         android:defaultValue="defaultString" />
-            """.trimIndent())
-        }
-        "getArgInAction", "setArgInAction" -> {
-          assertThat(it.navigationElement.text).isEqualTo(
             """
+                .trimIndent()
+            )
+        }
+        "getArgInAction",
+        "setArgInAction" -> {
+          assertThat(it.navigationElement.text)
+            .isEqualTo(
+              """
               <argument
                         android:name="arg_in_action"
                         app:argType="string" />
-            """.trimIndent())
-        }
-        "getArgInDestination", "setArgInDestination" -> {
-          assertThat(it.navigationElement.text).isEqualTo(
             """
+                .trimIndent()
+            )
+        }
+        "getArgInDestination",
+        "setArgInDestination" -> {
+          assertThat(it.navigationElement.text)
+            .isEqualTo(
+              """
               <argument
                       android:name="arg_in_destination"
                       app:argType="string" />
-            """.trimIndent())
+            """
+                .trimIndent()
+            )
         }
         else -> throw IllegalAccessError("This should never happen!")
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/TypeMapping.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/TypeMapping.kt
index d7e2c92..f25b17c 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/TypeMapping.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/java/TypeMapping.kt
@@ -20,4 +20,4 @@
  */
 data class TypeMapping(val before: String, val after: String) {
   constructor(beforeAndAfter: String) : this(beforeAndAfter, beforeAndAfter)
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/xml/SafeArgsXmlTagTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/xml/SafeArgsXmlTagTest.kt
index e97ba54..020292e 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/xml/SafeArgsXmlTagTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/psi/xml/SafeArgsXmlTagTest.kt
@@ -25,32 +25,34 @@
 import org.junit.Test
 
 class SafeArgsXmlTagTest {
-  @get:Rule
-  val applicationRule = ApplicationRule()
+  @get:Rule val applicationRule = ApplicationRule()
 
   @Test
   fun checkValueEquivalency() {
-    val originalTag = object: XmlTagImpl() {
-      override fun isPhysical() = true
-    }
+    val originalTag =
+      object : XmlTagImpl() {
+        override fun isPhysical() = true
+      }
 
-    val tagA = SafeArgsXmlTag(
-      xmlTag = originalTag,
-      icon = IconManager.getInstance().getPlatformIcon(PlatformIcons.Class),
-      name = "Foo",
-      containerIdentifier = "package1"
-    )
+    val tagA =
+      SafeArgsXmlTag(
+        xmlTag = originalTag,
+        icon = IconManager.getInstance().getPlatformIcon(PlatformIcons.Class),
+        name = "Foo",
+        containerIdentifier = "package1"
+      )
 
-    val tagB = SafeArgsXmlTag(
-      xmlTag = originalTag,
-      icon = IconManager.getInstance().getPlatformIcon(PlatformIcons.Class),
-      name = "Foo",
-      containerIdentifier = "package1"
-    )
+    val tagB =
+      SafeArgsXmlTag(
+        xmlTag = originalTag,
+        icon = IconManager.getInstance().getPlatformIcon(PlatformIcons.Class),
+        name = "Foo",
+        containerIdentifier = "package1"
+      )
 
     ApplicationManager.getApplication().runReadAction {
       assertThat(tagA.isEquivalentTo(tagB)).isTrue()
       assertThat(tagA).isEqualTo(tagB)
     }
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/tracker/TestSafeArgsTracker.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/tracker/TestSafeArgsTracker.kt
index 6ffd676..e3207f8 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/tracker/TestSafeArgsTracker.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/tracker/TestSafeArgsTracker.kt
@@ -23,4 +23,4 @@
     // test to assert results immediately rather than having to wait on multi-threaded signalling.
     block()
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/tracker/gradle/SafeArgsTrackerTest.kt b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/tracker/gradle/SafeArgsTrackerTest.kt
index 9b7059a..bd2b633 100644
--- a/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/tracker/gradle/SafeArgsTrackerTest.kt
+++ b/nav/safeargs/tests/common/src/com/android/tools/idea/nav/safeargs/tracker/gradle/SafeArgsTrackerTest.kt
@@ -32,9 +32,7 @@
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
 
-/**
- * Verify that we can sync a Gradle project that applies the safe args plugin.
- */
+/** Verify that we can sync a Gradle project that applies the safe args plugin. */
 @RunsInEdt
 @RunWith(Parameterized::class)
 class SafeArgsTrackerTest(private val params: TestParams) {
@@ -48,45 +46,47 @@
     @Suppress("unused") // Accessed via reflection by JUnit
     @JvmStatic
     @get:Parameterized.Parameters(name = "{0}")
-    val parameters = listOf(
-      TestParams(TestDataPaths.MULTI_MODULE_PROJECT) { event ->
-        event!!
-        assertThat(event.eventContext).isEqualTo(NavSafeArgsEvent.EventContext.SYNC_EVENT_CONTEXT)
-        event.projectMetadata.let { projectMetadata ->
-          assertThat(projectMetadata.moduleCount).isEqualTo(3)
-          assertThat(projectMetadata.javaPluginCount).isEqualTo(1)
-          assertThat(projectMetadata.kotlinPluginCount).isEqualTo(1)
-        }
-      },
-      TestParams(TestDataPaths.PROJECT_USING_JAVA_PLUGIN) { event ->
-        event!!
-        assertThat(event.eventContext).isEqualTo(NavSafeArgsEvent.EventContext.SYNC_EVENT_CONTEXT)
-        event.projectMetadata.let { projectMetadata ->
-          assertThat(projectMetadata.moduleCount).isEqualTo(1)
-          assertThat(projectMetadata.javaPluginCount).isEqualTo(1)
-          assertThat(projectMetadata.kotlinPluginCount).isEqualTo(0)
-        }
-      },
-      TestParams(TestDataPaths.PROJECT_USING_KOTLIN_PLUGIN) { event ->
-        event!!
-        assertThat(event.eventContext).isEqualTo(NavSafeArgsEvent.EventContext.SYNC_EVENT_CONTEXT)
-        event.projectMetadata.let { projectMetadata ->
-          assertThat(projectMetadata.moduleCount).isEqualTo(1)
-          assertThat(projectMetadata.javaPluginCount).isEqualTo(0)
-          assertThat(projectMetadata.kotlinPluginCount).isEqualTo(1)
-        }
-      },
-      // Projects not using safe args don't generate safe args metrics
-      TestParams(TestDataPaths.PROJECT_WITHOUT_SAFE_ARGS) { event -> assertThat(event).isNull() })
+    val parameters =
+      listOf(
+        TestParams(TestDataPaths.MULTI_MODULE_PROJECT) { event ->
+          event!!
+          assertThat(event.eventContext).isEqualTo(NavSafeArgsEvent.EventContext.SYNC_EVENT_CONTEXT)
+          event.projectMetadata.let { projectMetadata ->
+            assertThat(projectMetadata.moduleCount).isEqualTo(3)
+            assertThat(projectMetadata.javaPluginCount).isEqualTo(1)
+            assertThat(projectMetadata.kotlinPluginCount).isEqualTo(1)
+          }
+        },
+        TestParams(TestDataPaths.PROJECT_USING_JAVA_PLUGIN) { event ->
+          event!!
+          assertThat(event.eventContext).isEqualTo(NavSafeArgsEvent.EventContext.SYNC_EVENT_CONTEXT)
+          event.projectMetadata.let { projectMetadata ->
+            assertThat(projectMetadata.moduleCount).isEqualTo(1)
+            assertThat(projectMetadata.javaPluginCount).isEqualTo(1)
+            assertThat(projectMetadata.kotlinPluginCount).isEqualTo(0)
+          }
+        },
+        TestParams(TestDataPaths.PROJECT_USING_KOTLIN_PLUGIN) { event ->
+          event!!
+          assertThat(event.eventContext).isEqualTo(NavSafeArgsEvent.EventContext.SYNC_EVENT_CONTEXT)
+          event.projectMetadata.let { projectMetadata ->
+            assertThat(projectMetadata.moduleCount).isEqualTo(1)
+            assertThat(projectMetadata.javaPluginCount).isEqualTo(0)
+            assertThat(projectMetadata.kotlinPluginCount).isEqualTo(1)
+          }
+        },
+        // Projects not using safe args don't generate safe args metrics
+        TestParams(TestDataPaths.PROJECT_WITHOUT_SAFE_ARGS) { event -> assertThat(event).isNull() }
+      )
   }
 
   private val projectRule = AndroidGradleProjectRule()
 
   // The tests need to run on the EDT thread but we must initialize the project rule off of it
-  @get:Rule
-  val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
+  @get:Rule val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
 
-  private val fixture get() = projectRule.fixture as JavaCodeInsightTestFixture
+  private val fixture
+    get() = projectRule.fixture as JavaCodeInsightTestFixture
 
   @Test
   fun verifyExpectedAnalytics() {
@@ -98,17 +98,17 @@
       projectRule.load(params.project)
       projectRule.requestSyncAndWait()
 
-      val safeArgsEvent = tracker.usages
-        .map { it.studioEvent }
-        .filter { it.kind == AndroidStudioEvent.EventKind.NAV_SAFE_ARGS_EVENT }
-        .map { it.navSafeArgsEvent }
-        .lastOrNull()
+      val safeArgsEvent =
+        tracker.usages
+          .map { it.studioEvent }
+          .filter { it.kind == AndroidStudioEvent.EventKind.NAV_SAFE_ARGS_EVENT }
+          .map { it.navSafeArgsEvent }
+          .lastOrNull()
 
       params.verify(safeArgsEvent)
-    }
-    finally {
+    } finally {
       tracker.close()
       UsageTracker.cleanAfterTesting()
     }
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/ArgsClassKtDescriptorsTest.kt b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/ArgsClassKtDescriptorsTest.kt
index a5bba3b..70bfec7 100644
--- a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/ArgsClassKtDescriptorsTest.kt
+++ b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/ArgsClassKtDescriptorsTest.kt
@@ -34,14 +34,13 @@
 
 @RunsInEdt
 class ArgsClassKtDescriptorsTest {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule(SafeArgsMode.KOTLIN)
+  @get:Rule val safeArgsRule = SafeArgsRule(SafeArgsMode.KOTLIN)
 
   @Test
   fun checkContributorsOfArgsClass() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -63,61 +62,67 @@
                 app:argType=".Fragment1" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
 
-    val safeArgProviderExtension = PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
-      it is SafeArgsKtPackageProviderExtension
-    }
+    val safeArgProviderExtension =
+      PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
+        it is SafeArgsKtPackageProviderExtension
+      }
 
     val traceMock: BindingTrace = MockitoKt.mock()
     val moduleSourceInfo = safeArgsRule.module.productionSourceInfo
     val moduleDescriptor = safeArgsRule.module.toDescriptor()
 
-    val fragmentProvider = safeArgProviderExtension.getPackageFragmentProvider(
-      project = safeArgsRule.project,
-      module = moduleDescriptor!!,
-      storageManager = LockBasedStorageManager.NO_LOCKS,
-      trace = traceMock,
-      moduleInfo = moduleSourceInfo,
-      lookupTracker = LookupTracker.DO_NOTHING
-    ) as SafeArgsSyntheticPackageProvider
+    val fragmentProvider =
+      safeArgProviderExtension.getPackageFragmentProvider(
+        project = safeArgsRule.project,
+        module = moduleDescriptor!!,
+        storageManager = LockBasedStorageManager.NO_LOCKS,
+        trace = traceMock,
+        moduleInfo = moduleSourceInfo,
+        lookupTracker = LookupTracker.DO_NOTHING
+      ) as SafeArgsSyntheticPackageProvider
 
-    val argsClassMetadata = fragmentProvider
-      .getPackageFragments(FqName("test.safeargs"))
-      .flatMap { it.getMemberScope().classesInScope() }
-      .single()
+    val argsClassMetadata =
+      fragmentProvider
+        .getPackageFragments(FqName("test.safeargs"))
+        .flatMap { it.getMemberScope().classesInScope() }
+        .single()
 
     assertThat(argsClassMetadata.fqcn).isEqualTo("test.safeargs.Fragment1Args")
-    assertThat(argsClassMetadata.constructors.map { it.toString() }).containsExactly(
-      "Fragment1Args(argOne: kotlin.String, argTwo: kotlin.IntArray, argThree: test.safeargs.Fragment1)"
-    )
+    assertThat(argsClassMetadata.constructors.map { it.toString() })
+      .containsExactly(
+        "Fragment1Args(argOne: kotlin.String, argTwo: kotlin.IntArray, argThree: test.safeargs.Fragment1)"
+      )
 
-    assertThat(argsClassMetadata.classifiers.map { it.toString() }).containsExactly(
-      "test.safeargs.Fragment1Args.Companion"
-    )
+    assertThat(argsClassMetadata.classifiers.map { it.toString() })
+      .containsExactly("test.safeargs.Fragment1Args.Companion")
 
-    assertThat(argsClassMetadata.companionObject!!.functions.map { it.toString() }).containsExactly(
-      "fromBundle(bundle: android.os.Bundle): test.safeargs.Fragment1Args"
-    )
+    assertThat(argsClassMetadata.companionObject!!.functions.map { it.toString() })
+      .containsExactly("fromBundle(bundle: android.os.Bundle): test.safeargs.Fragment1Args")
 
-    assertThat(argsClassMetadata.properties.map { it.toString() }).containsExactly(
-      "val argOne: kotlin.String",
-      "val argTwo: kotlin.IntArray",
-      "val argThree: test.safeargs.Fragment1"
-    )
+    assertThat(argsClassMetadata.properties.map { it.toString() })
+      .containsExactly(
+        "val argOne: kotlin.String",
+        "val argTwo: kotlin.IntArray",
+        "val argThree: test.safeargs.Fragment1"
+      )
 
-    assertThat(argsClassMetadata.functions.map { it.toString() }).containsExactly(
-      // generated functions of data class
-      "component1(): kotlin.String",
-      "component2(): kotlin.IntArray",
-      "component3(): test.safeargs.Fragment1",
-      "copy(argOne: kotlin.String, argTwo: kotlin.IntArray, argThree: test.safeargs.Fragment1): test.safeargs.Fragment1Args",
-      // normal functions
-      "toBundle(): android.os.Bundle"
-    )
+    assertThat(argsClassMetadata.functions.map { it.toString() })
+      .containsExactly(
+        // generated functions of data class
+        "component1(): kotlin.String",
+        "component2(): kotlin.IntArray",
+        "component3(): test.safeargs.Fragment1",
+        "copy(argOne: kotlin.String, argTwo: kotlin.IntArray, argThree: test.safeargs.Fragment1): test.safeargs.Fragment1Args",
+        // normal functions
+        "toBundle(): android.os.Bundle"
+      )
   }
 
   @Test
@@ -126,7 +131,7 @@
 
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -149,63 +154,71 @@
                 app:argType=".Fragment1" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
 
-    val safeArgProviderExtension = PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
-      it is SafeArgsKtPackageProviderExtension
-    }
+    val safeArgProviderExtension =
+      PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
+        it is SafeArgsKtPackageProviderExtension
+      }
 
     val traceMock: BindingTrace = MockitoKt.mock()
     val moduleSourceInfo = safeArgsRule.module.productionSourceInfo
     val moduleDescriptor = safeArgsRule.module.toDescriptor()
 
-    val fragmentProvider = safeArgProviderExtension.getPackageFragmentProvider(
-      project = safeArgsRule.project,
-      module = moduleDescriptor!!,
-      storageManager = LockBasedStorageManager.NO_LOCKS,
-      trace = traceMock,
-      moduleInfo = moduleSourceInfo,
-      lookupTracker = LookupTracker.DO_NOTHING
-    ) as SafeArgsSyntheticPackageProvider
+    val fragmentProvider =
+      safeArgProviderExtension.getPackageFragmentProvider(
+        project = safeArgsRule.project,
+        module = moduleDescriptor!!,
+        storageManager = LockBasedStorageManager.NO_LOCKS,
+        trace = traceMock,
+        moduleInfo = moduleSourceInfo,
+        lookupTracker = LookupTracker.DO_NOTHING
+      ) as SafeArgsSyntheticPackageProvider
 
-    val argsClassMetadata = fragmentProvider
-      .getPackageFragments(FqName("test.safeargs"))
-      .flatMap { it.getMemberScope().classesInScope() }
-      .single()
+    val argsClassMetadata =
+      fragmentProvider
+        .getPackageFragments(FqName("test.safeargs"))
+        .flatMap { it.getMemberScope().classesInScope() }
+        .single()
 
     assertThat(argsClassMetadata.fqcn).isEqualTo("test.safeargs.Fragment1Args")
-    assertThat(argsClassMetadata.constructors.map { it.toString() }).containsExactly(
-      "Fragment1Args(argTwo: kotlin.IntArray, argThree: test.safeargs.Fragment1, argOne: kotlin.String)"
-    )
+    assertThat(argsClassMetadata.constructors.map { it.toString() })
+      .containsExactly(
+        "Fragment1Args(argTwo: kotlin.IntArray, argThree: test.safeargs.Fragment1, argOne: kotlin.String)"
+      )
 
-    assertThat(argsClassMetadata.classifiers.map { it.toString() }).containsExactly(
-      "test.safeargs.Fragment1Args.Companion"
-    )
+    assertThat(argsClassMetadata.classifiers.map { it.toString() })
+      .containsExactly("test.safeargs.Fragment1Args.Companion")
 
-    assertThat(argsClassMetadata.companionObject!!.functions.map { it.toString() }).containsExactly(
-      "fromBundle(bundle: android.os.Bundle): test.safeargs.Fragment1Args",
-      "fromSavedStateHandle(savedStateHandle: androidx.lifecycle.SavedStateHandle): test.safeargs.Fragment1Args",
-    )
+    assertThat(argsClassMetadata.companionObject!!.functions.map { it.toString() })
+      .containsExactly(
+        "fromBundle(bundle: android.os.Bundle): test.safeargs.Fragment1Args",
+        "fromSavedStateHandle(savedStateHandle: androidx.lifecycle.SavedStateHandle): test.safeargs.Fragment1Args",
+      )
 
-    assertThat(argsClassMetadata.properties.map { it.toString() }).containsExactly(
-      "val argOne: kotlin.String",
-      "val argTwo: kotlin.IntArray",
-      "val argThree: test.safeargs.Fragment1"
-    )
+    assertThat(argsClassMetadata.properties.map { it.toString() })
+      .containsExactly(
+        "val argOne: kotlin.String",
+        "val argTwo: kotlin.IntArray",
+        "val argThree: test.safeargs.Fragment1"
+      )
 
-    assertThat(argsClassMetadata.functions.map { it.toString() }).containsExactly(
-      // generated functions of data class
-      "component1(): kotlin.String",
-      "component2(): kotlin.IntArray",
-      "component3(): test.safeargs.Fragment1",
-      "copy(argTwo: kotlin.IntArray, argThree: test.safeargs.Fragment1, argOne: kotlin.String): test.safeargs.Fragment1Args",
-      // normal functions
-      "toSavedStateHandle(): androidx.lifecycle.SavedStateHandle",
-      "toBundle(): android.os.Bundle"
-    )
+    assertThat(argsClassMetadata.functions.map { it.toString() })
+      .containsExactly(
+        // generated functions of data class
+        "component1(): kotlin.String",
+        "component2(): kotlin.IntArray",
+        "component3(): test.safeargs.Fragment1",
+        "copy(argTwo: kotlin.IntArray, argThree: test.safeargs.Fragment1, argOne: kotlin.String): test.safeargs.Fragment1Args",
+        // normal functions
+        "toSavedStateHandle(): androidx.lifecycle.SavedStateHandle",
+        "toBundle(): android.os.Bundle"
+      )
   }
 
   @Test
@@ -214,7 +227,7 @@
 
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -236,63 +249,71 @@
                 app:argType=".Fragment1" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
 
-    val safeArgProviderExtension = PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
-      it is SafeArgsKtPackageProviderExtension
-    }
+    val safeArgProviderExtension =
+      PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
+        it is SafeArgsKtPackageProviderExtension
+      }
 
     val traceMock: BindingTrace = MockitoKt.mock()
     val moduleSourceInfo = safeArgsRule.module.productionSourceInfo
     val moduleDescriptor = safeArgsRule.module.toDescriptor()
 
-    val fragmentProvider = safeArgProviderExtension.getPackageFragmentProvider(
-      project = safeArgsRule.project,
-      module = moduleDescriptor!!,
-      storageManager = LockBasedStorageManager.NO_LOCKS,
-      trace = traceMock,
-      moduleInfo = moduleSourceInfo,
-      lookupTracker = LookupTracker.DO_NOTHING
-    ) as SafeArgsSyntheticPackageProvider
+    val fragmentProvider =
+      safeArgProviderExtension.getPackageFragmentProvider(
+        project = safeArgsRule.project,
+        module = moduleDescriptor!!,
+        storageManager = LockBasedStorageManager.NO_LOCKS,
+        trace = traceMock,
+        moduleInfo = moduleSourceInfo,
+        lookupTracker = LookupTracker.DO_NOTHING
+      ) as SafeArgsSyntheticPackageProvider
 
-    val argsClassMetadata = fragmentProvider
-      .getPackageFragments(FqName("test.safeargs"))
-      .flatMap { it.getMemberScope().classesInScope() }
-      .single()
+    val argsClassMetadata =
+      fragmentProvider
+        .getPackageFragments(FqName("test.safeargs"))
+        .flatMap { it.getMemberScope().classesInScope() }
+        .single()
 
     assertThat(argsClassMetadata.fqcn).isEqualTo("test.safeargs.Fragment1Args")
-    assertThat(argsClassMetadata.constructors.map { it.toString() }).containsExactly(
-      "Fragment1Args(argOne: kotlin.String, argTwo: kotlin.IntArray, argThree: test.safeargs.Fragment1)"
-    )
+    assertThat(argsClassMetadata.constructors.map { it.toString() })
+      .containsExactly(
+        "Fragment1Args(argOne: kotlin.String, argTwo: kotlin.IntArray, argThree: test.safeargs.Fragment1)"
+      )
 
-    assertThat(argsClassMetadata.classifiers.map { it.toString() }).containsExactly(
-      "test.safeargs.Fragment1Args.Companion"
-    )
+    assertThat(argsClassMetadata.classifiers.map { it.toString() })
+      .containsExactly("test.safeargs.Fragment1Args.Companion")
 
-    assertThat(argsClassMetadata.companionObject!!.functions.map { it.toString() }).containsExactly(
-      "fromBundle(bundle: android.os.Bundle): test.safeargs.Fragment1Args",
-      "fromSavedStateHandle(savedStateHandle: androidx.lifecycle.SavedStateHandle): test.safeargs.Fragment1Args",
-    )
+    assertThat(argsClassMetadata.companionObject!!.functions.map { it.toString() })
+      .containsExactly(
+        "fromBundle(bundle: android.os.Bundle): test.safeargs.Fragment1Args",
+        "fromSavedStateHandle(savedStateHandle: androidx.lifecycle.SavedStateHandle): test.safeargs.Fragment1Args",
+      )
 
-    assertThat(argsClassMetadata.properties.map { it.toString() }).containsExactly(
-      "val argOne: kotlin.String",
-      "val argTwo: kotlin.IntArray",
-      "val argThree: test.safeargs.Fragment1"
-    )
+    assertThat(argsClassMetadata.properties.map { it.toString() })
+      .containsExactly(
+        "val argOne: kotlin.String",
+        "val argTwo: kotlin.IntArray",
+        "val argThree: test.safeargs.Fragment1"
+      )
 
-    assertThat(argsClassMetadata.functions.map { it.toString() }).containsExactly(
-      // generated functions of data class
-      "component1(): kotlin.String",
-      "component2(): kotlin.IntArray",
-      "component3(): test.safeargs.Fragment1",
-      "copy(argOne: kotlin.String, argTwo: kotlin.IntArray, argThree: test.safeargs.Fragment1): test.safeargs.Fragment1Args",
-      // normal functions
-      "toSavedStateHandle(): androidx.lifecycle.SavedStateHandle",
-      "toBundle(): android.os.Bundle"
-    )
+    assertThat(argsClassMetadata.functions.map { it.toString() })
+      .containsExactly(
+        // generated functions of data class
+        "component1(): kotlin.String",
+        "component2(): kotlin.IntArray",
+        "component3(): test.safeargs.Fragment1",
+        "copy(argOne: kotlin.String, argTwo: kotlin.IntArray, argThree: test.safeargs.Fragment1): test.safeargs.Fragment1Args",
+        // normal functions
+        "toSavedStateHandle(): androidx.lifecycle.SavedStateHandle",
+        "toBundle(): android.os.Bundle"
+      )
   }
 
   @Test
@@ -301,7 +322,7 @@
 
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -323,61 +344,69 @@
                 app:argType=".Fragment1" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
 
-    val safeArgProviderExtension = PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
-      it is SafeArgsKtPackageProviderExtension
-    }
+    val safeArgProviderExtension =
+      PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
+        it is SafeArgsKtPackageProviderExtension
+      }
 
     val traceMock: BindingTrace = MockitoKt.mock()
     val moduleSourceInfo = safeArgsRule.module.productionSourceInfo
     val moduleDescriptor = safeArgsRule.module.toDescriptor()
 
-    val fragmentProvider = safeArgProviderExtension.getPackageFragmentProvider(
-      project = safeArgsRule.project,
-      module = moduleDescriptor!!,
-      storageManager = LockBasedStorageManager.NO_LOCKS,
-      trace = traceMock,
-      moduleInfo = moduleSourceInfo,
-      lookupTracker = LookupTracker.DO_NOTHING
-    ) as SafeArgsSyntheticPackageProvider
+    val fragmentProvider =
+      safeArgProviderExtension.getPackageFragmentProvider(
+        project = safeArgsRule.project,
+        module = moduleDescriptor!!,
+        storageManager = LockBasedStorageManager.NO_LOCKS,
+        trace = traceMock,
+        moduleInfo = moduleSourceInfo,
+        lookupTracker = LookupTracker.DO_NOTHING
+      ) as SafeArgsSyntheticPackageProvider
 
-    val argsClassMetadata = fragmentProvider
-      .getPackageFragments(FqName("test.safeargs"))
-      .flatMap { it.getMemberScope().classesInScope() }
-      .single()
+    val argsClassMetadata =
+      fragmentProvider
+        .getPackageFragments(FqName("test.safeargs"))
+        .flatMap { it.getMemberScope().classesInScope() }
+        .single()
 
     assertThat(argsClassMetadata.fqcn).isEqualTo("test.safeargs.Fragment1Args")
-    assertThat(argsClassMetadata.constructors.map { it.toString() }).containsExactly(
-      "Fragment1Args(argOne: kotlin.String, argTwo: kotlin.IntArray, argThree: test.safeargs.Fragment1)"
-    )
+    assertThat(argsClassMetadata.constructors.map { it.toString() })
+      .containsExactly(
+        "Fragment1Args(argOne: kotlin.String, argTwo: kotlin.IntArray, argThree: test.safeargs.Fragment1)"
+      )
 
-    assertThat(argsClassMetadata.classifiers.map { it.toString() }).containsExactly(
-      "test.safeargs.Fragment1Args.Companion"
-    )
+    assertThat(argsClassMetadata.classifiers.map { it.toString() })
+      .containsExactly("test.safeargs.Fragment1Args.Companion")
 
-    assertThat(argsClassMetadata.companionObject!!.functions.map { it.toString() }).containsExactly(
-      "fromBundle(bundle: android.os.Bundle): test.safeargs.Fragment1Args",
-      "fromSavedStateHandle(savedStateHandle: androidx.lifecycle.SavedStateHandle): test.safeargs.Fragment1Args",
-    )
+    assertThat(argsClassMetadata.companionObject!!.functions.map { it.toString() })
+      .containsExactly(
+        "fromBundle(bundle: android.os.Bundle): test.safeargs.Fragment1Args",
+        "fromSavedStateHandle(savedStateHandle: androidx.lifecycle.SavedStateHandle): test.safeargs.Fragment1Args",
+      )
 
-    assertThat(argsClassMetadata.properties.map { it.toString() }).containsExactly(
-      "val argOne: kotlin.String",
-      "val argTwo: kotlin.IntArray",
-      "val argThree: test.safeargs.Fragment1"
-    )
+    assertThat(argsClassMetadata.properties.map { it.toString() })
+      .containsExactly(
+        "val argOne: kotlin.String",
+        "val argTwo: kotlin.IntArray",
+        "val argThree: test.safeargs.Fragment1"
+      )
 
-    assertThat(argsClassMetadata.functions.map { it.toString() }).containsExactly(
-      // generated functions of data class
-      "component1(): kotlin.String",
-      "component2(): kotlin.IntArray",
-      "component3(): test.safeargs.Fragment1",
-      "copy(argOne: kotlin.String, argTwo: kotlin.IntArray, argThree: test.safeargs.Fragment1): test.safeargs.Fragment1Args",
-      // normal functions
-      "toBundle(): android.os.Bundle"
-    )
+    assertThat(argsClassMetadata.functions.map { it.toString() })
+      .containsExactly(
+        // generated functions of data class
+        "component1(): kotlin.String",
+        "component2(): kotlin.IntArray",
+        "component3(): test.safeargs.Fragment1",
+        "copy(argOne: kotlin.String, argTwo: kotlin.IntArray, argThree: test.safeargs.Fragment1): test.safeargs.Fragment1Args",
+        // normal functions
+        "toBundle(): android.os.Bundle"
+      )
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/ClassMetadata.kt b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/ClassMetadata.kt
index a5cbcd3..279ec71 100644
--- a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/ClassMetadata.kt
+++ b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/ClassMetadata.kt
@@ -55,10 +55,7 @@
   }
 }
 
-internal class ParameterMetadata(
-  var name: String = "",
-  var type: String = ""
-) {
+internal class ParameterMetadata(var name: String = "", var type: String = "") {
   override fun toString(): String {
     return "$name: $type"
   }
@@ -94,8 +91,7 @@
         descriptor.unsubstitutedMemberScope.getContributedDescriptors().forEach { desc ->
           if (desc is ClassDescriptor) {
             classifiers.add(fromDescriptor(desc))
-          }
-          else {
+          } else {
             desc.accept(visitor, this)
           }
         }
@@ -111,7 +107,9 @@
   }
 }
 
-internal fun ResolutionScope.classesInScope(nameFilter: (String) -> Boolean = { true }): Collection<ClassMetadata> {
+internal fun ResolutionScope.classesInScope(
+  nameFilter: (String) -> Boolean = { true }
+): Collection<ClassMetadata> {
   return this.getContributedDescriptors { nameFilter(it.asString()) }
     .sortedWith(MemberComparator.INSTANCE)
     .filterIsInstance<ClassDescriptor>()
@@ -126,8 +124,9 @@
 }
 
 private fun List<ParameterDescriptor>.toMetadata(): MutableList<ParameterMetadata> {
-  return this
-    .map { paramDesc -> ParameterMetadata(paramDesc.name.asString(), paramDesc.type.asString()) }
+  return this.map { paramDesc ->
+      ParameterMetadata(paramDesc.name.asString(), paramDesc.type.asString())
+    }
     .toMutableList()
 }
 
@@ -146,13 +145,17 @@
 private class MetadataVisitor : DeclarationDescriptorVisitor<Unit, ClassMetadata> {
   override fun visitClassDescriptor(descriptor: ClassDescriptor, data: ClassMetadata) {
     data.fqcn = descriptor.fqNameSafe.asString()
-    data.supertypes = descriptor.typeConstructor.supertypes
-      .filter { type -> !type.isAnyOrNullableAny() }
-      .map { type -> type.asString() }
-      .toMutableList()
+    data.supertypes =
+      descriptor.typeConstructor.supertypes
+        .filter { type -> !type.isAnyOrNullableAny() }
+        .map { type -> type.asString() }
+        .toMutableList()
   }
 
-  override fun visitConstructorDescriptor(constructorDescriptor: ConstructorDescriptor, data: ClassMetadata) {
+  override fun visitConstructorDescriptor(
+    constructorDescriptor: ConstructorDescriptor,
+    data: ClassMetadata
+  ) {
     data.constructors.add(constructorDescriptor.toMetadata())
   }
 
@@ -164,16 +167,33 @@
     data.properties.add(descriptor.toMetadata())
   }
 
-
   override fun visitModuleDeclaration(descriptor: ModuleDescriptor, data: ClassMetadata) {}
   override fun visitPackageViewDescriptor(descriptor: PackageViewDescriptor, data: ClassMetadata) {}
-  override fun visitPropertyGetterDescriptor(descriptor: PropertyGetterDescriptor, data: ClassMetadata) {}
-  override fun visitPropertySetterDescriptor(descriptor: PropertySetterDescriptor, data: ClassMetadata) {}
-  override fun visitReceiverParameterDescriptor(descriptor: ReceiverParameterDescriptor, data: ClassMetadata) {}
-  override fun visitPackageFragmentDescriptor(descriptor: PackageFragmentDescriptor, data: ClassMetadata) {}
+  override fun visitPropertyGetterDescriptor(
+    descriptor: PropertyGetterDescriptor,
+    data: ClassMetadata
+  ) {}
+  override fun visitPropertySetterDescriptor(
+    descriptor: PropertySetterDescriptor,
+    data: ClassMetadata
+  ) {}
+  override fun visitReceiverParameterDescriptor(
+    descriptor: ReceiverParameterDescriptor,
+    data: ClassMetadata
+  ) {}
+  override fun visitPackageFragmentDescriptor(
+    descriptor: PackageFragmentDescriptor,
+    data: ClassMetadata
+  ) {}
   override fun visitScriptDescriptor(scriptDescriptor: ScriptDescriptor, data: ClassMetadata) {}
   override fun visitTypeAliasDescriptor(descriptor: TypeAliasDescriptor, data: ClassMetadata) {}
-  override fun visitTypeParameterDescriptor(descriptor: TypeParameterDescriptor, data: ClassMetadata) {}
-  override fun visitValueParameterDescriptor(descriptor: ValueParameterDescriptor, data: ClassMetadata) {}
+  override fun visitTypeParameterDescriptor(
+    descriptor: TypeParameterDescriptor,
+    data: ClassMetadata
+  ) {}
+  override fun visitValueParameterDescriptor(
+    descriptor: ValueParameterDescriptor,
+    data: ClassMetadata
+  ) {}
   override fun visitVariableDescriptor(descriptor: VariableDescriptor, data: ClassMetadata) {}
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/DirectionsClassKtDescriptorsTest.kt b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/DirectionsClassKtDescriptorsTest.kt
index bc012bb..3f18006 100644
--- a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/DirectionsClassKtDescriptorsTest.kt
+++ b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/DirectionsClassKtDescriptorsTest.kt
@@ -34,14 +34,13 @@
 
 @RunsInEdt
 class DirectionsClassKtDescriptorsTest {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule(SafeArgsMode.KOTLIN)
+  @get:Rule val safeArgsRule = SafeArgsRule(SafeArgsMode.KOTLIN)
 
   @Test
   fun checkContributorsOfDirectionsClass() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -70,41 +69,47 @@
               android:name="test.safeargs.Fragment2"
               android:label="Fragment2" />
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
 
-    val safeArgProviderExtension = PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
-      it is SafeArgsKtPackageProviderExtension
-    }
+    val safeArgProviderExtension =
+      PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
+        it is SafeArgsKtPackageProviderExtension
+      }
 
     val traceMock: BindingTrace = MockitoKt.mock()
     val moduleSourceInfo = safeArgsRule.module.productionSourceInfo
     val moduleDescriptor = safeArgsRule.module.toDescriptor()
 
-    val fragmentProvider = safeArgProviderExtension.getPackageFragmentProvider(
-      project = safeArgsRule.project,
-      module = moduleDescriptor!!,
-      storageManager = LockBasedStorageManager.NO_LOCKS,
-      trace = traceMock,
-      moduleInfo = moduleSourceInfo,
-      lookupTracker = LookupTracker.DO_NOTHING
-    ) as SafeArgsSyntheticPackageProvider
+    val fragmentProvider =
+      safeArgProviderExtension.getPackageFragmentProvider(
+        project = safeArgsRule.project,
+        module = moduleDescriptor!!,
+        storageManager = LockBasedStorageManager.NO_LOCKS,
+        trace = traceMock,
+        moduleInfo = moduleSourceInfo,
+        lookupTracker = LookupTracker.DO_NOTHING
+      ) as SafeArgsSyntheticPackageProvider
 
-    val directionsClassMetadata = fragmentProvider.getPackageFragments(FqName("test.safeargs"))
-      .flatMap { it.getMemberScope().classesInScope { name -> name.endsWith("Directions") } }
-      .first()
+    val directionsClassMetadata =
+      fragmentProvider
+        .getPackageFragments(FqName("test.safeargs"))
+        .flatMap { it.getMemberScope().classesInScope { name -> name.endsWith("Directions") } }
+        .first()
 
     assertThat(directionsClassMetadata.constructors).isEmpty()
-    assertThat(directionsClassMetadata.classifiers.map { it.toString() }).containsExactly(
-      "test.safeargs.Fragment1Directions.Companion"
-    )
-    assertThat(directionsClassMetadata.companionObject!!.functions.map { it.toString() }).containsExactly(
-      "actionFragment1ToFragment2(): androidx.navigation.NavDirections",
-      "actionFragment1ToMain(): androidx.navigation.NavDirections",
-      "actionWithoutDestination(): androidx.navigation.NavDirections",
-    )
+    assertThat(directionsClassMetadata.classifiers.map { it.toString() })
+      .containsExactly("test.safeargs.Fragment1Directions.Companion")
+    assertThat(directionsClassMetadata.companionObject!!.functions.map { it.toString() })
+      .containsExactly(
+        "actionFragment1ToFragment2(): androidx.navigation.NavDirections",
+        "actionFragment1ToMain(): androidx.navigation.NavDirections",
+        "actionWithoutDestination(): androidx.navigation.NavDirections",
+      )
     assertThat(directionsClassMetadata.functions).isEmpty()
   }
 
@@ -113,7 +118,7 @@
     safeArgsRule.addFakeNavigationDependency(SafeArgsFeatureVersions.ADJUST_PARAMS_WITH_DEFAULTS)
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -159,54 +164,60 @@
             </action>
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
 
-    val safeArgProviderExtension = PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
-      it is SafeArgsKtPackageProviderExtension
-    }
+    val safeArgProviderExtension =
+      PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
+        it is SafeArgsKtPackageProviderExtension
+      }
 
     val traceMock: BindingTrace = MockitoKt.mock()
     val moduleSourceInfo = safeArgsRule.module.productionSourceInfo
     val moduleDescriptor = safeArgsRule.module.toDescriptor()
 
-    val fragmentProvider = safeArgProviderExtension.getPackageFragmentProvider(
-      project = safeArgsRule.project,
-      module = moduleDescriptor!!,
-      storageManager = LockBasedStorageManager.NO_LOCKS,
-      trace = traceMock,
-      moduleInfo = moduleSourceInfo,
-      lookupTracker = LookupTracker.DO_NOTHING
-    ) as SafeArgsSyntheticPackageProvider
+    val fragmentProvider =
+      safeArgProviderExtension.getPackageFragmentProvider(
+        project = safeArgsRule.project,
+        module = moduleDescriptor!!,
+        storageManager = LockBasedStorageManager.NO_LOCKS,
+        trace = traceMock,
+        moduleInfo = moduleSourceInfo,
+        lookupTracker = LookupTracker.DO_NOTHING
+      ) as SafeArgsSyntheticPackageProvider
 
-    val directionsClassMetadata = fragmentProvider.getPackageFragments(FqName("test.safeargs"))
-      .flatMap { it.getMemberScope().classesInScope { name -> name.endsWith("Directions") } }
-      .sortedBy { it.fqcn }
+    val directionsClassMetadata =
+      fragmentProvider
+        .getPackageFragments(FqName("test.safeargs"))
+        .flatMap { it.getMemberScope().classesInScope { name -> name.endsWith("Directions") } }
+        .sortedBy { it.fqcn }
 
     assertThat(directionsClassMetadata.size).isEqualTo(2)
 
     directionsClassMetadata[0].let { directionsClass ->
       assertThat(directionsClass.constructors).isEmpty()
-      assertThat(directionsClass.classifiers.map { it.toString() }).containsExactly(
-        "test.safeargs.Fragment1Directions.Companion"
-      )
-      assertThat(directionsClass.companionObject!!.functions.map { it.toString() }).containsExactly(
-        "actionFragment1ToFragment2(overriddenArg: kotlin.String, arg: kotlin.String, overriddenArgWithDefaultValue: kotlin.Int)" +
-        ": androidx.navigation.NavDirections"
-      )
+      assertThat(directionsClass.classifiers.map { it.toString() })
+        .containsExactly("test.safeargs.Fragment1Directions.Companion")
+      assertThat(directionsClass.companionObject!!.functions.map { it.toString() })
+        .containsExactly(
+          "actionFragment1ToFragment2(overriddenArg: kotlin.String, arg: kotlin.String, overriddenArgWithDefaultValue: kotlin.Int)" +
+            ": androidx.navigation.NavDirections"
+        )
       assertThat(directionsClass.functions).isEmpty()
     }
 
     directionsClassMetadata[1].let { directionsClass ->
       assertThat(directionsClass.constructors).isEmpty()
-      assertThat(directionsClass.classifiers.map { it.toString() }).containsExactly(
-        "test.safeargs.Fragment2Directions.Companion"
-      )
-      assertThat(directionsClass.companionObject!!.functions.map { it.toString() }).containsExactly(
-        "actionFragment2ToMain(overriddenArgWithDefaultValue: kotlin.Int): androidx.navigation.NavDirections"
-      )
+      assertThat(directionsClass.classifiers.map { it.toString() })
+        .containsExactly("test.safeargs.Fragment2Directions.Companion")
+      assertThat(directionsClass.companionObject!!.functions.map { it.toString() })
+        .containsExactly(
+          "actionFragment2ToMain(overriddenArgWithDefaultValue: kotlin.Int): androidx.navigation.NavDirections"
+        )
       assertThat(directionsClass.functions).isEmpty()
     }
   }
@@ -215,7 +226,7 @@
   fun testIncludedNavigationCase() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -232,42 +243,46 @@
                   app:destination="@id/included_graph" />                  
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
 
-    val safeArgProviderExtension = PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
-      it is SafeArgsKtPackageProviderExtension
-    }
+    val safeArgProviderExtension =
+      PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
+        it is SafeArgsKtPackageProviderExtension
+      }
 
     val traceMock: BindingTrace = MockitoKt.mock()
     val moduleSourceInfo = safeArgsRule.module.productionSourceInfo
     val moduleDescriptor = safeArgsRule.module.toDescriptor()
 
-    val fragmentProvider = safeArgProviderExtension.getPackageFragmentProvider(
-      project = safeArgsRule.project,
-      module = moduleDescriptor!!,
-      storageManager = LockBasedStorageManager.NO_LOCKS,
-      trace = traceMock,
-      moduleInfo = moduleSourceInfo,
-      lookupTracker = LookupTracker.DO_NOTHING
-    ) as SafeArgsSyntheticPackageProvider
+    val fragmentProvider =
+      safeArgProviderExtension.getPackageFragmentProvider(
+        project = safeArgsRule.project,
+        module = moduleDescriptor!!,
+        storageManager = LockBasedStorageManager.NO_LOCKS,
+        trace = traceMock,
+        moduleInfo = moduleSourceInfo,
+        lookupTracker = LookupTracker.DO_NOTHING
+      ) as SafeArgsSyntheticPackageProvider
 
-    val directionsClassMetadata = fragmentProvider.getPackageFragments(FqName("test.safeargs"))
-      .flatMap { it.getMemberScope().classesInScope { name -> name.endsWith("Directions") } }
-      .sortedBy { it.fqcn }
+    val directionsClassMetadata =
+      fragmentProvider
+        .getPackageFragments(FqName("test.safeargs"))
+        .flatMap { it.getMemberScope().classesInScope { name -> name.endsWith("Directions") } }
+        .sortedBy { it.fqcn }
 
     assertThat(directionsClassMetadata.size).isEqualTo(1)
 
     directionsClassMetadata[0].let { directionsClass ->
       assertThat(directionsClass.constructors).isEmpty()
-      assertThat(directionsClass.classifiers.map { it.toString() }).containsExactly(
-        "test.safeargs.Fragment2Directions.Companion"
-      )
-      assertThat(directionsClass.companionObject!!.functions.map { it.toString() }).containsExactly(
-        "actionFragment2ToIncludedGraph(): androidx.navigation.NavDirections"
-      )
+      assertThat(directionsClass.classifiers.map { it.toString() })
+        .containsExactly("test.safeargs.Fragment2Directions.Companion")
+      assertThat(directionsClass.companionObject!!.functions.map { it.toString() })
+        .containsExactly("actionFragment2ToIncludedGraph(): androidx.navigation.NavDirections")
       assertThat(directionsClass.functions).isEmpty()
     }
   }
@@ -276,7 +291,7 @@
   fun testGlobalActionCase() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -312,67 +327,71 @@
                 
           </navigation>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
 
-    val safeArgProviderExtension = PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
-      it is SafeArgsKtPackageProviderExtension
-    }
+    val safeArgProviderExtension =
+      PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
+        it is SafeArgsKtPackageProviderExtension
+      }
 
     val traceMock: BindingTrace = MockitoKt.mock()
     val moduleSourceInfo = safeArgsRule.module.productionSourceInfo
     val moduleDescriptor = safeArgsRule.module.toDescriptor()
 
-    val fragmentProvider = safeArgProviderExtension.getPackageFragmentProvider(
-      project = safeArgsRule.project,
-      module = moduleDescriptor!!,
-      storageManager = LockBasedStorageManager.NO_LOCKS,
-      trace = traceMock,
-      moduleInfo = moduleSourceInfo,
-      lookupTracker = LookupTracker.DO_NOTHING
-    ) as SafeArgsSyntheticPackageProvider
+    val fragmentProvider =
+      safeArgProviderExtension.getPackageFragmentProvider(
+        project = safeArgsRule.project,
+        module = moduleDescriptor!!,
+        storageManager = LockBasedStorageManager.NO_LOCKS,
+        trace = traceMock,
+        moduleInfo = moduleSourceInfo,
+        lookupTracker = LookupTracker.DO_NOTHING
+      ) as SafeArgsSyntheticPackageProvider
 
-    val directionsClassMetadata = fragmentProvider.getPackageFragments(FqName("test.safeargs"))
-      .flatMap { it.getMemberScope().classesInScope { name -> name.endsWith("Directions") } }
-      .sortedBy { it.fqcn }
+    val directionsClassMetadata =
+      fragmentProvider
+        .getPackageFragments(FqName("test.safeargs"))
+        .flatMap { it.getMemberScope().classesInScope { name -> name.endsWith("Directions") } }
+        .sortedBy { it.fqcn }
 
     assertThat(directionsClassMetadata.size).isEqualTo(3)
 
     directionsClassMetadata[0].let { directionsClass ->
       assertThat(directionsClass.constructors).isEmpty()
-      assertThat(directionsClass.classifiers.map { it.toString() }).containsExactly(
-        "test.safeargs.Fragment2Directions.Companion"
-      )
-      assertThat(directionsClass.companionObject!!.functions.map { it.toString() }).containsExactly(
-        "actionFragment2ToIncludedGraph(): androidx.navigation.NavDirections",
-        "actionToIncludedGraph(): androidx.navigation.NavDirections",
-        "actionInnerNavigationToIncludedGraph(): androidx.navigation.NavDirections"
-      )
+      assertThat(directionsClass.classifiers.map { it.toString() })
+        .containsExactly("test.safeargs.Fragment2Directions.Companion")
+      assertThat(directionsClass.companionObject!!.functions.map { it.toString() })
+        .containsExactly(
+          "actionFragment2ToIncludedGraph(): androidx.navigation.NavDirections",
+          "actionToIncludedGraph(): androidx.navigation.NavDirections",
+          "actionInnerNavigationToIncludedGraph(): androidx.navigation.NavDirections"
+        )
       assertThat(directionsClass.functions).isEmpty()
     }
 
     directionsClassMetadata[1].let { directionsClass ->
       assertThat(directionsClass.constructors).isEmpty()
-      assertThat(directionsClass.classifiers.map { it.toString() }).containsExactly(
-        "test.safeargs.InnerNavigationDirections.Companion"
-      )
-      assertThat(directionsClass.companionObject!!.functions.map { it.toString() }).containsExactly(
-        "actionToIncludedGraph(): androidx.navigation.NavDirections",
-        "actionInnerNavigationToIncludedGraph(): androidx.navigation.NavDirections"
-      )
+      assertThat(directionsClass.classifiers.map { it.toString() })
+        .containsExactly("test.safeargs.InnerNavigationDirections.Companion")
+      assertThat(directionsClass.companionObject!!.functions.map { it.toString() })
+        .containsExactly(
+          "actionToIncludedGraph(): androidx.navigation.NavDirections",
+          "actionInnerNavigationToIncludedGraph(): androidx.navigation.NavDirections"
+        )
       assertThat(directionsClass.functions).isEmpty()
     }
 
     directionsClassMetadata[2].let { directionsClass ->
       assertThat(directionsClass.constructors).isEmpty()
-      assertThat(directionsClass.classifiers.map { it.toString() }).containsExactly(
-        "test.safeargs.MainDirections.Companion"
-      )
-      assertThat(directionsClass.companionObject!!.functions.map { it.toString() }).containsExactly(
-        "actionToIncludedGraph(): androidx.navigation.NavDirections"
-      )
+      assertThat(directionsClass.classifiers.map { it.toString() })
+        .containsExactly("test.safeargs.MainDirections.Companion")
+      assertThat(directionsClass.companionObject!!.functions.map { it.toString() })
+        .containsExactly("actionToIncludedGraph(): androidx.navigation.NavDirections")
       assertThat(directionsClass.functions).isEmpty()
     }
   }
@@ -381,7 +400,7 @@
   fun checkNoDestinationDefinedCase() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -405,39 +424,43 @@
                 app:popUpTo="@id/fragment1" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
 
-    val safeArgProviderExtension = PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
-      it is SafeArgsKtPackageProviderExtension
-    }
+    val safeArgProviderExtension =
+      PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
+        it is SafeArgsKtPackageProviderExtension
+      }
 
     val traceMock: BindingTrace = MockitoKt.mock()
     val moduleSourceInfo = safeArgsRule.module.productionSourceInfo
     val moduleDescriptor = safeArgsRule.module.toDescriptor()
 
-    val fragmentProvider = safeArgProviderExtension.getPackageFragmentProvider(
-      project = safeArgsRule.project,
-      module = moduleDescriptor!!,
-      storageManager = LockBasedStorageManager.NO_LOCKS,
-      trace = traceMock,
-      moduleInfo = moduleSourceInfo,
-      lookupTracker = LookupTracker.DO_NOTHING
-    ) as SafeArgsSyntheticPackageProvider
+    val fragmentProvider =
+      safeArgProviderExtension.getPackageFragmentProvider(
+        project = safeArgsRule.project,
+        module = moduleDescriptor!!,
+        storageManager = LockBasedStorageManager.NO_LOCKS,
+        trace = traceMock,
+        moduleInfo = moduleSourceInfo,
+        lookupTracker = LookupTracker.DO_NOTHING
+      ) as SafeArgsSyntheticPackageProvider
 
-    val directionsClassMetadata = fragmentProvider.getPackageFragments(FqName("test.safeargs"))
-      .flatMap { it.getMemberScope().classesInScope { name -> name.endsWith("Directions") } }
-      .first()
+    val directionsClassMetadata =
+      fragmentProvider
+        .getPackageFragments(FqName("test.safeargs"))
+        .flatMap { it.getMemberScope().classesInScope { name -> name.endsWith("Directions") } }
+        .first()
 
     assertThat(directionsClassMetadata.constructors).isEmpty()
-    assertThat(directionsClassMetadata.classifiers.map { it.toString() }).containsExactly(
-      "test.safeargs.Fragment2Directions.Companion"
-    )
-    assertThat(directionsClassMetadata.companionObject!!.functions.map { it.toString() }).containsExactly(
-      "actionFragment2ToFragment1(): androidx.navigation.NavDirections"
-    )
+    assertThat(directionsClassMetadata.classifiers.map { it.toString() })
+      .containsExactly("test.safeargs.Fragment2Directions.Companion")
+    assertThat(directionsClassMetadata.companionObject!!.functions.map { it.toString() })
+      .containsExactly("actionFragment2ToFragment1(): androidx.navigation.NavDirections")
     assertThat(directionsClassMetadata.functions).isEmpty()
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KotlinTypeUtilsKtTest.kt b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KotlinTypeUtilsKtTest.kt
index edb70e5..a475b47 100644
--- a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KotlinTypeUtilsKtTest.kt
+++ b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/KotlinTypeUtilsKtTest.kt
@@ -30,13 +30,10 @@
 import org.junit.Rule
 import org.junit.Test
 
-/**
- *  Tests on types check, nullabilities check, inferred types check
- */
+/** Tests on types check, nullabilities check, inferred types check */
 @RunsInEdt
 class KotlinTypeUtilsKtTest {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule(SafeArgsMode.KOTLIN)
+  @get:Rule val safeArgsRule = SafeArgsRule(SafeArgsMode.KOTLIN)
 
   private val builtIn = DefaultBuiltIns.Instance
   private lateinit var moduleDescriptor: ModuleDescriptor
@@ -46,129 +43,141 @@
     moduleDescriptor = safeArgsRule.module.toDescriptor()!!
   }
 
-  /**
-   * Primitive types regular check
-   */
+  /** Primitive types regular check */
   @Test
   fun checkInteger() {
-    val type = builtIn.getKotlinType(
-      typeStr = "integer",
-      defaultValue = null,
-      moduleDescriptor = moduleDescriptor
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = "integer",
+        defaultValue = null,
+        moduleDescriptor = moduleDescriptor
+      )
     assertThat(type).isEqualTo(builtIn.intType)
   }
 
   @Test
   fun checkIntegerArray() {
-    val type = builtIn.getKotlinType(
-      typeStr = "integer[]",
-      defaultValue = null,
-      moduleDescriptor = moduleDescriptor
-    )
-    assertThat(type).isEqualTo(builtIn.getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(builtIn.intType))
+    val type =
+      builtIn.getKotlinType(
+        typeStr = "integer[]",
+        defaultValue = null,
+        moduleDescriptor = moduleDescriptor
+      )
+    assertThat(type)
+      .isEqualTo(builtIn.getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(builtIn.intType))
   }
 
   @Test
   fun checkFloat() {
-    val type = builtIn.getKotlinType(
-      typeStr = "float",
-      defaultValue = null,
-      moduleDescriptor = moduleDescriptor
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = "float",
+        defaultValue = null,
+        moduleDescriptor = moduleDescriptor
+      )
     assertThat(type).isEqualTo(builtIn.floatType)
   }
 
   @Test
   fun checkFloatArray() {
-    val type = builtIn.getKotlinType(
-      typeStr = "float[]",
-      defaultValue = null,
-      moduleDescriptor = moduleDescriptor
-    )
-    assertThat(type).isEqualTo(builtIn.getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(builtIn.floatType))
+    val type =
+      builtIn.getKotlinType(
+        typeStr = "float[]",
+        defaultValue = null,
+        moduleDescriptor = moduleDescriptor
+      )
+    assertThat(type)
+      .isEqualTo(builtIn.getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(builtIn.floatType))
   }
 
   @Test
   fun checkLong() {
-    val type = builtIn.getKotlinType(
-      typeStr = "long",
-      defaultValue = null,
-      moduleDescriptor = moduleDescriptor
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = "long",
+        defaultValue = null,
+        moduleDescriptor = moduleDescriptor
+      )
     assertThat(type).isEqualTo(builtIn.longType)
   }
 
   @Test
   fun checkLongArray() {
-    val type = builtIn.getKotlinType(
-      typeStr = "long[]",
-      defaultValue = null,
-      moduleDescriptor = moduleDescriptor
-    )
-    assertThat(type).isEqualTo(builtIn.getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(builtIn.longType))
+    val type =
+      builtIn.getKotlinType(
+        typeStr = "long[]",
+        defaultValue = null,
+        moduleDescriptor = moduleDescriptor
+      )
+    assertThat(type)
+      .isEqualTo(builtIn.getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(builtIn.longType))
   }
 
   @Test
   fun checkBoolean() {
-    val type = builtIn.getKotlinType(
-      typeStr = "boolean",
-      defaultValue = null,
-      moduleDescriptor = moduleDescriptor
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = "boolean",
+        defaultValue = null,
+        moduleDescriptor = moduleDescriptor
+      )
     assertThat(type).isEqualTo(builtIn.booleanType)
   }
 
   @Test
   fun checkBooleanArray() {
-    val type = builtIn.getKotlinType(
-      typeStr = "boolean[]",
-      defaultValue = null,
-      moduleDescriptor = moduleDescriptor
-    )
-    assertThat(type).isEqualTo(builtIn.getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(builtIn.booleanType))
+    val type =
+      builtIn.getKotlinType(
+        typeStr = "boolean[]",
+        defaultValue = null,
+        moduleDescriptor = moduleDescriptor
+      )
+    assertThat(type)
+      .isEqualTo(builtIn.getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(builtIn.booleanType))
   }
 
-  /**
-   *  Not primitive types regular check
-   */
+  /** Not primitive types regular check */
   @Test
   fun checkString() {
-    val type = builtIn.getKotlinType(
-      typeStr = "string",
-      defaultValue = null,
-      moduleDescriptor = moduleDescriptor
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = "string",
+        defaultValue = null,
+        moduleDescriptor = moduleDescriptor
+      )
     assertThat(type).isEqualTo(builtIn.stringType)
   }
 
   @Test
   fun checkStringArray() {
-    val type = builtIn.getKotlinType(
-      typeStr = "string[]",
-      defaultValue = null,
-      moduleDescriptor = moduleDescriptor
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = "string[]",
+        defaultValue = null,
+        moduleDescriptor = moduleDescriptor
+      )
     assertThat(type).isEqualTo(builtIn.getArrayType(Variance.INVARIANT, builtIn.stringType))
   }
 
   @Test
   fun checkResourceReference() {
-    val type = builtIn.getKotlinType(
-      typeStr = "reference",
-      defaultValue = null,
-      moduleDescriptor = moduleDescriptor
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = "reference",
+        defaultValue = null,
+        moduleDescriptor = moduleDescriptor
+      )
     assertThat(type).isEqualTo(builtIn.intType)
   }
 
   @Test
   fun checkCustomType() {
-    val type = builtIn.getKotlinType(
-      typeStr = "test.safeargs.MyCustomType",
-      defaultValue = null,
-      moduleDescriptor = moduleDescriptor
-    ) as ErrorType
+    val type =
+      builtIn.getKotlinType(
+        typeStr = "test.safeargs.MyCustomType",
+        defaultValue = null,
+        moduleDescriptor = moduleDescriptor
+      ) as ErrorType
 
     assertThat(type.nullability()).isEqualTo(TypeNullability.NOT_NULL)
     assertThat(type.debugMessage).isEqualTo("Unresolved type for test.safeargs.MyCustomType")
@@ -176,135 +185,139 @@
 
   @Test
   fun checkCustomTypeArray() {
-    val type = builtIn.getKotlinType(
-      typeStr = "test.safeargs.MyCustomType[]",
-      defaultValue = null,
-      moduleDescriptor = moduleDescriptor
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = "test.safeargs.MyCustomType[]",
+        defaultValue = null,
+        moduleDescriptor = moduleDescriptor
+      )
 
     val elementType = builtIn.getArrayElementType(type) as ErrorType
     assertThat(elementType.debugMessage).isEqualTo("Unresolved type for test.safeargs.MyCustomType")
   }
 
-  /**
-   *  Inferred types check
-   */
+  /** Inferred types check */
   @Test
   fun checkInferredInteger() {
-    val type = builtIn.getKotlinType(
-      typeStr = null,
-      defaultValue = "1",
-      moduleDescriptor = moduleDescriptor
-    )
+    val type =
+      builtIn.getKotlinType(typeStr = null, defaultValue = "1", moduleDescriptor = moduleDescriptor)
     assertThat(type).isEqualTo(builtIn.intType)
   }
 
   @Test
   fun checkInferredFloat() {
-    val type = builtIn.getKotlinType(
-      typeStr = null,
-      defaultValue = "1f",
-      moduleDescriptor = moduleDescriptor
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = null,
+        defaultValue = "1f",
+        moduleDescriptor = moduleDescriptor
+      )
     assertThat(type).isEqualTo(builtIn.floatType)
   }
 
   @Test
   fun checkInferredLong() {
-    val type = builtIn.getKotlinType(
-      typeStr = null,
-      defaultValue = "1L",
-      moduleDescriptor = moduleDescriptor
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = null,
+        defaultValue = "1L",
+        moduleDescriptor = moduleDescriptor
+      )
     assertThat(type).isEqualTo(builtIn.longType)
   }
 
   @Test
   fun checkInferredBoolean() {
-    val type = builtIn.getKotlinType(
-      typeStr = null,
-      defaultValue = "true",
-      moduleDescriptor = moduleDescriptor
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = null,
+        defaultValue = "true",
+        moduleDescriptor = moduleDescriptor
+      )
     assertThat(type).isEqualTo(builtIn.booleanType)
   }
 
   @Test
   fun checkInferredString() {
-    val type = builtIn.getKotlinType(
-      typeStr = null,
-      defaultValue = "someString",
-      moduleDescriptor = moduleDescriptor
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = null,
+        defaultValue = "someString",
+        moduleDescriptor = moduleDescriptor
+      )
     assertThat(type).isEqualTo(builtIn.stringType)
   }
 
   @Test
   fun checkInferredNullString() {
-    val type = builtIn.getKotlinType(
-      typeStr = null,
-      defaultValue = "@null",
-      moduleDescriptor = moduleDescriptor
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = null,
+        defaultValue = "@null",
+        moduleDescriptor = moduleDescriptor
+      )
 
     assertThat(type).isEqualTo(builtIn.stringType)
   }
 
   @Test
   fun checkInferredResourceReference() {
-    val type = builtIn.getKotlinType(
-      typeStr = null,
-      defaultValue = "@resourceType/resourceName",
-      moduleDescriptor = moduleDescriptor
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = null,
+        defaultValue = "@resourceType/resourceName",
+        moduleDescriptor = moduleDescriptor
+      )
     assertThat(type).isEqualTo(builtIn.intType)
   }
 
-  /**
-   *  Not primitive types nullability check
-   */
+  /** Not primitive types nullability check */
   @Test
   fun checkNullableString() {
-    val type = builtIn.getKotlinType(
-      typeStr = "string",
-      defaultValue = null,
-      moduleDescriptor = moduleDescriptor,
-      isNonNull = false
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = "string",
+        defaultValue = null,
+        moduleDescriptor = moduleDescriptor,
+        isNonNull = false
+      )
     assertThat(type.nullability()).isEqualTo(TypeNullability.NULLABLE)
   }
 
   @Test
   fun checkNullableCustomType() {
-    val type = builtIn.getKotlinType(
-      typeStr = "test.safeargs.MyCustomType",
-      defaultValue = "@null",
-      moduleDescriptor = moduleDescriptor,
-      isNonNull = false
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = "test.safeargs.MyCustomType",
+        defaultValue = "@null",
+        moduleDescriptor = moduleDescriptor,
+        isNonNull = false
+      )
 
     assertThat(type.nullability()).isEqualTo(TypeNullability.NULLABLE)
   }
 
   @Test
   fun checkNullableStringArray() {
-    val type = builtIn.getKotlinType(
-      typeStr = "string[]",
-      defaultValue = null,
-      moduleDescriptor = moduleDescriptor,
-      isNonNull = false
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = "string[]",
+        defaultValue = null,
+        moduleDescriptor = moduleDescriptor,
+        isNonNull = false
+      )
     assertThat(type.nullability()).isEqualTo(TypeNullability.NULLABLE)
   }
 
   @Test
   fun checkNullableCustomTypeArray() {
-    val type = builtIn.getKotlinType(
-      typeStr = "test.safeargs.MyCustomType[]",
-      defaultValue = null,
-      moduleDescriptor = moduleDescriptor,
-      isNonNull = false
-    )
+    val type =
+      builtIn.getKotlinType(
+        typeStr = "test.safeargs.MyCustomType[]",
+        defaultValue = null,
+        moduleDescriptor = moduleDescriptor,
+        isNonNull = false
+      )
     assertThat(type.nullability()).isEqualTo(TypeNullability.NULLABLE)
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgNavigationKtTest.kt b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgNavigationKtTest.kt
index 8ece8c3..e8acbb7f 100644
--- a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgNavigationKtTest.kt
+++ b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgNavigationKtTest.kt
@@ -38,14 +38,13 @@
 
 @RunsInEdt
 class SafeArgNavigationKtTest {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule(SafeArgsMode.KOTLIN)
+  @get:Rule val safeArgsRule = SafeArgsRule(SafeArgsMode.KOTLIN)
 
   @Test
   fun canNavigateToXmlTagFromArgsKtClass() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -69,33 +68,38 @@
                 app:argType="string" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
 
-    val safeArgProviderExtension = PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
-      it is SafeArgsKtPackageProviderExtension
-    }
+    val safeArgProviderExtension =
+      PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
+        it is SafeArgsKtPackageProviderExtension
+      }
 
     val traceMock: BindingTrace = MockitoKt.mock()
     val moduleSourceInfo = safeArgsRule.module.productionSourceInfo
     val moduleDescriptor = safeArgsRule.module.toDescriptor()
 
-    val fragmentProvider = safeArgProviderExtension.getPackageFragmentProvider(
-      project = safeArgsRule.project,
-      module = moduleDescriptor!!,
-      storageManager = LockBasedStorageManager.NO_LOCKS,
-      trace = traceMock,
-      moduleInfo = moduleSourceInfo,
-      lookupTracker = LookupTracker.DO_NOTHING
-    ) as SafeArgsSyntheticPackageProvider
+    val fragmentProvider =
+      safeArgProviderExtension.getPackageFragmentProvider(
+        project = safeArgsRule.project,
+        module = moduleDescriptor!!,
+        storageManager = LockBasedStorageManager.NO_LOCKS,
+        trace = traceMock,
+        moduleInfo = moduleSourceInfo,
+        lookupTracker = LookupTracker.DO_NOTHING
+      ) as SafeArgsSyntheticPackageProvider
 
-
-    val argsClassDescriptors: List<LightArgsKtClass> = fragmentProvider.getPackageFragments(FqName("test.safeargs"))
-      .flatMap { it.getMemberScope().getContributedDescriptors() }
-      .sortedWith(MemberComparator.INSTANCE)
-      .mapNotNull { it as? LightArgsKtClass }
+    val argsClassDescriptors: List<LightArgsKtClass> =
+      fragmentProvider
+        .getPackageFragments(FqName("test.safeargs"))
+        .flatMap { it.getMemberScope().getContributedDescriptors() }
+        .sortedWith(MemberComparator.INSTANCE)
+        .mapNotNull { it as? LightArgsKtClass }
 
     assertThat(argsClassDescriptors.size).isEqualTo(2)
     // check Fragment1Args class navigation
@@ -112,27 +116,33 @@
             is PropertyDescriptorImpl -> {
               val resolvedNavigationElement = descriptor.source.getPsi()!!
               assertThat(resolvedNavigationElement is XmlTag).isTrue()
-              assertThat((resolvedNavigationElement as XmlTag).text).isEqualTo(
-                """
+              assertThat((resolvedNavigationElement as XmlTag).text)
+                .isEqualTo(
+                  """
                 <argument
                         android:name="arg_one"
                         app:argType="string" />
-                """.trimIndent())
+                """
+                    .trimIndent()
+                )
               assertThat(descriptor.name.asString()).isEqualTo("argOne")
             }
             is SimpleFunctionDescriptorImpl -> {
               val resolvedNavigationElement = descriptor.source.getPsi()!!
               assertThat(resolvedNavigationElement is XmlTag).isTrue()
               if (descriptor.name.asString() == "component1") {
-                assertThat((resolvedNavigationElement as XmlTag).text).isEqualTo(
-                  """
+                assertThat((resolvedNavigationElement as XmlTag).text)
+                  .isEqualTo(
+                    """
                 <argument
                         android:name="arg_one"
                         app:argType="string" />
-                """.trimIndent())
-              }
-              else {
-                assertThat((resolvedNavigationElement as XmlTag).text).contains("id=\"@+id/fragment1\"")
+                """
+                      .trimIndent()
+                  )
+              } else {
+                assertThat((resolvedNavigationElement as XmlTag).text)
+                  .contains("id=\"@+id/fragment1\"")
               }
             }
           }
@@ -155,12 +165,15 @@
             is PropertyDescriptorImpl -> {
               val resolvedNavigationElement = descriptor.source.getPsi()!!
               assertThat(resolvedNavigationElement is XmlTag).isTrue()
-              assertThat((resolvedNavigationElement as XmlTag).text).isEqualTo(
-                """
+              assertThat((resolvedNavigationElement as XmlTag).text)
+                .isEqualTo(
+                  """
                 <argument
                         android:name="Arg_two"
                         app:argType="string" />
-                """.trimIndent())
+                """
+                    .trimIndent()
+                )
               assertThat(descriptor.name.asString()).isEqualTo("ArgTwo")
             }
             is SimpleFunctionDescriptorImpl -> {
@@ -168,15 +181,18 @@
               assertThat(resolvedNavigationElement is XmlTag).isTrue()
 
               if (descriptor.name.asString() == "component1") {
-                assertThat((resolvedNavigationElement as XmlTag).text).isEqualTo(
-                  """
+                assertThat((resolvedNavigationElement as XmlTag).text)
+                  .isEqualTo(
+                    """
                 <argument
                         android:name="Arg_two"
                         app:argType="string" />
-                """.trimIndent())
-              }
-              else {
-                assertThat((resolvedNavigationElement as XmlTag).text).contains("id=\"@+id/fragment2\"")
+                """
+                      .trimIndent()
+                  )
+              } else {
+                assertThat((resolvedNavigationElement as XmlTag).text)
+                  .contains("id=\"@+id/fragment2\"")
               }
             }
           }
@@ -188,7 +204,7 @@
   fun canNavigateToXmlTagFromDirectionsKtClass() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -229,32 +245,38 @@
 
           </navigation>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
 
-    val safeArgProviderExtension = PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
-      it is SafeArgsKtPackageProviderExtension
-    }
+    val safeArgProviderExtension =
+      PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
+        it is SafeArgsKtPackageProviderExtension
+      }
 
     val traceMock: BindingTrace = MockitoKt.mock()
     val moduleSourceInfo = safeArgsRule.module.productionSourceInfo
     val moduleDescriptor = safeArgsRule.module.toDescriptor()
 
-    val fragmentProvider = safeArgProviderExtension.getPackageFragmentProvider(
-      project = safeArgsRule.project,
-      module = moduleDescriptor!!,
-      storageManager = LockBasedStorageManager.NO_LOCKS,
-      trace = traceMock,
-      moduleInfo = moduleSourceInfo,
-      lookupTracker = LookupTracker.DO_NOTHING
-    ) as SafeArgsSyntheticPackageProvider
+    val fragmentProvider =
+      safeArgProviderExtension.getPackageFragmentProvider(
+        project = safeArgsRule.project,
+        module = moduleDescriptor!!,
+        storageManager = LockBasedStorageManager.NO_LOCKS,
+        trace = traceMock,
+        moduleInfo = moduleSourceInfo,
+        lookupTracker = LookupTracker.DO_NOTHING
+      ) as SafeArgsSyntheticPackageProvider
 
-    val directionsClassDescriptors: List<LightDirectionsKtClass> = fragmentProvider.getPackageFragments(FqName("test.safeargs"))
-      .flatMap { it.getMemberScope().getContributedDescriptors() }
-      .sortedWith(MemberComparator.INSTANCE)
-      .mapNotNull { it as? LightDirectionsKtClass }
+    val directionsClassDescriptors: List<LightDirectionsKtClass> =
+      fragmentProvider
+        .getPackageFragments(FqName("test.safeargs"))
+        .flatMap { it.getMemberScope().getContributedDescriptors() }
+        .sortedWith(MemberComparator.INSTANCE)
+        .mapNotNull { it as? LightDirectionsKtClass }
 
     assertThat(directionsClassDescriptors.size).isEqualTo(5)
 
@@ -264,30 +286,36 @@
       assertThat(navigationElement).isInstanceOf(XmlTag::class.java)
       assertThat((navigationElement as XmlTag).text).contains("id=\"@+id/fragment1\"")
 
-      it.companionObjectDescriptor
-        .unsubstitutedMemberScope
+      it.companionObjectDescriptor.unsubstitutedMemberScope
         .getContributedDescriptors()
         .sortedWith(MemberComparator.INSTANCE)
         .forEach { descriptor ->
-          val resolvedNavigationElement = (descriptor as SimpleFunctionDescriptorImpl).source.getPsi()!!
+          val resolvedNavigationElement =
+            (descriptor as SimpleFunctionDescriptorImpl).source.getPsi()!!
           assertThat(resolvedNavigationElement is XmlTag).isTrue()
 
           when (descriptor.name.toString()) {
             "actionFragment1ToFragment2" -> {
-              assertThat((resolvedNavigationElement as XmlTag).text).isEqualTo(
-                """
+              assertThat((resolvedNavigationElement as XmlTag).text)
+                .isEqualTo(
+                  """
                 <action
                       android:id="@+id/action_fragment1_to_fragment2"
                       app:destination="@id/fragment2" />
-                """.trimIndent())
+                """
+                    .trimIndent()
+                )
             }
             "actionFragment1ToFragment3" -> {
-              assertThat((resolvedNavigationElement as XmlTag).text).isEqualTo(
-                """
+              assertThat((resolvedNavigationElement as XmlTag).text)
+                .isEqualTo(
+                  """
                 <action
                       android:id="@+id/action_fragment1_to_fragment3"
                       app:destination="@id/fragment3" />
-                """.trimIndent())
+                """
+                    .trimIndent()
+                )
             }
           }
         }
@@ -299,19 +327,22 @@
       assertThat(navigationElement).isInstanceOf(XmlTag::class.java)
       assertThat((navigationElement as XmlTag).text).contains("id=\"@+id/fragment2\"")
 
-      it.companionObjectDescriptor
-        .unsubstitutedMemberScope
+      it.companionObjectDescriptor.unsubstitutedMemberScope
         .getContributedDescriptors()
         .sortedWith(MemberComparator.INSTANCE)
         .forEach { descriptor ->
-          val resolvedNavigationElement = (descriptor as SimpleFunctionDescriptorImpl).source.getPsi()!!
+          val resolvedNavigationElement =
+            (descriptor as SimpleFunctionDescriptorImpl).source.getPsi()!!
           assertThat(resolvedNavigationElement is XmlTag).isTrue()
-          assertThat((resolvedNavigationElement as XmlTag).text).isEqualTo(
-            """
+          assertThat((resolvedNavigationElement as XmlTag).text)
+            .isEqualTo(
+              """
                 <action
                     android:id="@+id/action_to_nested"
                     app:destination="@id/nested" />
-            """.trimIndent())
+            """
+                .trimIndent()
+            )
         }
     }
 
@@ -321,19 +352,22 @@
       assertThat(navigationElement).isInstanceOf(XmlTag::class.java)
       assertThat((navigationElement as XmlTag).text).contains("id=\"@+id/fragment3\"")
 
-      it.companionObjectDescriptor
-        .unsubstitutedMemberScope
+      it.companionObjectDescriptor.unsubstitutedMemberScope
         .getContributedDescriptors()
         .sortedWith(MemberComparator.INSTANCE)
         .forEach { descriptor ->
-          val resolvedNavigationElement = (descriptor as SimpleFunctionDescriptorImpl).source.getPsi()!!
+          val resolvedNavigationElement =
+            (descriptor as SimpleFunctionDescriptorImpl).source.getPsi()!!
           assertThat(resolvedNavigationElement is XmlTag).isTrue()
-          assertThat((resolvedNavigationElement as XmlTag).text).isEqualTo(
-            """
+          assertThat((resolvedNavigationElement as XmlTag).text)
+            .isEqualTo(
+              """
                 <action
                     android:id="@+id/action_to_nested"
                     app:destination="@id/nested" />
-            """.trimIndent())
+            """
+                .trimIndent()
+            )
         }
     }
 
@@ -343,19 +377,22 @@
       assertThat(navigationElement).isInstanceOf(XmlTag::class.java)
       assertThat((navigationElement as XmlTag).text).contains("id=\"@+id/main\"")
 
-      it.companionObjectDescriptor
-        .unsubstitutedMemberScope
+      it.companionObjectDescriptor.unsubstitutedMemberScope
         .getContributedDescriptors()
         .sortedWith(MemberComparator.INSTANCE)
         .forEach { descriptor ->
-          val resolvedNavigationElement = (descriptor as SimpleFunctionDescriptorImpl).source.getPsi()!!
+          val resolvedNavigationElement =
+            (descriptor as SimpleFunctionDescriptorImpl).source.getPsi()!!
           assertThat(resolvedNavigationElement is XmlTag).isTrue()
-          assertThat((resolvedNavigationElement as XmlTag).text).isEqualTo(
-            """
+          assertThat((resolvedNavigationElement as XmlTag).text)
+            .isEqualTo(
+              """
                 <action
                     android:id="@+id/action_to_nested"
                     app:destination="@id/nested" />
-            """.trimIndent())
+            """
+                .trimIndent()
+            )
         }
     }
 
@@ -365,20 +402,23 @@
       assertThat(navigationElement).isInstanceOf(XmlTag::class.java)
       assertThat((navigationElement as XmlTag).text).contains("id=\"@+id/nested\"")
 
-      it.companionObjectDescriptor
-        .unsubstitutedMemberScope
+      it.companionObjectDescriptor.unsubstitutedMemberScope
         .getContributedDescriptors()
         .sortedWith(MemberComparator.INSTANCE)
         .forEach { descriptor ->
-          val resolvedNavigationElement = (descriptor as SimpleFunctionDescriptorImpl).source.getPsi()!!
+          val resolvedNavigationElement =
+            (descriptor as SimpleFunctionDescriptorImpl).source.getPsi()!!
           assertThat(resolvedNavigationElement is XmlTag).isTrue()
-          assertThat((resolvedNavigationElement as XmlTag).text).isEqualTo(
-            """
+          assertThat((resolvedNavigationElement as XmlTag).text)
+            .isEqualTo(
+              """
                 <action
                     android:id="@+id/action_to_nested"
                     app:destination="@id/nested" />
-            """.trimIndent())
+            """
+                .trimIndent()
+            )
         }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsCacheTest.kt b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsCacheTest.kt
index 4ab3092..a0e8e16 100644
--- a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsCacheTest.kt
+++ b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsCacheTest.kt
@@ -27,14 +27,13 @@
 
 @RunsInEdt
 class SafeArgsCacheTest {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule(SafeArgsMode.NONE)
+  @get:Rule val safeArgsRule = SafeArgsRule(SafeArgsMode.NONE)
 
   @Test
   fun cachesAreClearedWhenPluginModeChanges() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/nav_main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -51,7 +50,9 @@
                 app:destination="@id/main" />
           </fragment>
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     val javaCache = SafeArgsCacheModuleService.getInstance(safeArgsRule.androidFacet)
     val ktCache = KtDescriptorCacheModuleService.getInstance(safeArgsRule.module)
@@ -73,4 +74,4 @@
     assertThat(javaCache.directions).isEmpty()
     assertThat(ktCache.getDescriptors(moduleDescriptor)).isEmpty()
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsKotlinPackageDescriptorTest.kt b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsKotlinPackageDescriptorTest.kt
index 2ed5f63..82fbb1a 100644
--- a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsKotlinPackageDescriptorTest.kt
+++ b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/SafeArgsKotlinPackageDescriptorTest.kt
@@ -33,17 +33,14 @@
 
 @RunsInEdt
 class SafeArgsKotlinPackageDescriptorTest {
-  @get:Rule
-  val safeArgsRule = SafeArgsRule(SafeArgsMode.KOTLIN)
+  @get:Rule val safeArgsRule = SafeArgsRule(SafeArgsMode.KOTLIN)
 
-  /**
-   * Check contributed args and directions class descriptors for single module case
-   */
+  /** Check contributed args and directions class descriptors for single module case */
   @Test
   fun checkContributorsOfPackage() {
     safeArgsRule.fixture.addFileToProject(
       "res/navigation/main.xml",
-      //language=XML
+      // language=XML
       """
         <?xml version="1.0" encoding="utf-8"?>
         <navigation xmlns:android="http://schemas.android.com/apk/res/android"
@@ -76,49 +73,57 @@
               android:id="@+id/action_main_to_fragment1"
               app:destination="@id/fragment1" />                      
         </navigation>
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
 
     // Initialize repository after creating resources, needed for codegen to work
     StudioResourceRepositoryManager.getInstance(safeArgsRule.androidFacet).moduleResources
 
-    val safeArgProviderExtension = PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
-      it is SafeArgsKtPackageProviderExtension
-    }
+    val safeArgProviderExtension =
+      PackageFragmentProviderExtension.getInstances(safeArgsRule.project).first {
+        it is SafeArgsKtPackageProviderExtension
+      }
 
     val traceMock: BindingTrace = mock()
     val moduleSourceInfo = safeArgsRule.module.productionSourceInfo
     val moduleDescriptor = safeArgsRule.module.toDescriptor()
 
-    val fragmentProvider = safeArgProviderExtension.getPackageFragmentProvider(
-      project = safeArgsRule.project,
-      module = moduleDescriptor!!,
-      storageManager = LockBasedStorageManager.NO_LOCKS,
-      trace = traceMock,
-      moduleInfo = moduleSourceInfo,
-      lookupTracker = LookupTracker.DO_NOTHING
-    ) as SafeArgsSyntheticPackageProvider
+    val fragmentProvider =
+      safeArgProviderExtension.getPackageFragmentProvider(
+        project = safeArgsRule.project,
+        module = moduleDescriptor!!,
+        storageManager = LockBasedStorageManager.NO_LOCKS,
+        trace = traceMock,
+        moduleInfo = moduleSourceInfo,
+        lookupTracker = LookupTracker.DO_NOTHING
+      ) as SafeArgsSyntheticPackageProvider
 
     // Check contents for Fragment1
-    val classesMetadata1 = fragmentProvider
-      .getPackageFragments(FqName("test.safeargs"))
-      .flatMap { it.getMemberScope().classesInScope() }
-      .sortedBy { it.fqcn }
+    val classesMetadata1 =
+      fragmentProvider
+        .getPackageFragments(FqName("test.safeargs"))
+        .flatMap { it.getMemberScope().classesInScope() }
+        .sortedBy { it.fqcn }
 
-    assertThat(classesMetadata1.map { it.toString() }).containsExactly(
-      "test.safeargs.Fragment1Args: androidx.navigation.NavArgs",
-      "test.safeargs.Fragment1Directions",
-      "test.safeargs.MainDirections"
-    )
+    assertThat(classesMetadata1.map { it.toString() })
+      .containsExactly(
+        "test.safeargs.Fragment1Args: androidx.navigation.NavArgs",
+        "test.safeargs.Fragment1Directions",
+        "test.safeargs.MainDirections"
+      )
 
     // Check contents for Fragment2
-    val classesMetadata2 = fragmentProvider
-      .getPackageFragments(FqName("test.safeargs.sub1"))
-      .flatMap { it.getMemberScope().classesInScope() }
-      .sortedBy { it.fqcn }
+    val classesMetadata2 =
+      fragmentProvider
+        .getPackageFragments(FqName("test.safeargs.sub1"))
+        .flatMap { it.getMemberScope().classesInScope() }
+        .sortedBy { it.fqcn }
 
-    assertThat(classesMetadata2.map { it.toString() }).containsExactly(
-      "test.safeargs.sub1.Fragment2Args: androidx.navigation.NavArgs",
-      "test.safeargs.sub1.Fragment2Directions"
-    )
+    assertThat(classesMetadata2.map { it.toString() })
+      .containsExactly(
+        "test.safeargs.sub1.Fragment2Args: androidx.navigation.NavArgs",
+        "test.safeargs.sub1.Fragment2Directions"
+      )
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/HighlightingTest.kt b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/HighlightingTest.kt
index 591412b..4f19028 100644
--- a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/HighlightingTest.kt
+++ b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/HighlightingTest.kt
@@ -27,21 +27,21 @@
 import com.intellij.testFramework.EdtRule
 import com.intellij.testFramework.RunsInEdt
 import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
+import java.io.File
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.rules.RuleChain
-import java.io.File
 
 @RunsInEdt
 class HighlightingTest {
   private val projectRule = AndroidGradleProjectRule()
 
   // The tests need to run on the EDT thread but we must initialize the project rule off of it
-  @get:Rule
-  val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
+  @get:Rule val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
 
-  private val fixture get() = projectRule.fixture as JavaCodeInsightTestFixture
+  private val fixture
+    get() = projectRule.fixture as JavaCodeInsightTestFixture
 
   @Before
   fun setUp() {
@@ -56,7 +56,9 @@
           // language=kotlin
           """
             class FooClass
-          """.trimIndent())
+          """
+            .trimIndent()
+        )
       }
     }
     NavigationResourcesModificationListener.ensureSubscribed(fixture.project)
@@ -66,7 +68,10 @@
   fun testDestructuringDeclaration() {
     projectRule.requestSyncAndWait()
 
-    val file = fixture.project.findAppModule().fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
+    val file =
+      fixture.project
+        .findAppModule()
+        .fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
     WriteCommandAction.runWriteCommandAction(fixture.project) {
       file!!.setText(
         // language=kotlin
@@ -77,11 +82,13 @@
                   val (arg1, arg2) = FirstFragmentArgs(1, 2)
               }
           }
-        """.trimIndent(),
-        fixture.project)
+        """
+          .trimIndent(),
+        fixture.project
+      )
     }
     fixture.configureFromExistingVirtualFile(file!!)
     val highlightInfos = fixture.doHighlighting(HighlightSeverity.ERROR)
     assertThat(highlightInfos).isEmpty()
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsGeneratedKotlinCodeMatchTest.kt b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsGeneratedKotlinCodeMatchTest.kt
index 27fcf29..0ab29ad 100644
--- a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsGeneratedKotlinCodeMatchTest.kt
+++ b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsGeneratedKotlinCodeMatchTest.kt
@@ -28,6 +28,7 @@
 import com.intellij.testFramework.EdtRule
 import com.intellij.testFramework.RunsInEdt
 import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
+import java.io.File
 import org.jetbrains.kotlin.descriptors.ClassDescriptor
 import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
 import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -54,40 +55,42 @@
 import org.junit.Test
 import org.junit.rules.RuleChain
 import org.junit.rules.TemporaryFolder
-import java.io.File
 
 @RunsInEdt
 class SafeArgsGeneratedKotlinCodeMatchTest {
   private val moduleName = "kotlinapp"
   private val projectRule = AndroidGradleProjectRule()
-  private val fixture get() = projectRule.fixture as JavaCodeInsightTestFixture
-  //TODO (b/162520387): Do not ignore these methods when testing.
-  private val IGNORED_METHODS = setOf("equals", "hashCode", "toString", "getActionId", "getArguments")
+  private val fixture
+    get() = projectRule.fixture as JavaCodeInsightTestFixture
+  // TODO (b/162520387): Do not ignore these methods when testing.
+  private val IGNORED_METHODS =
+    setOf("equals", "hashCode", "toString", "getActionId", "getArguments")
 
-  @get:Rule
-  val expect: Expect = Expect.create()
+  @get:Rule val expect: Expect = Expect.create()
 
-  @get:Rule
-  val temporaryFolder = TemporaryFolder()
+  @get:Rule val temporaryFolder = TemporaryFolder()
 
-
-  @get:Rule
-  val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
+  @get:Rule val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
 
   @Before
   fun initProject() {
     // to be able to change the project before import, we copy it into a temp folder
-    val testSrc = resolveWorkspacePath("tools/adt/idea/nav/safeargs/testData/projects/SafeArgsTestApp")
+    val testSrc =
+      resolveWorkspacePath("tools/adt/idea/nav/safeargs/testData/projects/SafeArgsTestApp")
     val container = temporaryFolder.newFile("TestApp")
     testSrc.toFile().copyRecursively(container, overwrite = true)
 
-    val settingsFile = container.resolve("settings.gradle").also {
-      assertWithMessage("settings file should exist").that(it.exists()).isTrue()
-    }
+    val settingsFile =
+      container.resolve("settings.gradle").also {
+        assertWithMessage("settings file should exist").that(it.exists()).isTrue()
+      }
     // update settings to only include the desired module
-    settingsFile.writeText("""
+    settingsFile.writeText(
+      """
       include ':$moduleName'
-    """.trimIndent())
+    """
+        .trimIndent()
+    )
 
     projectRule.fixture.testDataPath = temporaryFolder.root.absolutePath
     projectRule.load("TestApp") { projectRoot ->
@@ -99,7 +102,9 @@
           // language=kotlin
           """
             class FooClass
-          """.trimIndent())
+          """
+            .trimIndent()
+        )
       }
     }
 
@@ -114,9 +119,12 @@
     assertThat(assembleDebug.isBuildSuccessful).isTrue()
 
     LocalFileSystem.getInstance().refresh(false)
-    val codeOutDir = File(projectRule.project.basePath, "$moduleName/$PLUGIN_OUT_DIR").also {
-      assertWithMessage("should be able to find generated navigation code").that(it.exists()).isTrue()
-    }
+    val codeOutDir =
+      File(projectRule.project.basePath, "$moduleName/$PLUGIN_OUT_DIR").also {
+        assertWithMessage("should be able to find generated navigation code")
+          .that(it.exists())
+          .isTrue()
+      }
     // parse generated code
     val allGeneratedCode = listOf(codeOutDir).flatMap(::loadClasses).toSet()
     // delete generated code
@@ -127,103 +135,146 @@
     // now find all that code via other means (in memory codegen) and assert it is the same.
 
     val moduleDescriptor = projectRule.project.findAppModule().getMainModule().toDescriptor()!!
-    moduleDescriptor.resolveClassByFqName(FqName("com.example.safeargtest.Foo"), NoLookupLocation.WHEN_FIND_BY_FQNAME)
+    moduleDescriptor.resolveClassByFqName(
+      FqName("com.example.safeargtest.Foo"),
+      NoLookupLocation.WHEN_FIND_BY_FQNAME
+    )
 
     allGeneratedCode.forEach { generated ->
-
-      val classDescriptor = if (generated.isCompanionObject) {
-        moduleDescriptor.resolveClassByFqName(FqName(generated.qualifiedName).parent(), NoLookupLocation.WHEN_FIND_BY_FQNAME)
-          ?.companionObjectDescriptor?.toDescription()
-      }
-      else {
-        moduleDescriptor.resolveClassByFqName(FqName(generated.qualifiedName), NoLookupLocation.WHEN_FIND_BY_FQNAME)
-          ?.toDescription()
-      }
+      val classDescriptor =
+        if (generated.isCompanionObject) {
+          moduleDescriptor
+            .resolveClassByFqName(
+              FqName(generated.qualifiedName).parent(),
+              NoLookupLocation.WHEN_FIND_BY_FQNAME
+            )
+            ?.companionObjectDescriptor
+            ?.toDescription()
+        } else {
+          moduleDescriptor
+            .resolveClassByFqName(
+              FqName(generated.qualifiedName),
+              NoLookupLocation.WHEN_FIND_BY_FQNAME
+            )
+            ?.toDescription()
+        }
 
       expect.withMessage(generated.qualifiedName).that(classDescriptor).isNotNull()
       classDescriptor!!.let {
-        expect.withMessage(generated.qualifiedName).that(classDescriptor.qualifiedName).isEqualTo(generated.qualifiedName)
-        expect.withMessage(generated.qualifiedName).that(classDescriptor.constructor).isEqualTo(generated.constructor)
-        expect.withMessage(generated.qualifiedName).that(classDescriptor.methods).containsExactlyElementsIn(generated.methods)
-        expect.withMessage(generated.qualifiedName).that(classDescriptor.fields).containsExactlyElementsIn(generated.fields)
+        expect
+          .withMessage(generated.qualifiedName)
+          .that(classDescriptor.qualifiedName)
+          .isEqualTo(generated.qualifiedName)
+        expect
+          .withMessage(generated.qualifiedName)
+          .that(classDescriptor.constructor)
+          .isEqualTo(generated.constructor)
+        expect
+          .withMessage(generated.qualifiedName)
+          .that(classDescriptor.methods)
+          .containsExactlyElementsIn(generated.methods)
+        expect
+          .withMessage(generated.qualifiedName)
+          .that(classDescriptor.fields)
+          .containsExactlyElementsIn(generated.fields)
       }
     }
   }
 
   private fun loadClasses(classesOut: File): List<ClassDescription> {
-    return classesOut.walkTopDown().filter {
-      it.name.endsWith("kt")
-    }.toList().flatMap { generatedSourceFile ->
-      generatedSourceFile.loadClassesDescriptions()
-    }
+    return classesOut
+      .walkTopDown()
+      .filter { it.name.endsWith("kt") }
+      .toList()
+      .flatMap { generatedSourceFile -> generatedSourceFile.loadClassesDescriptions() }
   }
 
   private fun File.loadClassesDescriptions(): List<ClassDescription> {
     val descriptions = mutableListOf<ClassDescription>()
 
-    val virtual = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(this) ?: throw IllegalArgumentException("cannot find $this")
+    val virtual =
+      LocalFileSystem.getInstance().refreshAndFindFileByIoFile(this)
+        ?: throw IllegalArgumentException("cannot find $this")
     val psi = PsiManager.getInstance(projectRule.project).findFile(virtual)
     val uast = psi.toUElement()!!
-    uast.accept(object : AbstractUastVisitor() {
-      override fun visitClass(node: UClass): Boolean {
-        val descriptor = (node as KotlinUClass).sourcePsi?.descriptor as? ClassDescriptor
-        descriptor?.takeIf { it.visibility == DescriptorVisibilities.PUBLIC }?.toDescription()?.let {
-          descriptions.add(it)
+    uast.accept(
+      object : AbstractUastVisitor() {
+        override fun visitClass(node: UClass): Boolean {
+          val descriptor = (node as KotlinUClass).sourcePsi?.descriptor as? ClassDescriptor
+          descriptor
+            ?.takeIf { it.visibility == DescriptorVisibilities.PUBLIC }
+            ?.toDescription()
+            ?.let { descriptions.add(it) }
+          return super.visitClass(node)
         }
-        return super.visitClass(node)
       }
-    })
+    )
     return descriptions
   }
 
-  private fun ClassDescriptor.toDescription() = ClassDescription(
-    isCompanionObject = this.isCompanionObject,
-    qualifiedName = this.fqNameSafe.asString(),
-    constructor = (this.unsubstitutedPrimaryConstructor as? FunctionDescriptor)
-      ?.takeIf { it.visibility == DescriptorVisibilities.PUBLIC }
-      ?.toDescription(),
-    methods = this.unsubstitutedMemberScope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)
-      .asSequence()
-      .filterIsInstance<FunctionDescriptor>()
-      .filter { it.visibility == DescriptorVisibilities.PUBLIC }
-      .map { it.toDescription() }
-      .filter { !IGNORED_METHODS.contains(it.name) }
-      .sortedBy { it.name }
-      .toSet(),
-    fields = this.unsubstitutedMemberScope.getContributedDescriptors(DescriptorKindFilter.VARIABLES)
-      .asSequence()
-      .filterIsInstance<PropertyDescriptor>()
-      .map { it.toDescription() }
-      .sortedBy { it.name }
-      .toSet()
-  )
+  private fun ClassDescriptor.toDescription() =
+    ClassDescription(
+      isCompanionObject = this.isCompanionObject,
+      qualifiedName = this.fqNameSafe.asString(),
+      constructor =
+        (this.unsubstitutedPrimaryConstructor as? FunctionDescriptor)
+          ?.takeIf { it.visibility == DescriptorVisibilities.PUBLIC }
+          ?.toDescription(),
+      methods =
+        this.unsubstitutedMemberScope
+          .getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)
+          .asSequence()
+          .filterIsInstance<FunctionDescriptor>()
+          .filter { it.visibility == DescriptorVisibilities.PUBLIC }
+          .map { it.toDescription() }
+          .filter { !IGNORED_METHODS.contains(it.name) }
+          .sortedBy { it.name }
+          .toSet(),
+      fields =
+        this.unsubstitutedMemberScope
+          .getContributedDescriptors(DescriptorKindFilter.VARIABLES)
+          .asSequence()
+          .filterIsInstance<PropertyDescriptor>()
+          .map { it.toDescription() }
+          .sortedBy { it.name }
+          .toSet()
+    )
 
-  private fun FunctionDescriptor.toDescription() = MethodDescription(
-    name = this.name.asString(),
-    type = this.returnType?.toDescription(),
-    params = this.valueParameters.map { it.toDescription() }.toSet(),
-    modifiers = setOf(this.visibility.toString(), this.modality.toString())
-  )
+  private fun FunctionDescriptor.toDescription() =
+    MethodDescription(
+      name = this.name.asString(),
+      type = this.returnType?.toDescription(),
+      params = this.valueParameters.map { it.toDescription() }.toSet(),
+      modifiers = setOf(this.visibility.toString(), this.modality.toString())
+    )
 
-  private fun PropertyDescriptor.toDescription() = FieldDescription(
-    name = this.name.asString(),
-    type = this.type.toDescription(),
-    modifiers = setOf(this.visibility.toString(), this.modality.toString())
-  )
+  private fun PropertyDescriptor.toDescription() =
+    FieldDescription(
+      name = this.name.asString(),
+      type = this.type.toDescription(),
+      modifiers = setOf(this.visibility.toString(), this.modality.toString())
+    )
 
-  private fun ValueParameterDescriptor.toDescription() = ParamDescription(
-    name = this.name.asString(),
-    type = this.type.toDescription(),
-    modifiers = setOf(this.visibility.toString())
-  )
+  private fun ValueParameterDescriptor.toDescription() =
+    ParamDescription(
+      name = this.name.asString(),
+      type = this.type.toDescription(),
+      modifiers = setOf(this.visibility.toString())
+    )
 
   private fun KotlinType.toDescription(): String {
     val type = if (this.isMarkedNullable) this.makeNullable() else this
     return when (type) {
-      // Note: References to dependencies are not working when generating sources, e.g. NavDirections, but they are
-      // not critical to verifying safe args behavior, so we're OK simply peeling the class name out of the error type
+      // Note: References to dependencies are not working when generating sources, e.g.
+      // NavDirections, but they are
+      // not critical to verifying safe args behavior, so we're OK simply peeling the class name out
+      // of the error type
       // for now.
-      is ErrorType -> type.debugMessage.removePrefix("Unresolved type for ").substringAfterLast('.').substringAfterLast('$')
+      is ErrorType ->
+        type.debugMessage
+          .removePrefix("Unresolved type for ")
+          .substringAfterLast('.')
+          .substringAfterLast('$')
       else -> type.fqName!!.shortName().asString().substringAfterLast('$')
     }
   }
@@ -240,20 +291,23 @@
     val name: String,
     val type: String?,
     val modifiers: Set<String>,
-    val params: Set<ParamDescription>)
+    val params: Set<ParamDescription>
+  )
 
   private data class FieldDescription(
     val name: String,
     val type: String,
-    val modifiers: Set<String>)
+    val modifiers: Set<String>
+  )
 
   private data class ParamDescription(
     val name: String,
     val type: String,
-    val modifiers: Set<String>)
+    val modifiers: Set<String>
+  )
 
   companion object {
     const val PLUGIN_OUT_DIR = "build/generated/source/navigation-args/debug"
     const val GENERATE_TASK = "generateSafeArgsDebug"
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsIconsRenderingTest.kt b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsIconsRenderingTest.kt
index 053a281..fc29ac85 100644
--- a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsIconsRenderingTest.kt
+++ b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsIconsRenderingTest.kt
@@ -30,22 +30,22 @@
 import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
 import com.intellij.ui.IconManager
 import com.intellij.ui.PlatformIcons
+import java.io.File
 import org.jetbrains.kotlin.idea.KotlinIcons
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.rules.RuleChain
-import java.io.File
 
 @RunsInEdt
 class SafeArgsIconsRenderingTest {
   private val projectRule = AndroidGradleProjectRule()
 
   // The tests need to run on the EDT thread but we must initialize the project rule off of it
-  @get:Rule
-  val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
+  @get:Rule val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
 
-  private val fixture get() = projectRule.fixture as JavaCodeInsightTestFixture
+  private val fixture
+    get() = projectRule.fixture as JavaCodeInsightTestFixture
 
   @Before
   fun setUp() {
@@ -61,7 +61,9 @@
           """
             package com.example.myapplication
             class FooClass
-          """.trimIndent())
+          """
+            .trimIndent()
+        )
       }
     }
     NavigationResourcesModificationListener.ensureSubscribed(fixture.project)
@@ -71,11 +73,14 @@
   fun testClassIcons() {
     projectRule.requestSyncAndWait()
 
-    val file = fixture.project.findAppModule().fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
+    val file =
+      fixture.project
+        .findAppModule()
+        .fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
     WriteCommandAction.runWriteCommandAction(fixture.project) {
       file!!.replaceWithSaving(
         "class FooClass",
-        //language=kotlin
+        // language=kotlin
         """
         class FooClass {
             fun myTest() {
@@ -83,8 +88,10 @@
                 val directionsClass = 
             }
         }
-      """.trimIndent(),
-        fixture.project)
+      """
+          .trimIndent(),
+        fixture.project
+      )
     }
 
     fixture.openFileInEditor(file!!)
@@ -93,32 +100,39 @@
     fixture.moveCaret("val argsClass = |")
     fixture.type("Args")
     fixture.completeBasic()
-    var icons = fixture.lookupElements!!
-      .filter { it.lookupString.endsWith("FragmentArgs") }
-      .map { DefaultLookupItemRenderer.getRawIcon(it) }
-      .toSet()
-    assertThat(icons).containsExactly(IconManager.getInstance().getPlatformIcon(PlatformIcons.Class))
+    var icons =
+      fixture.lookupElements!!
+        .filter { it.lookupString.endsWith("FragmentArgs") }
+        .map { DefaultLookupItemRenderer.getRawIcon(it) }
+        .toSet()
+    assertThat(icons)
+      .containsExactly(IconManager.getInstance().getPlatformIcon(PlatformIcons.Class))
 
     // check directions classes
     fixture.moveCaret("val directionsClass = |")
     fixture.type("Directions")
     fixture.completeBasic()
-    icons = fixture.lookupElements!!
-      .filter { it.lookupString.endsWith("FragmentDirections") }
-      .mapNotNull { DefaultLookupItemRenderer.getRawIcon(it) }
-      .toSet()
-    assertThat(icons).containsExactly(IconManager.getInstance().getPlatformIcon(PlatformIcons.Class))
+    icons =
+      fixture.lookupElements!!
+        .filter { it.lookupString.endsWith("FragmentDirections") }
+        .mapNotNull { DefaultLookupItemRenderer.getRawIcon(it) }
+        .toSet()
+    assertThat(icons)
+      .containsExactly(IconManager.getInstance().getPlatformIcon(PlatformIcons.Class))
   }
 
   @Test
   fun testMethodAndPropertyIcons() {
     projectRule.requestSyncAndWait()
 
-    val file = fixture.project.findAppModule().fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
+    val file =
+      fixture.project
+        .findAppModule()
+        .fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
     WriteCommandAction.runWriteCommandAction(fixture.project) {
       file!!.replaceWithSaving(
         "class FooClass",
-        //language=kotlin
+        // language=kotlin
         """
         class FooClass {
             fun myTest() {
@@ -129,8 +143,10 @@
                 val directionsClass2 = SecondFragmentDirections().
             }
         }
-      """.trimIndent(),
-        fixture.project)
+      """
+          .trimIndent(),
+        fixture.project
+      )
     }
 
     fixture.openFileInEditor(file!!)
@@ -138,33 +154,43 @@
     // check static method from args class
     fixture.moveCaret("val argsClass1 = SecondFragmentArgs.|")
     fixture.completeBasic()
-    var icons = fixture.lookupElements!!
-      .map { it.lookupString to DefaultLookupItemRenderer.getRawIcon(it) }
-      .toSet()
-    assertThat(icons).contains("fromBundle" to IconManager.getInstance().getPlatformIcon(PlatformIcons.Function))
+    var icons =
+      fixture.lookupElements!!
+        .map { it.lookupString to DefaultLookupItemRenderer.getRawIcon(it) }
+        .toSet()
+    assertThat(icons)
+      .contains("fromBundle" to IconManager.getInstance().getPlatformIcon(PlatformIcons.Function))
 
     // check static method from directions class
     fixture.moveCaret("val directionsClass1 = SecondFragmentDirections.|")
     fixture.completeBasic()
-    icons = fixture.lookupElements!!
-      .mapNotNull { it.lookupString to DefaultLookupItemRenderer.getRawIcon(it) }
-      .toSet()
-    assertThat(icons).contains("actionSecondFragmentToFirstFragment" to IconManager.getInstance().getPlatformIcon(PlatformIcons.Function))
+    icons =
+      fixture.lookupElements!!
+        .mapNotNull { it.lookupString to DefaultLookupItemRenderer.getRawIcon(it) }
+        .toSet()
+    assertThat(icons)
+      .contains(
+        "actionSecondFragmentToFirstFragment" to
+          IconManager.getInstance().getPlatformIcon(PlatformIcons.Function)
+      )
 
     // check methods from args class
     fixture.moveCaret("val argsClass2 = SecondFragmentArgs().|")
 
     fixture.completeBasic()
-    icons = fixture.lookupElements!!
-      .map { it.lookupString to DefaultLookupItemRenderer.getRawIcon(it) }
-      .toSet()
-    assertThat(icons).containsAllOf(
-      // componentN() functions of data class are filtered out when collecting variants during completions.
-      "arg1" to KotlinIcons.FIELD_VAL,
-      "copy" to IconManager.getInstance().getPlatformIcon(PlatformIcons.Function),
-      "toBundle" to IconManager.getInstance().getPlatformIcon(PlatformIcons.Function)
-    )
+    icons =
+      fixture.lookupElements!!
+        .map { it.lookupString to DefaultLookupItemRenderer.getRawIcon(it) }
+        .toSet()
+    assertThat(icons)
+      .containsAllOf(
+        // componentN() functions of data class are filtered out when collecting variants during
+        // completions.
+        "arg1" to KotlinIcons.FIELD_VAL,
+        "copy" to IconManager.getInstance().getPlatformIcon(PlatformIcons.Function),
+        "toBundle" to IconManager.getInstance().getPlatformIcon(PlatformIcons.Function)
+      )
 
     // directions class only has companion object
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsImportKtResolverTest.kt b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsImportKtResolverTest.kt
index 3a3f67e..888ed69 100644
--- a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsImportKtResolverTest.kt
+++ b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsImportKtResolverTest.kt
@@ -27,21 +27,21 @@
 import com.intellij.testFramework.EdtRule
 import com.intellij.testFramework.RunsInEdt
 import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
+import java.io.File
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.rules.RuleChain
-import java.io.File
 
 @RunsInEdt
 class SafeArgsImportKtResolverTest {
   private val projectRule = AndroidGradleProjectRule()
 
   // The tests need to run on the EDT thread but we must initialize the project rule off of it
-  @get:Rule
-  val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
+  @get:Rule val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
 
-  private val fixture get() = projectRule.fixture as JavaCodeInsightTestFixture
+  private val fixture
+    get() = projectRule.fixture as JavaCodeInsightTestFixture
 
   @Before
   fun setUp() {
@@ -61,7 +61,9 @@
                     val argsClass2 = FirstFragmentArgs().
                 }
             }
-          """.trimIndent())
+          """
+            .trimIndent()
+        )
       }
     }
     NavigationResourcesModificationListener.ensureSubscribed(fixture.project)
@@ -71,12 +73,15 @@
   fun testImportFixWithSingleSuggestion() {
     projectRule.requestSyncAndWait()
 
-    val file = fixture.project.findAppModule().fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
+    val file =
+      fixture.project
+        .findAppModule()
+        .fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
     fixture.configureFromExistingVirtualFile(file!!)
 
     // Before auto import fix
-    val unresolvedReferences = fixture.doHighlighting()
-      .filter { it.description?.contains("[UNRESOLVED_REFERENCE]") == true }
+    val unresolvedReferences =
+      fixture.doHighlighting().filter { it.description?.contains("[UNRESOLVED_REFERENCE]") == true }
 
     assertThat(unresolvedReferences).hasSize(2)
 
@@ -97,17 +102,22 @@
                 val argsClass2 = FirstFragmentArgs().
             }
         }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
   }
 
   @Test
   fun testImportFixWithAmbiguities() {
     projectRule.requestSyncAndWait()
 
-    val file = fixture.project.findAppModule().fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
+    val file =
+      fixture.project
+        .findAppModule()
+        .fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
     WriteCommandAction.runWriteCommandAction(fixture.project) {
       file!!.setText(
-        //language=kotlin
+        // language=kotlin
         """
           class FooClass {
               fun myTest() {
@@ -115,14 +125,16 @@
                   val argsClass2 = SecondFragmentArgs().
               }
           }
-        """.trimIndent(),
-        fixture.project)
+        """
+          .trimIndent(),
+        fixture.project
+      )
     }
     fixture.configureFromExistingVirtualFile(file!!)
 
     // Before auto import fix
-    val unresolvedReferences = fixture.doHighlighting()
-      .filter { it.description?.contains("[UNRESOLVED_REFERENCE]") == true }
+    val unresolvedReferences =
+      fixture.doHighlighting().filter { it.description?.contains("[UNRESOLVED_REFERENCE]") == true }
 
     assertThat(unresolvedReferences).hasSize(2)
 
@@ -144,17 +156,22 @@
                 val argsClass2 = SecondFragmentArgs().
             }
         }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
   }
 
   @Test
   fun testImportFixForCompanionFunctions() {
     projectRule.requestSyncAndWait()
 
-    val file = fixture.project.findAppModule().fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
+    val file =
+      fixture.project
+        .findAppModule()
+        .fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
     WriteCommandAction.runWriteCommandAction(fixture.project) {
       file!!.setText(
-        //language=kotlin
+        // language=kotlin
         """
           package com.example.myapplication
 
@@ -163,14 +180,16 @@
                   val argsClass1 = from${caret}Bundle()
               }
           }
-        """.trimIndent(),
-        fixture.project)
+        """
+          .trimIndent(),
+        fixture.project
+      )
     }
     fixture.configureFromExistingVirtualFile(file!!)
 
     // Before auto import fix
-    val unresolvedReferences = fixture.doHighlighting()
-      .filter { it.description?.contains("[UNRESOLVED_REFERENCE]") == true }
+    val unresolvedReferences =
+      fixture.doHighlighting().filter { it.description?.contains("[UNRESOLVED_REFERENCE]") == true }
 
     assertThat(unresolvedReferences).hasSize(1)
 
@@ -189,6 +208,8 @@
                 val argsClass1 = from${caret}Bundle()
             }
         }
-      """.trimIndent())
+      """
+        .trimIndent()
+    )
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsKtCompletionContributorTest.kt b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsKtCompletionContributorTest.kt
index 2d394c1..632ad8f 100644
--- a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsKtCompletionContributorTest.kt
+++ b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsKtCompletionContributorTest.kt
@@ -28,21 +28,21 @@
 import com.intellij.testFramework.EdtRule
 import com.intellij.testFramework.RunsInEdt
 import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
+import java.io.File
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.rules.RuleChain
-import java.io.File
 
 @RunsInEdt
 class SafeArgsKtCompletionContributorTest {
   private val projectRule = AndroidGradleProjectRule()
 
   // The tests need to run on the EDT thread but we must initialize the project rule off of it
-  @get:Rule
-  val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
+  @get:Rule val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
 
-  private val fixture get() = projectRule.fixture as JavaCodeInsightTestFixture
+  private val fixture
+    get() = projectRule.fixture as JavaCodeInsightTestFixture
 
   @Before
   fun setUp() {
@@ -58,7 +58,9 @@
           """
             package com.example.myapplication
             class FooClass
-          """.trimIndent())
+          """
+            .trimIndent()
+        )
       }
     }
 
@@ -68,18 +70,21 @@
   /**
    * Check args and directions classes shown up in the completions
    *
-   * Test Project structure:
-   * base app module(safe arg mode is on) --> lib dep module(safe arg mode is on)
+   * Test Project structure: base app module(safe arg mode is on) --> lib dep module(safe arg mode
+   * is on)
    */
   @Test
   fun testBasicCompletion() {
     projectRule.requestSyncAndWait()
 
-    val file = fixture.project.findAppModule().fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
+    val file =
+      fixture.project
+        .findAppModule()
+        .fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
     WriteCommandAction.runWriteCommandAction(fixture.project) {
       file!!.replaceWithSaving(
         "class FooClass",
-        //language=kotlin
+        // language=kotlin
         """
         class FooClass {
             fun myTest() {
@@ -88,8 +93,10 @@
                 val generatedClass = 
             }
         }
-      """.trimIndent(),
-        fixture.project)
+      """
+          .trimIndent(),
+        fixture.project
+      )
     }
 
     fixture.openFileInEditor(file!!)
@@ -98,73 +105,86 @@
     fixture.moveCaret("val argsClass = |")
     fixture.type("Args")
     fixture.completeBasic()
-    val argsElements = fixture.lookupElements!!
-      .map {
-        val presentation = LookupElementPresentation()
-        it.renderElement(presentation)
-        presentation
-      }
-      .map { it.itemText + " " + it.tailText }
+    val argsElements =
+      fixture.lookupElements!!
+        .map {
+          val presentation = LookupElementPresentation()
+          it.renderElement(presentation)
+          presentation
+        }
+        .map { it.itemText + " " + it.tailText }
 
-    assertThat(argsElements).containsAllOf(
-      "FirstFragmentArgs  (com.example.mylibrary)",
-      "SecondFragmentArgs  (com.example.myapplication)",
-      "SecondFragmentArgs  (com.example.mylibrary)")
+    assertThat(argsElements)
+      .containsAllOf(
+        "FirstFragmentArgs  (com.example.mylibrary)",
+        "SecondFragmentArgs  (com.example.myapplication)",
+        "SecondFragmentArgs  (com.example.mylibrary)"
+      )
 
     // check directions classes
     fixture.moveCaret("val directionsClass = |")
     fixture.type("Directions")
     fixture.completeBasic()
-    val directionsElements = fixture.lookupElements!!
-      .map {
-        val presentation = LookupElementPresentation()
-        it.renderElement(presentation)
-        presentation
-      }
-      .map { it.itemText + " " + it.tailText }
+    val directionsElements =
+      fixture.lookupElements!!
+        .map {
+          val presentation = LookupElementPresentation()
+          it.renderElement(presentation)
+          presentation
+        }
+        .map { it.itemText + " " + it.tailText }
 
-    assertThat(directionsElements).containsAllOf(
-      "SecondFragmentDirections  (com.example.myapplication)",
-      "FirstFragmentDirections  (com.example.mylibrary)",
-      "SecondFragmentDirections  (com.example.mylibrary)")
-
+    assertThat(directionsElements)
+      .containsAllOf(
+        "SecondFragmentDirections  (com.example.myapplication)",
+        "FirstFragmentDirections  (com.example.mylibrary)",
+        "SecondFragmentDirections  (com.example.mylibrary)"
+      )
 
     // check all safe args classes
     fixture.moveCaret("val generatedClass = |")
     fixture.completeBasic()
-    val allElements = fixture.lookupElements!!
-      .map {
-        val presentation = LookupElementPresentation()
-        it.renderElement(presentation)
-        presentation
-      }
-      .filter { it.itemText!!.endsWith("Args") || it.itemText!!.endsWith("Directions") }
-      .map { it.itemText + " " + it.tailText }
+    val allElements =
+      fixture.lookupElements!!
+        .map {
+          val presentation = LookupElementPresentation()
+          it.renderElement(presentation)
+          presentation
+        }
+        .filter { it.itemText!!.endsWith("Args") || it.itemText!!.endsWith("Directions") }
+        .map { it.itemText + " " + it.tailText }
 
-    assertThat(allElements).containsAllOf(
-      "FirstFragmentArgs  (com.example.mylibrary)",
-      "SecondFragmentArgs  (com.example.myapplication)",
-      "SecondFragmentArgs  (com.example.mylibrary)",
-      "SecondFragmentDirections  (com.example.myapplication)",
-      "FirstFragmentDirections  (com.example.mylibrary)",
-      "SecondFragmentDirections  (com.example.mylibrary)")
+    assertThat(allElements)
+      .containsAllOf(
+        "FirstFragmentArgs  (com.example.mylibrary)",
+        "SecondFragmentArgs  (com.example.myapplication)",
+        "SecondFragmentArgs  (com.example.mylibrary)",
+        "SecondFragmentDirections  (com.example.myapplication)",
+        "FirstFragmentDirections  (com.example.mylibrary)",
+        "SecondFragmentDirections  (com.example.mylibrary)"
+      )
   }
 
   @Test
   fun testCompletionInImports() {
     projectRule.requestSyncAndWait()
 
-    val file = fixture.project.findAppModule().fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
+    val file =
+      fixture.project
+        .findAppModule()
+        .fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
     WriteCommandAction.runWriteCommandAction(fixture.project) {
       file!!.replaceWithSaving(
         "class FooClass",
-        //language=kotlin
+        // language=kotlin
         """
         import com.
         import com.example.mylibrary.
         class FooClass
-      """.trimIndent(),
-        fixture.project)
+      """
+          .trimIndent(),
+        fixture.project
+      )
     }
 
     fixture.openFileInEditor(file!!)
@@ -185,38 +205,46 @@
     // (Just for sanity check, completions are not provided by [SafeArgsKtCompletionContributor])
     fixture.moveCaret("import com.example.mylibrary.|")
     fixture.completeBasic()
-    val allElements = fixture.lookupElements!!
-      .map {
-        val presentation = LookupElementPresentation()
-        it.renderElement(presentation)
-        presentation
-      }
-      .filter { it.itemText!!.endsWith("Args") || it.itemText!!.endsWith("Directions") }
-      .map { it.itemText + " " + it.tailText }
+    val allElements =
+      fixture.lookupElements!!
+        .map {
+          val presentation = LookupElementPresentation()
+          it.renderElement(presentation)
+          presentation
+        }
+        .filter { it.itemText!!.endsWith("Args") || it.itemText!!.endsWith("Directions") }
+        .map { it.itemText + " " + it.tailText }
 
-    assertThat(allElements).containsAllOf(
-      "FirstFragmentArgs  (com.example.mylibrary)",
-      "FirstFragmentDirections  (com.example.mylibrary)",
-      "SecondFragmentArgs  (com.example.mylibrary)",
-      "SecondFragmentDirections  (com.example.mylibrary)")
+    assertThat(allElements)
+      .containsAllOf(
+        "FirstFragmentArgs  (com.example.mylibrary)",
+        "FirstFragmentDirections  (com.example.mylibrary)",
+        "SecondFragmentArgs  (com.example.mylibrary)",
+        "SecondFragmentDirections  (com.example.mylibrary)"
+      )
   }
 
   @Test
   fun testCompletionWithReceiver() {
     projectRule.requestSyncAndWait()
 
-    val file = fixture.project.findAppModule().fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
+    val file =
+      fixture.project
+        .findAppModule()
+        .fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
     WriteCommandAction.runWriteCommandAction(fixture.project) {
       file!!.replaceWithSaving(
         "class FooClass",
-        //language=kotlin
+        // language=kotlin
         """
         class FooClass {
           val a = com.
           val b = com.example.mylibrary.
         }
-      """.trimIndent(),
-        fixture.project)
+      """
+          .trimIndent(),
+        fixture.project
+      )
     }
 
     fixture.openFileInEditor(file!!)
@@ -237,19 +265,22 @@
     // (Just for sanity check, completions are not provided by [SafeArgsKtCompletionContributor])
     fixture.moveCaret("com.example.mylibrary.|")
     fixture.completeBasic()
-    val allElements = fixture.lookupElements!!
-      .map {
-        val presentation = LookupElementPresentation()
-        it.renderElement(presentation)
-        presentation
-      }
-      .filter { it.itemText!!.endsWith("Args") || it.itemText!!.endsWith("Directions") }
-      .map { it.itemText + " " + it.tailText }
+    val allElements =
+      fixture.lookupElements!!
+        .map {
+          val presentation = LookupElementPresentation()
+          it.renderElement(presentation)
+          presentation
+        }
+        .filter { it.itemText!!.endsWith("Args") || it.itemText!!.endsWith("Directions") }
+        .map { it.itemText + " " + it.tailText }
 
-    assertThat(allElements).containsAllOf(
-      "FirstFragmentArgs  (com.example.mylibrary)",
-      "FirstFragmentDirections  (com.example.mylibrary)",
-      "SecondFragmentArgs  (com.example.mylibrary)",
-      "SecondFragmentDirections  (com.example.mylibrary)")
+    assertThat(allElements)
+      .containsAllOf(
+        "FirstFragmentArgs  (com.example.mylibrary)",
+        "FirstFragmentDirections  (com.example.mylibrary)",
+        "SecondFragmentArgs  (com.example.mylibrary)",
+        "SecondFragmentDirections  (com.example.mylibrary)"
+      )
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsKtFindingUsageTest.kt b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsKtFindingUsageTest.kt
index a9c6a46..3267f87 100644
--- a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsKtFindingUsageTest.kt
+++ b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsKtFindingUsageTest.kt
@@ -29,21 +29,21 @@
 import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
 import com.intellij.usages.PsiElementUsageTarget
 import com.intellij.usages.UsageTargetUtil
+import java.io.File
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import org.junit.rules.RuleChain
-import java.io.File
 
 @RunsInEdt
 class SafeArgsKtFindingUsageTest {
   private val projectRule = AndroidGradleProjectRule()
 
   // The tests need to run on the EDT thread but we must initialize the project rule off of it
-  @get:Rule
-  val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
+  @get:Rule val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
 
-  private val fixture get() = projectRule.fixture as JavaCodeInsightTestFixture
+  private val fixture
+    get() = projectRule.fixture as JavaCodeInsightTestFixture
 
   @Before
   fun setUp() {
@@ -67,7 +67,9 @@
                     val argsClass2 = FirstFragmentArgs().
                 }
             }
-          """.trimIndent())
+          """
+            .trimIndent()
+        )
       }
     }
     NavigationResourcesModificationListener.ensureSubscribed(fixture.project)
@@ -78,11 +80,16 @@
     projectRule.requestSyncAndWait()
 
     val appModuleMain = fixture.project.findAppModule().getMainModule()
-    val file = appModuleMain.fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
+    val file =
+      appModuleMain.fileUnderGradleRoot("src/main/java/com/example/myapplication/FooClass.kt")
     fixture.configureFromExistingVirtualFile(file!!)
-    val targets = UsageTargetUtil.findUsageTargets { (fixture.editor as EditorEx).dataContext.getData(it) }
-    val presentation = fixture.getUsageViewTreeTextRepresentation((targets.first() as PsiElementUsageTarget).element)
-    assertThat(presentation).isEqualTo("""
+    val targets =
+      UsageTargetUtil.findUsageTargets { (fixture.editor as EditorEx).dataContext.getData(it) }
+    val presentation =
+      fixture.getUsageViewTreeTextRepresentation((targets.first() as PsiElementUsageTarget).element)
+    assertThat(presentation)
+      .isEqualTo(
+        """
       <root> (3)
        XML tag
         <FirstFragmentArgs> of file nav_graph.xml
@@ -107,6 +114,8 @@
            FooClass.kt (1)
             3import com.example.mylibrary.FirstFragmentArgs
 
-    """.trimIndent())
+    """
+          .trimIndent()
+      )
   }
-}
\ No newline at end of file
+}
diff --git a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsKtPackageDescriptorTestMultiKtModules.kt b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsKtPackageDescriptorTestMultiKtModules.kt
index 6bc3f79..dd63861 100644
--- a/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsKtPackageDescriptorTestMultiKtModules.kt
+++ b/nav/safeargs/tests/k1/src/com/android/tools/idea/nav/safeargs/kotlin/k1/gradle/SafeArgsKtPackageDescriptorTestMultiKtModules.kt
@@ -15,11 +15,9 @@
  */
 package com.android.tools.idea.nav.safeargs.kotlin.gradle
 
-import com.android.flags.junit.FlagRule
-import com.android.tools.idea.flags.StudioFlags
 import com.android.tools.idea.nav.safeargs.TestDataPaths
-import com.android.tools.idea.nav.safeargs.project.NavigationResourcesModificationListener
 import com.android.tools.idea.nav.safeargs.kotlin.k1.classesInScope
+import com.android.tools.idea.nav.safeargs.project.NavigationResourcesModificationListener
 import com.android.tools.idea.projectsystem.getMainModule
 import com.android.tools.idea.testing.AndroidGradleProjectRule
 import com.android.tools.idea.testing.findAppModule
@@ -40,10 +38,10 @@
   private val projectRule = AndroidGradleProjectRule()
 
   // The tests need to run on the EDT thread but we must initialize the project rule off of it
-  @get:Rule
-  val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
+  @get:Rule val ruleChain = RuleChain.outerRule(projectRule).around(EdtRule())!!
 
-  private val fixture get() = projectRule.fixture as JavaCodeInsightTestFixture
+  private val fixture
+    get() = projectRule.fixture as JavaCodeInsightTestFixture
 
   @Before
   fun setUp() {
@@ -53,11 +51,11 @@
   }
 
   /**
-   * Check contributed descriptors for base app and library module by providing fully qualified package names
+   * Check contributed descriptors for base app and library module by providing fully qualified
+   * package names
    *
-   * Test Project structure:
-   * -base app module(safe arg mode is on) --> lib dep module(safe arg mode is on)
-   * -excluded lib module(safe arg mode is on)
+   * Test Project structure: -base app module(safe arg mode is on) --> lib dep module(safe arg mode
+   * is on) -excluded lib module(safe arg mode is on)
    */
   @Test
   fun multiModuleTest() {
@@ -67,56 +65,64 @@
     val appModule = fixture.project.findAppModule().getMainModule()
     val appModuleDescriptor = appModule.toDescriptor()
 
-    val classesMetadataAppPackageInApp = appModuleDescriptor!!
-      .getPackage(FqName("com.example.myapplication"))
-      .memberScope
-      .classesInScope { name -> name.endsWith("Args") || name.endsWith("Directions") }
+    val classesMetadataAppPackageInApp =
+      appModuleDescriptor!!
+        .getPackage(FqName("com.example.myapplication"))
+        .memberScope
+        .classesInScope { name -> name.endsWith("Args") || name.endsWith("Directions") }
 
-    assertThat(classesMetadataAppPackageInApp.map { it.fqcn to it.file }).containsExactly(
-      "com.example.myapplication.SecondFragmentArgs" to "nav_graph.xml",
-      "com.example.myapplication.SecondFragmentDirections" to "nav_graph.xml"
-    )
+    assertThat(classesMetadataAppPackageInApp.map { it.fqcn to it.file })
+      .containsExactly(
+        "com.example.myapplication.SecondFragmentArgs" to "nav_graph.xml",
+        "com.example.myapplication.SecondFragmentDirections" to "nav_graph.xml"
+      )
 
     // check contents when providing lib package name in app module.
-    val classesMetadataLibPackageInApp = appModuleDescriptor
-      .getPackage(FqName("com.example.mylibrary"))
-      .memberScope
-      .classesInScope { name -> name.endsWith("Args") || name.endsWith("Directions") }
+    val classesMetadataLibPackageInApp =
+      appModuleDescriptor.getPackage(FqName("com.example.mylibrary")).memberScope.classesInScope {
+        name ->
+        name.endsWith("Args") || name.endsWith("Directions")
+      }
 
     // It collects 'packageFragmentProviderForWholeModuleWithDependencies'
-    assertThat(classesMetadataLibPackageInApp.map { it.fqcn to it.file }).containsExactly(
-      "com.example.mylibrary.FirstFragmentArgs" to "nav_graph.xml",
-      "com.example.mylibrary.FirstFragmentDirections" to "nav_graph.xml",
-      "com.example.mylibrary.SecondFragmentArgs" to "libnav_graph.xml",
-      "com.example.mylibrary.SecondFragmentDirections" to "libnav_graph.xml"
-    )
+    assertThat(classesMetadataLibPackageInApp.map { it.fqcn to it.file })
+      .containsExactly(
+        "com.example.mylibrary.FirstFragmentArgs" to "nav_graph.xml",
+        "com.example.mylibrary.FirstFragmentDirections" to "nav_graph.xml",
+        "com.example.mylibrary.SecondFragmentArgs" to "libnav_graph.xml",
+        "com.example.mylibrary.SecondFragmentDirections" to "libnav_graph.xml"
+      )
 
     // check contents for library module
     val libModule = fixture.project.findModule("mylibrary").getMainModule()
     val libModuleDescriptor = libModule.toDescriptor()
 
-    val classesMetadataInLib = libModuleDescriptor!!
-      .getPackage(FqName("com.example.mylibrary"))
-      .memberScope
-      .classesInScope { name -> name.endsWith("Args") || name.endsWith("Directions") }
+    val classesMetadataInLib =
+      libModuleDescriptor!!
+        .getPackage(FqName("com.example.mylibrary"))
+        .memberScope
+        .classesInScope { name -> name.endsWith("Args") || name.endsWith("Directions") }
 
-    assertThat(classesMetadataInLib.map { it.fqcn to it.file }).containsExactly(
-      "com.example.mylibrary.SecondFragmentArgs" to "libnav_graph.xml",
-      "com.example.mylibrary.SecondFragmentDirections" to "libnav_graph.xml"
-    )
+    assertThat(classesMetadataInLib.map { it.fqcn to it.file })
+      .containsExactly(
+        "com.example.mylibrary.SecondFragmentArgs" to "libnav_graph.xml",
+        "com.example.mylibrary.SecondFragmentDirections" to "libnav_graph.xml"
+      )
 
     // check contents for excluded library module
     val libModuleExcluded = fixture.project.findModule("mylibraryexcluded").getMainModule()
     val libModuleExcludedDescriptor = libModuleExcluded.toDescriptor()
 
-    val classesMetadataInLibExcluded = libModuleExcludedDescriptor!!
-      .getPackage(FqName("com.example.mylibrary"))
-      .memberScope
-      .classesInScope { name -> name.endsWith("Args") || name.endsWith("Directions") }
+    val classesMetadataInLibExcluded =
+      libModuleExcludedDescriptor!!
+        .getPackage(FqName("com.example.mylibrary"))
+        .memberScope
+        .classesInScope { name -> name.endsWith("Args") || name.endsWith("Directions") }
 
-    assertThat(classesMetadataInLibExcluded.map { it.fqcn to it.file }).containsExactly(
-      "com.example.mylibrary.SecondFragmentArgs" to "excludedlibnav_graph.xml",
-      "com.example.mylibrary.SecondFragmentDirections" to "excludedlibnav_graph.xml"
-    )
+    assertThat(classesMetadataInLibExcluded.map { it.fqcn to it.file })
+      .containsExactly(
+        "com.example.mylibrary.SecondFragmentArgs" to "excludedlibnav_graph.xml",
+        "com.example.mylibrary.SecondFragmentDirections" to "excludedlibnav_graph.xml"
+      )
   }
-}
\ No newline at end of file
+}
diff --git a/old-agp-tests/BUILD b/old-agp-tests/BUILD
index 9ee6ee8..9270df4 100644
--- a/old-agp-tests/BUILD
+++ b/old-agp-tests/BUILD
@@ -1,6 +1,6 @@
 load("//tools/base/bazel:bazel.bzl", "iml_module")
 load("//tools/base/bazel:maven.bzl", "maven_repository")
-load(":agp_versions.bzl", "AGP_3_1_4", "AGP_3_3_2", "AGP_3_5", "AGP_4_0", "AGP_4_1", "AGP_4_2", "AGP_7_0", "AGP_7_1", "AGP_7_2", "AGP_7_3", "AGP_7_4", "AGP_8_0", "AGP_8_1", "AGP_8_2", "GRADLE_5_3_1", "GRADLE_5_5", "GRADLE_6_7_1", "GRADLE_7_0_2", "GRADLE_7_2", "GRADLE_7_3_3", "GRADLE_7_4", "GRADLE_7_5", "GRADLE_8_0", "GRADLE_8_2", "GRADLE_LATEST", "local_old_agp_test")
+load(":agp_versions.bzl", "AGP_3_1_4", "AGP_3_3_2", "AGP_3_5", "AGP_4_0", "AGP_4_1", "AGP_4_2", "AGP_7_0", "AGP_7_1", "AGP_7_2", "AGP_7_3", "AGP_7_4", "AGP_8_0", "AGP_8_1", "AGP_8_2", "GRADLE_5_3_1", "GRADLE_5_5", "GRADLE_6_7_1", "GRADLE_7_0_2", "GRADLE_7_2", "GRADLE_7_3_3", "GRADLE_7_4", "GRADLE_7_5", "GRADLE_8_0", "GRADLE_8_2", "GRADLE_LATEST", "generate_old_agp_tests_from_list")
 
 # managed by go/iml_to_build
 iml_module(
@@ -174,177 +174,113 @@
     ],
 )
 
-local_old_agp_test(
-    additional_jdks = ["11"],
-    agp_version = AGP_3_1_4,
-    gradle_version = GRADLE_5_3_1,
-    tags = [
-        "block-network",
-        "no_test_mac",
-        "no_test_windows",
-    ],
-)
+COMMON_OLD_AGP_TEST_TARGETS_TAGS = [
+    "block-network",
+    "no_test_mac",
+    "no_test_windows",
+]
 
-local_old_agp_test(
-    additional_jdks = ["11"],
-    agp_version = AGP_3_3_2,
-    gradle_version = GRADLE_5_3_1,
-    shard_count = 1,
-    tags = [
-        "block-network",
-        "no_test_mac",
-        "no_test_windows",
-    ],
-)
-
-local_old_agp_test(
-    additional_jdks = ["11"],
-    agp_version = AGP_3_3_2,
-    gradle_version = GRADLE_5_5,
-    shard_count = 1,
-    tags = [
-        "block-network",
-        "no_test_mac",
-        "no_test_windows",
-    ],
-)
-
-local_old_agp_test(
-    additional_jdks = [
-        "1.8",
-        "11",
-    ],
-    agp_version = AGP_3_5,
-    gradle_version = GRADLE_5_5,
-    shard_count = 4,
-    tags = [
-        "block-network",
-        "no_test_mac",
-        "no_test_windows",
-    ],
-)
-
-local_old_agp_test(
-    additional_jdks = ["11"],
-    agp_version = AGP_4_0,
-    gradle_version = GRADLE_6_7_1,
-    shard_count = 3,
-    tags = [
-        "block-network",
-        "no_test_mac",
-        "no_test_windows",
-    ],
-)
-
-local_old_agp_test(
-    additional_jdks = ["11"],
-    agp_version = AGP_4_1,
-    gradle_version = GRADLE_6_7_1,
-    shard_count = 3,
-    tags = [
-        "block-network",
-        "no_test_mac",
-        "no_test_windows",
-    ],
-)
-
-local_old_agp_test(
-    additional_jdks = ["11"],
-    agp_version = AGP_4_2,
-    gradle_version = GRADLE_6_7_1,
-    shard_count = 4,
-    tags = [
-        "block-network",
-        "no_test_mac",
-        "no_test_windows",
-    ],
-)
-
-local_old_agp_test(
-    additional_jdks = ["11"],
-    agp_version = AGP_7_0,
-    gradle_version = GRADLE_7_0_2,
-    shard_count = 3,
-    tags = [
-        "block-network",
-        "no_test_mac",
-        "no_test_windows",
-    ],
-)
-
-local_old_agp_test(
-    agp_version = AGP_7_1,
-    gradle_version = GRADLE_7_2,
-    shard_count = 3,
-    tags = [
-        "block-network",
-        "no_test_mac",
-        "no_test_windows",
-    ],
-)
-
-local_old_agp_test(
-    agp_version = AGP_7_2,
-    gradle_version = GRADLE_7_3_3,
-    shard_count = 5,
-    tags = [
-        "block-network",
-        "no_test_mac",
-        "no_test_windows",
-    ],
-)
-
-local_old_agp_test(
-    agp_version = AGP_7_3,
-    gradle_version = GRADLE_7_4,
-    shard_count = 5,
-    tags = [
-        "block-network",
-        "no_test_mac",
-        "no_test_windows",
-    ],
-)
-
-local_old_agp_test(
-    agp_version = AGP_7_4,
-    gradle_version = GRADLE_7_5,
-    shard_count = 5,
-    tags = [
-        "block-network",
-        "no_test_mac",
-        "no_test_windows",
-    ],
-)
-
-local_old_agp_test(
-    agp_version = AGP_8_0,
-    gradle_version = GRADLE_8_0,
-    shard_count = 5,
-    tags = [
-        "block-network",
-        "no_test_mac",
-        "no_test_windows",
-    ],
-)
-
-local_old_agp_test(
-    agp_version = AGP_8_1,
-    gradle_version = GRADLE_8_0,
-    shard_count = 5,
-    tags = [
-        "block-network",
-        "no_test_mac",
-        "no_test_windows",
-    ],
-)
-
-local_old_agp_test(
-    agp_version = AGP_8_2,
-    gradle_version = GRADLE_8_2,
-    shard_count = 5,
-    tags = [
-        "block-network",
-        "no_test_mac",
-        "no_test_windows",
+generate_old_agp_tests_from_list(
+    tests_list = [
+        {
+            "additional_jdks": ["11"],
+            "agp_version": AGP_3_1_4,
+            "gradle_version": GRADLE_5_3_1,
+            "tags": COMMON_OLD_AGP_TEST_TARGETS_TAGS,
+        },
+        {
+            "additional_jdks": ["11"],
+            "agp_version": AGP_3_3_2,
+            "gradle_version": GRADLE_5_3_1,
+            "shard_count": 1,
+            "tags": COMMON_OLD_AGP_TEST_TARGETS_TAGS,
+        },
+        {
+            "additional_jdks": ["11"],
+            "agp_version": AGP_3_3_2,
+            "gradle_version": GRADLE_5_5,
+            "shard_count": 1,
+            "tags": COMMON_OLD_AGP_TEST_TARGETS_TAGS,
+        },
+        {
+            "additional_jdks": [
+                "1.8",
+                "11",
+            ],
+            "agp_version": AGP_3_5,
+            "gradle_version": GRADLE_5_5,
+            "shard_count": 4,
+            "tags": COMMON_OLD_AGP_TEST_TARGETS_TAGS,
+        },
+        {
+            "additional_jdks": ["11"],
+            "agp_version": AGP_4_0,
+            "gradle_version": GRADLE_6_7_1,
+            "shard_count": 3,
+            "tags": COMMON_OLD_AGP_TEST_TARGETS_TAGS,
+        },
+        {
+            "additional_jdks": ["11"],
+            "agp_version": AGP_4_1,
+            "gradle_version": GRADLE_6_7_1,
+            "shard_count": 3,
+            "tags": COMMON_OLD_AGP_TEST_TARGETS_TAGS,
+        },
+        {
+            "additional_jdks": ["11"],
+            "agp_version": AGP_4_2,
+            "gradle_version": GRADLE_6_7_1,
+            "shard_count": 4,
+            "tags": COMMON_OLD_AGP_TEST_TARGETS_TAGS,
+        },
+        {
+            "additional_jdks": ["11"],
+            "agp_version": AGP_7_0,
+            "gradle_version": GRADLE_7_0_2,
+            "shard_count": 3,
+            "tags": COMMON_OLD_AGP_TEST_TARGETS_TAGS,
+        },
+        {
+            "agp_version": AGP_7_1,
+            "gradle_version": GRADLE_7_2,
+            "shard_count": 3,
+            "tags": COMMON_OLD_AGP_TEST_TARGETS_TAGS,
+        },
+        {
+            "agp_version": AGP_7_2,
+            "gradle_version": GRADLE_7_3_3,
+            "shard_count": 5,
+            "tags": COMMON_OLD_AGP_TEST_TARGETS_TAGS,
+        },
+        {
+            "agp_version": AGP_7_3,
+            "gradle_version": GRADLE_7_4,
+            "shard_count": 5,
+            "tags": COMMON_OLD_AGP_TEST_TARGETS_TAGS,
+        },
+        {
+            "agp_version": AGP_7_4,
+            "gradle_version": GRADLE_7_5,
+            "shard_count": 5,
+            "tags": COMMON_OLD_AGP_TEST_TARGETS_TAGS,
+        },
+        {
+            "agp_version": AGP_8_0,
+            "gradle_version": GRADLE_8_0,
+            "shard_count": 5,
+            "tags": COMMON_OLD_AGP_TEST_TARGETS_TAGS,
+        },
+        {
+            "agp_version": AGP_8_1,
+            "gradle_version": GRADLE_8_0,
+            "shard_count": 5,
+            "tags": COMMON_OLD_AGP_TEST_TARGETS_TAGS,
+        },
+        {
+            "agp_version": AGP_8_2,
+            "gradle_version": GRADLE_8_2,
+            "shard_count": 5,
+            "tags": COMMON_OLD_AGP_TEST_TARGETS_TAGS,
+        },
     ],
 )
diff --git a/old-agp-tests/agp_versions.bzl b/old-agp-tests/agp_versions.bzl
index dd731fd..509831f 100644
--- a/old-agp-tests/agp_versions.bzl
+++ b/old-agp-tests/agp_versions.bzl
@@ -146,7 +146,7 @@
     GRADLE_5_3_1: ["//tools/base/build-system:gradle-distrib-5.3.1"],
 }
 
-def local_old_agp_test(
+def _local_old_agp_test(
         gradle_version,
         agp_version,
         additional_jdks = [],
@@ -169,3 +169,16 @@
         ignore_other_tests = False,
         **kwargs
     )
+
+def generate_old_agp_tests_from_list(tests_list):
+    """Creates tests running with OldAgpSuite from a list of test descriptions.
+
+    Having all test definitions as a list in one macro allows us to implement a check to ensure all
+    OldAgpTest tests from the module are covered with a test target and thus will actually run.
+
+    Args:
+      tests_list: list of kwargs objects, one per required test, containing arguments for that test.
+                  See _local_old_agp_test and old_agp_test for test arguments description.
+    """
+    for test_kwargs in tests_list:
+        _local_old_agp_test(**test_kwargs)
diff --git a/preview-designer/src/com/android/tools/idea/preview/NavigatingInteractionHandler.kt b/preview-designer/src/com/android/tools/idea/preview/NavigatingInteractionHandler.kt
index 940b17b..cbaebae 100644
--- a/preview-designer/src/com/android/tools/idea/preview/NavigatingInteractionHandler.kt
+++ b/preview-designer/src/com/android/tools/idea/preview/NavigatingInteractionHandler.kt
@@ -28,7 +28,7 @@
 import com.android.tools.idea.common.surface.selectComponent
 import com.android.tools.idea.concurrency.AndroidCoroutineScope
 import com.android.tools.idea.concurrency.AndroidDispatchers
-import com.android.tools.idea.uibuilder.surface.NlDesignSurface
+import com.android.tools.idea.uibuilder.surface.NavigationHandler
 import com.android.tools.idea.uibuilder.surface.NlInteractionHandler
 import java.awt.MouseInfo
 import java.awt.event.InputEvent
@@ -44,6 +44,7 @@
  */
 class NavigatingInteractionHandler(
   private val surface: DesignSurface<*>,
+  private val navigationHandler: NavigationHandler,
   private val isSelectionEnabled: () -> Boolean = { false }
 ) : NlInteractionHandler(surface) {
 
@@ -172,10 +173,9 @@
     val sceneView = surface.getSceneViewAt(x, y) ?: return
     val androidX = Coordinates.getAndroidXDip(sceneView, x)
     val androidY = Coordinates.getAndroidYDip(sceneView, y)
-    val navHandler = (surface as NlDesignSurface).navigationHandler ?: return
     val scene = sceneView.scene
     scope.launch(AndroidDispatchers.workerThread) {
-      if (!navHandler.handleNavigateWithCoordinates(sceneView, x, y, needsFocusEditor)) {
+      if (!navigationHandler.handleNavigateWithCoordinates(sceneView, x, y, needsFocusEditor)) {
         val sceneComponent =
           scene.findComponent(sceneView.context, androidX, androidY) ?: return@launch
         navigateToComponent(sceneComponent.nlComponent, needsFocusEditor)
diff --git a/preview-designer/src/com/android/tools/idea/preview/SurfacePreviewsUpdate.kt b/preview-designer/src/com/android/tools/idea/preview/SurfacePreviewsUpdate.kt
index 438315f..f4f78c6 100644
--- a/preview-designer/src/com/android/tools/idea/preview/SurfacePreviewsUpdate.kt
+++ b/preview-designer/src/com/android/tools/idea/preview/SurfacePreviewsUpdate.kt
@@ -172,6 +172,7 @@
   onRenderCompleted: () -> Unit,
   previewElementModelAdapter: PreviewElementModelAdapter<T, NlModel>,
   modelUpdater: NlModel.NlModelUpdaterInterface,
+  navigationHandler: PreviewNavigationHandler,
   configureLayoutlibSceneManager:
     (PreviewDisplaySettings, LayoutlibSceneManager) -> LayoutlibSceneManager
 ): List<T> {
@@ -281,11 +282,7 @@
           getPsiFileSafely(project, it)
         }
           ?: psiFile
-      (navigationHandler as? PreviewNavigationHandler)?.setDefaultLocation(
-        newModel,
-        defaultFile,
-        offset
-      )
+      navigationHandler.setDefaultLocation(newModel, defaultFile, offset)
 
       withContext(AndroidDispatchers.workerThread) {
         previewElementModelAdapter.applyToConfiguration(previewElement, newModel.configuration)
diff --git a/preview-designer/src/com/android/tools/idea/preview/representation/CommonPreviewRepresentation.kt b/preview-designer/src/com/android/tools/idea/preview/representation/CommonPreviewRepresentation.kt
index 995332e..e8b012e 100644
--- a/preview-designer/src/com/android/tools/idea/preview/representation/CommonPreviewRepresentation.kt
+++ b/preview-designer/src/com/android/tools/idea/preview/representation/CommonPreviewRepresentation.kt
@@ -152,6 +152,10 @@
 
   private val delegateInteractionHandler = DelegateInteractionHandler()
 
+  private val navigationHandler =
+    DefaultNavigationHandler { _, _, _, _, _ -> null }
+      .apply { Disposer.register(this@CommonPreviewRepresentation, this) }
+
   private val previewView = invokeAndWaitIfNeeded {
     viewConstructor(
       project,
@@ -162,9 +166,10 @@
           }
         }
         .setInteractionHandlerProvider {
-          delegateInteractionHandler.apply { delegate = NavigatingInteractionHandler(it) }
+          delegateInteractionHandler.apply {
+            delegate = NavigatingInteractionHandler(it, navigationHandler)
+          }
         }
-        .setNavigationHandler(DefaultNavigationHandler { _, _, _, _, _ -> null })
         .setDelegateDataProvider {
           when (it) {
             PREVIEW_VIEW_MODEL_STATUS.name -> previewViewModel
@@ -274,6 +279,7 @@
         this::onAfterRender,
         previewElementModelAdapter,
         modelUpdater,
+        navigationHandler,
         this::configureLayoutlibSceneManager
       )
 
diff --git a/profilers-android/src/com/android/tools/idea/profilers/AndroidProfilerToolWindow.kt b/profilers-android/src/com/android/tools/idea/profilers/AndroidProfilerToolWindow.kt
index 5a2e7d5..1499b22 100644
--- a/profilers-android/src/com/android/tools/idea/profilers/AndroidProfilerToolWindow.kt
+++ b/profilers-android/src/com/android/tools/idea/profilers/AndroidProfilerToolWindow.kt
@@ -32,6 +32,14 @@
 import com.android.tools.profilers.StudioProfilers
 import com.android.tools.profilers.tasks.ProfilerTaskType
 import com.android.tools.profilers.tasks.args.TaskArgs
+import com.android.tools.profilers.tasks.taskhandlers.ProfilerTaskHandler
+import com.android.tools.profilers.tasks.taskhandlers.singleartifact.cpu.CallstackSampleTaskHandler
+import com.android.tools.profilers.tasks.taskhandlers.singleartifact.cpu.JavaKotlinMethodSampleTaskHandler
+import com.android.tools.profilers.tasks.taskhandlers.singleartifact.cpu.JavaKotlinMethodTraceTaskHandler
+import com.android.tools.profilers.tasks.taskhandlers.singleartifact.cpu.SystemTraceTaskHandler
+import com.android.tools.profilers.tasks.taskhandlers.singleartifact.memory.HeapDumpTaskHandler
+import com.android.tools.profilers.tasks.taskhandlers.singleartifact.memory.JavaKotlinAllocationsTaskHandler
+import com.android.tools.profilers.tasks.taskhandlers.singleartifact.memory.NativeAllocationsTaskHandler
 import com.intellij.openapi.Disposable
 import com.intellij.openapi.module.Module
 import com.intellij.openapi.module.ModuleManager
@@ -53,6 +61,9 @@
   private val ideProfilerServices: IntellijProfilerServices
   private val ideProfilerComponents: IdeProfilerComponents
   val profilers: StudioProfilers
+  private var currentTaskHandler: ProfilerTaskHandler? = null
+  private val taskHandlers = HashMap<ProfilerTaskType, ProfilerTaskHandler>()
+
   private lateinit var homeTab: StudioProfilersHomeTab
   private lateinit var homePanel: JPanel
   private lateinit var profilersTab: StudioProfilersTab
@@ -69,7 +80,7 @@
     TransportService.getInstance()
 
     val client = ProfilerClient(TransportService.channelName)
-    profilers = StudioProfilers(client, ideProfilerServices)
+    profilers = StudioProfilers(client, ideProfilerServices, project, taskHandlers)
     val navigator = ideProfilerServices.codeNavigator
     // CPU ABI architecture, when needed by the code navigator, should be retrieved from StudioProfiler selected session.
     navigator.cpuArchSource = Supplier { profilers.sessionsManager.selectedSessionMetaData.processAbi }
@@ -90,6 +101,9 @@
 
     ideProfilerComponents = IntellijProfilerComponents(project, ideProfilerServices.featureTracker)
 
+    // Create and store the task handlers in a map.
+    initializeTaskHandlers()
+
     if (ideProfilerServices.featureConfig.isTaskBasedUxEnabled) {
       homeTab = StudioProfilersHomeTab(project, profilers, ideProfilerComponents)
       homePanel = JPanel(BorderLayout())
@@ -105,8 +119,15 @@
     initializeProfilerTab()
   }
 
-  private fun createTaskTab() {
-    createNewTab(profilersPanel, "<Task Name>", true)
+  private fun initializeTaskHandlers() {
+    val sessionsManager = profilers.sessionsManager
+    taskHandlers[ProfilerTaskType.SYSTEM_TRACE] = SystemTraceTaskHandler(sessionsManager)
+    taskHandlers[ProfilerTaskType.CALLSTACK_SAMPLE] = CallstackSampleTaskHandler(sessionsManager)
+    taskHandlers[ProfilerTaskType.JAVA_KOTLIN_METHOD_TRACE] = JavaKotlinMethodTraceTaskHandler(sessionsManager)
+    taskHandlers[ProfilerTaskType.JAVA_KOTLIN_METHOD_SAMPLE] = JavaKotlinMethodSampleTaskHandler(sessionsManager)
+    taskHandlers[ProfilerTaskType.HEAP_DUMP] = HeapDumpTaskHandler(sessionsManager)
+    taskHandlers[ProfilerTaskType.NATIVE_ALLOCATIONS] = NativeAllocationsTaskHandler(sessionsManager)
+    taskHandlers[ProfilerTaskType.JAVA_KOTLIN_ALLOCATIONS] = JavaKotlinAllocationsTaskHandler(sessionsManager)
   }
 
   @VisibleForTesting
@@ -144,11 +165,6 @@
     profilersPanel.add(profilersTab.view.component)
     profilersPanel.revalidate()
     profilersPanel.repaint()
-
-    // TODO(b/277797528) Remove once the task tab supports an L2 or L3 stage.
-    if (ideProfilerServices.featureConfig.isTaskBasedUxEnabled) {
-      profilers.setDefaultStage()
-    }
   }
 
   fun openHomeTab() {
@@ -162,13 +178,19 @@
   }
 
   fun openTaskTab(taskType: ProfilerTaskType, taskArgs: TaskArgs?) {
-    // The taskType and taskArgs will be utilized in the (to-be-added) task handlers.
-    val content = findTaskTab()
-    if (content != null) {
-      window.getContentManager().setSelectedContent(content)
+    val taskTab = findTaskTab()
+    val taskName = taskHandlers[taskType]?.getTaskName() ?: "Task Not Supported Yet"
+    if (taskTab != null) {
+      taskTab.displayName = taskName
+      window.getContentManager().setSelectedContent(taskTab)
     }
     else {
-      createTaskTab()
+      createNewTab(profilersPanel, taskName, true)
+    }
+    currentTaskHandler?.exit()
+    currentTaskHandler = taskHandlers[taskType]
+    currentTaskHandler?.let { taskHandler ->
+      val enterSuccessful = taskHandler.enter(taskArgs)
     }
   }
 
diff --git a/profilers-android/src/com/android/tools/idea/profilers/StartSystemTraceAction.kt b/profilers-android/src/com/android/tools/idea/profilers/StartSystemTraceAction.kt
index f222117..01dad92 100644
--- a/profilers-android/src/com/android/tools/idea/profilers/StartSystemTraceAction.kt
+++ b/profilers-android/src/com/android/tools/idea/profilers/StartSystemTraceAction.kt
@@ -20,6 +20,7 @@
 import com.android.tools.idea.run.profiler.CpuProfilerConfig
 import com.android.tools.profilers.cpu.CpuProfilerStage
 import com.android.tools.profilers.cpu.config.PerfettoConfiguration
+import com.intellij.openapi.actionSystem.ActionUpdateThread
 import com.intellij.openapi.actionSystem.AnActionEvent
 import com.intellij.openapi.project.DumbAwareAction
 
@@ -28,6 +29,9 @@
   "Start a system trace in the current profiling session",
   null
 ) {
+
+  override fun getActionUpdateThread() = ActionUpdateThread.BGT
+
   override fun update(e: AnActionEvent) {
     val project = e.project
     e.presentation.isEnabled =
diff --git a/profilers-android/src/com/android/tools/idea/profilers/StopCpuCaptureAction.kt b/profilers-android/src/com/android/tools/idea/profilers/StopCpuCaptureAction.kt
index 774fd14..24e3d46 100644
--- a/profilers-android/src/com/android/tools/idea/profilers/StopCpuCaptureAction.kt
+++ b/profilers-android/src/com/android/tools/idea/profilers/StopCpuCaptureAction.kt
@@ -18,6 +18,7 @@
 import android.annotation.SuppressLint
 import com.android.tools.idea.flags.StudioFlags
 import com.android.tools.profilers.cpu.CpuProfilerStage
+import com.intellij.openapi.actionSystem.ActionUpdateThread
 import com.intellij.openapi.actionSystem.AnActionEvent
 import com.intellij.openapi.project.DumbAwareAction
 
@@ -26,6 +27,9 @@
   "Stop a CPU capture in the current profiling session",
   null
 ) {
+
+  override fun getActionUpdateThread() = ActionUpdateThread.BGT
+
   override fun update(e: AnActionEvent) {
     val project = e.project
     val profilers = project?.let { AndroidProfilerToolWindowFactory.getProfilerToolWindow(it)?.profilers }
diff --git a/profilers-android/src/com/android/tools/idea/profilers/StopProfilingSessionAction.kt b/profilers-android/src/com/android/tools/idea/profilers/StopProfilingSessionAction.kt
index 523dcd4..81b23af 100644
--- a/profilers-android/src/com/android/tools/idea/profilers/StopProfilingSessionAction.kt
+++ b/profilers-android/src/com/android/tools/idea/profilers/StopProfilingSessionAction.kt
@@ -16,6 +16,7 @@
 package com.android.tools.idea.profilers
 
 import com.android.tools.idea.flags.StudioFlags
+import com.intellij.openapi.actionSystem.ActionUpdateThread
 import com.intellij.openapi.actionSystem.AnActionEvent
 import com.intellij.openapi.project.DumbAwareAction
 
@@ -24,6 +25,9 @@
   "Stop the current profiling session",
   null
 ) {
+
+  override fun getActionUpdateThread() = ActionUpdateThread.BGT
+
   override fun update(e: AnActionEvent) {
     val project = e.project
     e.presentation.isEnabled =
diff --git a/profilers-android/src/com/android/tools/idea/profilers/profilingconfig/CpuProfilingConfigurationsDialog.java b/profilers-android/src/com/android/tools/idea/profilers/profilingconfig/CpuProfilingConfigurationsDialog.java
index 7c58d60..daa67fd 100644
--- a/profilers-android/src/com/android/tools/idea/profilers/profilingconfig/CpuProfilingConfigurationsDialog.java
+++ b/profilers-android/src/com/android/tools/idea/profilers/profilingconfig/CpuProfilingConfigurationsDialog.java
@@ -74,6 +74,7 @@
 import org.jetbrains.annotations.Nls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.VisibleForTesting;
 
 public class CpuProfilingConfigurationsDialog extends SingleConfigurableEditor {
 
@@ -113,7 +114,8 @@
     myOnCloseCallback.accept(selectedConfigSupported ? selectedConfig : null);
   }
 
-  private static class ProfilingConfigurable implements Configurable {
+  @VisibleForTesting
+  static class ProfilingConfigurable implements Configurable {
 
     private static final String ADD = "Add";
 
@@ -226,14 +228,29 @@
       ToolbarDecorator toolbarDecorator = ToolbarDecorator.createDecorator(myConfigurations)
         .setToolbarPosition(ActionToolbarPosition.TOP)
         .setPanelBorder(JBUI.Borders.empty())
-        .setMoveUpAction(moveUpAction).setMoveUpActionUpdater(moveUpAction).setMoveUpActionName(MOVE_UP)
-        .setMoveDownAction(moveDownAction).setMoveDownActionUpdater(moveDownAction).setMoveDownActionName(MOVE_DOWN)
-        .setRemoveAction(removeAction).setRemoveActionUpdater(removeAction).setRemoveActionName(REMOVE)
-        .setAddAction(addAction).setAddActionUpdater(addAction).setAddActionName(ADD)
         .setMinimumSize(new JBDimension(200, 200))
         .setForcedDnD();
+
+      if (!StudioFlags.PROFILER_TASK_BASED_UX.get()) {
+        toolbarDecorator
+          .setMoveUpAction(moveUpAction).setMoveUpActionUpdater(moveUpAction).setMoveUpActionName(MOVE_UP)
+          .setMoveDownAction(moveDownAction).setMoveDownActionUpdater(moveDownAction).setMoveDownActionName(MOVE_DOWN)
+          .setRemoveAction(removeAction).setRemoveActionUpdater(removeAction).setRemoveActionName(REMOVE)
+          .setAddAction(addAction).setAddActionUpdater(addAction).setAddActionName(ADD);
+      }
+      else {
+        // Make the icons invisible
+        toolbarDecorator
+          .disableRemoveAction()
+          .disableDownAction()
+          .disableUpAction()
+          .disableAddAction();
+      }
+
       JComponent panel = toolbarDecorator.createPanel();
-      addAction.setPopupParent(panel);
+      if (!StudioFlags.PROFILER_TASK_BASED_UX.get()) {
+        addAction.setPopupParent(panel);
+      }
       return panel;
     }
 
diff --git a/profilers-android/testSrc/com/android/tools/idea/profilers/AndroidProfilerToolWindowFactoryTest.kt b/profilers-android/testSrc/com/android/tools/idea/profilers/AndroidProfilerToolWindowFactoryTest.kt
index 35a7a7e..eecf406 100644
--- a/profilers-android/testSrc/com/android/tools/idea/profilers/AndroidProfilerToolWindowFactoryTest.kt
+++ b/profilers-android/testSrc/com/android/tools/idea/profilers/AndroidProfilerToolWindowFactoryTest.kt
@@ -3,11 +3,23 @@
 import com.android.testutils.waitForCondition
 import com.android.tools.idea.flags.StudioFlags
 import com.android.tools.idea.sdk.AndroidOrApkFacetChecker
+import com.android.tools.profiler.proto.Common
+import com.android.tools.profiler.proto.Trace
+import com.android.tools.profilers.cpu.CpuCaptureSessionArtifact
+import com.android.tools.profilers.cpu.CpuProfilerStage
+import com.android.tools.profilers.memory.HeapProfdSessionArtifact
+import com.android.tools.profilers.memory.MainMemoryProfilerStage
 import com.android.tools.profilers.taskbased.home.OpenHomeTabListener
+import com.android.tools.profilers.tasks.ProfilerTaskType
+import com.android.tools.profilers.tasks.args.singleartifact.cpu.CpuTaskArgs
+import com.android.tools.profilers.tasks.args.singleartifact.memory.NativeAllocationsTaskArgs
 import com.google.common.truth.Truth.assertThat
 import com.intellij.openapi.wm.ext.LibraryDependentToolWindow
 import com.intellij.testFramework.ProjectRule
 import com.intellij.toolWindow.ToolWindowHeadlessManagerImpl
+import org.jetbrains.uast.util.isInstanceOf
+import org.junit.After
+import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
 import java.util.concurrent.TimeUnit
@@ -23,6 +35,17 @@
 
   private val project get() = projectRule.project
 
+  @Before
+  fun setup() {
+    // This test suite assumes the Task-Based UX is enabled unless otherwise specified.
+    StudioFlags.PROFILER_TASK_BASED_UX.override(true)
+  }
+
+  @After
+  fun cleanup() {
+    StudioFlags.PROFILER_TASK_BASED_UX.clearOverride()
+  }
+
   @Test
   fun isLibraryToolWindow() {
     val toolWindow =
@@ -35,8 +58,6 @@
 
   @Test
   fun `createToolWindowContent implicitly opens the home tab`() {
-    StudioFlags.PROFILER_TASK_BASED_UX.override(true);
-
     val toolWindow = ToolWindowHeadlessManagerImpl.MockToolWindow(project)
     val toolWindowFactory = AndroidProfilerToolWindowFactory()
     toolWindowFactory.init(toolWindow)
@@ -52,14 +73,10 @@
     assertThat(homeTabContent.tabName).isEqualTo("Home")
     assertThat(homeTabContent.displayName).isEqualTo("Home")
     assertThat(homeTabContent.toolwindowTitle).isEqualTo("Home")
-
-    StudioFlags.PROFILER_TASK_BASED_UX.clearOverride()
   }
 
   @Test
   fun `explicitly opening the home tab reselects existing home tab`() {
-    StudioFlags.PROFILER_TASK_BASED_UX.override(true);
-
     val toolWindow = ToolWindowHeadlessManagerImpl.MockToolWindow(project)
     val toolWindowFactory = AndroidProfilerToolWindowFactory()
     toolWindowFactory.init(toolWindow)
@@ -91,7 +108,71 @@
     waitForCondition(5L, TimeUnit.SECONDS) {
       toolWindow.contentManager.contentCount == 2 && toolWindow.contentManager.selectedContent == homeTabContent
     }
+  }
 
-    StudioFlags.PROFILER_TASK_BASED_UX.clearOverride()
+  @Test
+  fun `opening the task tab with CPU task creates second tab with CPU stage`() {
+    val toolWindow = ToolWindowHeadlessManagerImpl.MockToolWindow(project)
+    val toolWindowFactory = AndroidProfilerToolWindowFactory()
+    toolWindowFactory.init(toolWindow)
+    toolWindowFactory.createToolWindowContent(project, toolWindow)
+
+    // Wait for the home tab to be auto-selected via the call to openHomeTab() in AndroidProfilerToolWindow.createToolWindowContent.
+    waitForCondition(5L, TimeUnit.SECONDS) {
+      toolWindow.contentManager.selectedContent != null &&
+      toolWindow.contentManager.selectedContent!!.displayName == "Home"
+    }
+
+    // At this point, there is a home tab implicitly opened by the call to `createToolWindowContent`.
+
+    val profilerToolWindow = AndroidProfilerToolWindowFactory.PROJECT_PROFILER_MAP[project]
+    assertThat(profilerToolWindow).isNotNull()
+
+    profilerToolWindow!!.openTaskTab(ProfilerTaskType.SYSTEM_TRACE,
+                                     CpuTaskArgs(CpuCaptureSessionArtifact
+                                                 (profilerToolWindow.profilers, Common.Session.getDefaultInstance(),
+                                                  Common.SessionMetaData.getDefaultInstance(), Trace.TraceInfo.getDefaultInstance())))
+
+    // Opening the task tab with a SYSTEM_TRACE task (a CPU task) should open up a second tab with non-null content, a tab name
+    // of "System Trace" and the current stage should be set to the CpuProfilerStage.
+    waitForCondition(5L, TimeUnit.SECONDS) {
+      toolWindow.contentManager.contentCount == 2 &&
+      toolWindow.contentManager.selectedContent != null &&
+      toolWindow.contentManager.selectedContent!!.displayName == "System Trace"
+      profilerToolWindow.profilers.stage is CpuProfilerStage
+    }
+  }
+
+  @Test
+  fun `opening the task tab with memory task creates second tab with memory stage`() {
+    val toolWindow = ToolWindowHeadlessManagerImpl.MockToolWindow(project)
+    val toolWindowFactory = AndroidProfilerToolWindowFactory()
+    toolWindowFactory.init(toolWindow)
+    toolWindowFactory.createToolWindowContent(project, toolWindow)
+
+    // Wait for the home tab to be auto-selected via the call to openHomeTab() in AndroidProfilerToolWindow.createToolWindowContent.
+    waitForCondition(5L, TimeUnit.SECONDS) {
+      toolWindow.contentManager.selectedContent != null &&
+      toolWindow.contentManager.selectedContent!!.displayName == "Home"
+    }
+
+    // At this point, there is a home tab implicitly opened by the call to `createToolWindowContent`.
+
+    val profilerToolWindow = AndroidProfilerToolWindowFactory.PROJECT_PROFILER_MAP[project]
+    assertThat(profilerToolWindow).isNotNull()
+
+    profilerToolWindow!!.openTaskTab(ProfilerTaskType.NATIVE_ALLOCATIONS,
+                                     NativeAllocationsTaskArgs(HeapProfdSessionArtifact(
+                                     profilerToolWindow.profilers, Common.Session.getDefaultInstance(),
+                                                  Common.SessionMetaData.getDefaultInstance(), Trace.TraceInfo.getDefaultInstance())))
+
+    // Opening the task tab with a NATIVE_ALLOCATIONS task (a memory task) should open up a second tab with non-null content, a tab name
+    // of "Native Allocations" and the current stage should be set to the MainMemoryProfilerStage.
+    waitForCondition(5L, TimeUnit.SECONDS) {
+      toolWindow.contentManager.contentCount == 2 &&
+      toolWindow.contentManager.selectedContent != null &&
+      toolWindow.contentManager.selectedContent!!.displayName == "Native Allocations"
+      profilerToolWindow.profilers.stage is MainMemoryProfilerStage
+    }
   }
 }
\ No newline at end of file
diff --git a/profilers-android/testSrc/com/android/tools/idea/profilers/profilingconfig/CpuProfilingConfigurationsDialogTest.kt b/profilers-android/testSrc/com/android/tools/idea/profilers/profilingconfig/CpuProfilingConfigurationsDialogTest.kt
new file mode 100644
index 0000000..c336e31
--- /dev/null
+++ b/profilers-android/testSrc/com/android/tools/idea/profilers/profilingconfig/CpuProfilingConfigurationsDialogTest.kt
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.profilers.profilingconfig
+
+import com.android.tools.adtui.TreeWalker
+import com.android.tools.adtui.model.FakeTimer
+import com.android.tools.idea.flags.StudioFlags
+import com.android.tools.idea.transport.faketransport.FakeGrpcChannel
+import com.android.tools.idea.transport.faketransport.FakeTransportService
+import com.android.tools.profilers.FakeFeatureTracker
+import com.android.tools.profilers.FakeIdeProfilerServices
+import com.android.tools.profilers.ProfilerClient
+import com.android.tools.profilers.StudioProfilers
+import com.android.tools.profilers.analytics.FeatureTracker
+import com.android.tools.profilers.cpu.CpuProfilerStage
+import com.android.tools.profilers.cpu.config.CpuProfilerConfigModel
+import com.android.tools.profilers.event.FakeEventService
+import com.google.common.truth.Truth.assertThat
+import com.intellij.mock.MockProjectEx
+import com.intellij.openapi.project.Project
+import com.intellij.testFramework.ApplicationRule
+import com.intellij.testFramework.DisposableRule
+import com.intellij.testFramework.EdtRule
+import com.intellij.ui.CommonActionsPanel
+import com.intellij.ui.JBSplitter
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import javax.swing.JComponent
+
+class CpuProfilingConfigurationsDialogTest {
+
+  private lateinit var configurations: CpuProfilingConfigurationsDialog.ProfilingConfigurable
+  private lateinit var project: Project
+  private lateinit var model: CpuProfilerConfigModel
+  private lateinit var featureTracker: FeatureTracker
+  private lateinit var myStage: CpuProfilerStage
+  private var deviceLevel = 0
+
+  private val myTimer = FakeTimer()
+  private val myIdeServices = FakeIdeProfilerServices()
+  private val myTransportService = FakeTransportService(myTimer)
+
+  @get:Rule
+  val myGrpcChannel = FakeGrpcChannel("CpuProfilingConfigDialogTestChannel", myTransportService, FakeEventService())
+
+  @get:Rule
+  val myEdtRule = EdtRule()
+
+  @get:Rule
+  val applicationRule = ApplicationRule()
+
+  @get:Rule
+  val disposableRule = DisposableRule()
+
+  @Before
+  fun setUp() {
+    val profilers = StudioProfilers(ProfilerClient(myGrpcChannel.channel), myIdeServices, myTimer)
+    profilers.setPreferredProcess(FakeTransportService.FAKE_DEVICE_NAME, FakeTransportService.FAKE_PROCESS_NAME, null)
+    project = MockProjectEx(disposableRule.disposable)
+    myStage = CpuProfilerStage(profilers)
+    model =  CpuProfilerConfigModel(profilers, myStage)
+    model.profilingConfiguration = FakeIdeProfilerServices.ATRACE_CONFIG
+    featureTracker = FakeFeatureTracker()
+    configurations = CpuProfilingConfigurationsDialog.ProfilingConfigurable(project, model, deviceLevel, featureTracker)
+  }
+
+  @After
+  fun tearDown() {
+    // Need to clear any override we use inside tests here.
+    StudioFlags.PROFILER_TASK_BASED_UX.clearOverride()
+  }
+
+  @Test
+  fun configDialogIconWhenTaskBasedUxEnabled() {
+    StudioFlags.PROFILER_TASK_BASED_UX.override(true)
+    var profilingComponent : JComponent = configurations.createComponent()!!
+    assertThat(profilingComponent).isNotNull()
+    val splitter: JBSplitter = TreeWalker(profilingComponent).descendants().filterIsInstance<JBSplitter>().first()
+    val firstComponent = splitter.firstComponent
+    val actionPanel: CommonActionsPanel = TreeWalker(firstComponent).descendants().filterIsInstance<CommonActionsPanel>().first()
+    // Add, remove, up and down buttons should be null
+    val addButtonAction = actionPanel.getAnAction(CommonActionsPanel.Buttons.ADD)
+    assertThat(addButtonAction).isNull()
+    val downButtonAction = actionPanel.getAnAction(CommonActionsPanel.Buttons.DOWN)
+    assertThat(downButtonAction).isNull()
+    val upButtonAction = actionPanel.getAnAction(CommonActionsPanel.Buttons.UP)
+    assertThat(upButtonAction).isNull()
+    val removeButtonAction = actionPanel.getAnAction(CommonActionsPanel.Buttons.REMOVE)
+    assertThat(removeButtonAction).isNull()
+  }
+
+  @Test
+  fun configDialogIconWhenTaskBasedUxDisabled() {
+    StudioFlags.PROFILER_TASK_BASED_UX.override(false)
+    var profilingComponent : JComponent = configurations.createComponent()!!
+    assertThat(profilingComponent).isNotNull()
+    val splitter: JBSplitter = TreeWalker(profilingComponent).descendants().filterIsInstance<JBSplitter>().first()
+    val firstComponent = splitter.firstComponent
+    val actionPanel: CommonActionsPanel = TreeWalker(firstComponent).descendants().filterIsInstance<CommonActionsPanel>().first()
+    // Add, remove, up and down buttons should not be null
+    val addButtonAction = actionPanel.getAnAction(CommonActionsPanel.Buttons.ADD)
+    assertThat(addButtonAction).isNotNull()
+    val downButtonAction = actionPanel.getAnAction(CommonActionsPanel.Buttons.DOWN)
+    assertThat(downButtonAction).isNotNull()
+    val upButtonAction = actionPanel.getAnAction(CommonActionsPanel.Buttons.UP)
+    assertThat(upButtonAction).isNotNull()
+    val removeButtonAction = actionPanel.getAnAction(CommonActionsPanel.Buttons.REMOVE)
+    assertThat(removeButtonAction).isNotNull()
+  }
+}
\ No newline at end of file
diff --git a/profilers-ui/src/com/android/tools/profilers/ExportArtifactUtils.kt b/profilers-ui/src/com/android/tools/profilers/ExportArtifactUtils.kt
new file mode 100644
index 0000000..1d79b17
--- /dev/null
+++ b/profilers-ui/src/com/android/tools/profilers/ExportArtifactUtils.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.profilers
+
+import java.io.File
+import java.io.FileOutputStream
+import java.io.OutputStream
+import java.util.function.Consumer
+
+/**
+ * This class contains utility methods to aid in exporting a {@link SessionArtifact} to a file.
+ */
+object ExportArtifactUtils {
+
+  /**
+   * Opens an export file dialog and prompts user to export/save artifact as a file to disk.
+   */
+  @JvmStatic
+  fun exportArtifact(artifact: ExportableArtifact,
+                     exportAction: Consumer<OutputStream>,
+                     ideProfilerComponents: IdeProfilerComponents,
+                     ideServices: IdeProfilerServices) {
+    ideProfilerComponents.createExportDialog().open(
+      { "Export As" },
+      { artifact.exportableName },
+      { artifact.exportExtension },
+      { file: File -> ideServices.saveFile(file, { outputStream: FileOutputStream -> exportAction.accept(outputStream) }, null) }
+    )
+  }
+}
\ No newline at end of file
diff --git a/profilers-ui/src/com/android/tools/profilers/cpu/CpuCaptureArtifactView.java b/profilers-ui/src/com/android/tools/profilers/cpu/CpuCaptureArtifactView.java
index 0336c05..786bf0a 100644
--- a/profilers-ui/src/com/android/tools/profilers/cpu/CpuCaptureArtifactView.java
+++ b/profilers-ui/src/com/android/tools/profilers/cpu/CpuCaptureArtifactView.java
@@ -15,7 +15,6 @@
  */
 package com.android.tools.profilers.cpu;
 
-import com.android.tools.profilers.cpu.config.ProfilingConfiguration.TraceType;
 import com.android.tools.profilers.sessions.SessionArtifactView;
 import icons.StudioIcons;
 import org.jetbrains.annotations.NotNull;
@@ -37,14 +36,4 @@
     return buildCaptureArtifactView(getArtifact().getName(), getArtifact().getSubtitle(), StudioIcons.Profiler.Sessions.CPU,
                                     getArtifact().isOngoing());
   }
-
-  @Override
-  protected void exportArtifact() {
-    assert !getArtifact().isOngoing();
-    getSessionsView().getIdeProfilerComponents().createExportDialog().open(
-      () -> "Export As",
-      () -> CpuProfiler.generateCaptureFileName(TraceType.from(getArtifact().getArtifactProto().getConfiguration())),
-      () -> "trace",
-      file -> getArtifact().getProfilers().getIdeServices().saveFile(file, outputStream -> getArtifact().export(outputStream), null));
-  }
 }
\ No newline at end of file
diff --git a/profilers-ui/src/com/android/tools/profilers/cpu/CpuProfilerContextMenuInstaller.java b/profilers-ui/src/com/android/tools/profilers/cpu/CpuProfilerContextMenuInstaller.java
index a7feb11..d252344 100644
--- a/profilers-ui/src/com/android/tools/profilers/cpu/CpuProfilerContextMenuInstaller.java
+++ b/profilers-ui/src/com/android/tools/profilers/cpu/CpuProfilerContextMenuInstaller.java
@@ -78,7 +78,8 @@
         () -> "trace",
         file -> myStage.getStudioProfilers().getIdeServices().saveFile(
           file,
-          (output) -> CpuProfiler.saveCaptureToFile(myStage.getStudioProfilers(), getTraceIntersectingWithMouseX(x).getTraceInfo(), output),
+          (output) -> CpuProfiler.saveCaptureToFile(myStage.getStudioProfilers(), myStage.getStudioProfilers().getSession(),
+                                                    getTraceIntersectingWithMouseX(x).getTraceInfo(), output),
           null)));
     myInstaller.installGenericContextMenu(myComponent, ContextMenuItem.SEPARATOR);
   }
diff --git a/profilers-ui/src/com/android/tools/profilers/memory/HeapProfdArtifactView.java b/profilers-ui/src/com/android/tools/profilers/memory/HeapProfdArtifactView.java
index 7eca4d0..3dc9d3e 100644
--- a/profilers-ui/src/com/android/tools/profilers/memory/HeapProfdArtifactView.java
+++ b/profilers-ui/src/com/android/tools/profilers/memory/HeapProfdArtifactView.java
@@ -35,14 +35,4 @@
     return buildCaptureArtifactView(getArtifact().getName(), getArtifact().getSubtitle(), StudioIcons.Profiler.Sessions.HEAP,
                                     getArtifact().isOngoing());
   }
-
-  @Override
-  protected void exportArtifact() {
-    assert !getArtifact().isOngoing();
-    getSessionsView().getIdeProfilerComponents().createExportDialog().open(
-      () -> "Export As",
-      () -> MemoryProfiler.generateCaptureFileName(),
-      () -> "heapprofd",
-      file -> getSessionsView().getProfilers().getIdeServices().saveFile(file, outputStream -> getArtifact().export(outputStream), null));
-  }
 }
diff --git a/profilers-ui/src/com/android/tools/profilers/memory/HprofArtifactView.java b/profilers-ui/src/com/android/tools/profilers/memory/HprofArtifactView.java
index a35ba62..ab4684d 100644
--- a/profilers-ui/src/com/android/tools/profilers/memory/HprofArtifactView.java
+++ b/profilers-ui/src/com/android/tools/profilers/memory/HprofArtifactView.java
@@ -36,14 +36,4 @@
     return buildCaptureArtifactView(getArtifact().getName(), getArtifact().getSubtitle(), StudioIcons.Profiler.Sessions.HEAP,
                                     getArtifact().isOngoing());
   }
-
-  @Override
-  protected void exportArtifact() {
-    assert !getArtifact().isOngoing();
-    getSessionsView().getIdeProfilerComponents().createExportDialog().open(
-      () -> "Export As",
-      () -> MemoryProfiler.generateCaptureFileName(),
-      () -> "hprof",
-      file -> getSessionsView().getProfilers().getIdeServices().saveFile(file, outputStream -> getArtifact().export(outputStream), null));
-  }
 }
diff --git a/profilers-ui/src/com/android/tools/profilers/memory/LegacyAllocationsArtifactView.java b/profilers-ui/src/com/android/tools/profilers/memory/LegacyAllocationsArtifactView.java
index 21124e7..0910e2a 100644
--- a/profilers-ui/src/com/android/tools/profilers/memory/LegacyAllocationsArtifactView.java
+++ b/profilers-ui/src/com/android/tools/profilers/memory/LegacyAllocationsArtifactView.java
@@ -36,14 +36,4 @@
     return buildCaptureArtifactView(getArtifact().getName(), getArtifact().getSubtitle(), StudioIcons.Profiler.Sessions.ALLOCATIONS,
                                     getArtifact().isOngoing());
   }
-
-  @Override
-  protected void exportArtifact() {
-    assert !getArtifact().isOngoing();
-    getSessionsView().getIdeProfilerComponents().createExportDialog().open(
-      () -> "Export As",
-      () -> MemoryProfiler.generateCaptureFileName(),
-      () -> "alloc",
-      file -> getSessionsView().getProfilers().getIdeServices().saveFile(file, outputStream -> getArtifact().export(outputStream), null));
-  }
 }
diff --git a/profilers-ui/src/com/android/tools/profilers/sessions/SessionArtifactView.java b/profilers-ui/src/com/android/tools/profilers/sessions/SessionArtifactView.java
index 5cc9d59..be967c5 100644
--- a/profilers-ui/src/com/android/tools/profilers/sessions/SessionArtifactView.java
+++ b/profilers-ui/src/com/android/tools/profilers/sessions/SessionArtifactView.java
@@ -25,6 +25,8 @@
 import com.android.tools.adtui.stdui.DefaultContextMenuItem;
 import com.android.tools.adtui.stdui.StandardColors;
 import com.android.tools.inspectors.common.ui.ContextMenuInstaller;
+import com.android.tools.profilers.ExportArtifactUtils;
+import com.android.tools.profilers.ExportableArtifact;
 import com.android.tools.profilers.StudioProfilers;
 import com.google.common.annotations.VisibleForTesting;
 import com.intellij.util.IconUtil;
@@ -271,6 +273,11 @@
   protected abstract JComponent buildComponent();
 
   protected void exportArtifact() {
+    if (getArtifact() instanceof ExportableArtifact) {
+      assert !getArtifact().isOngoing();
+      ExportArtifactUtils.exportArtifact((ExportableArtifact)getArtifact(), getArtifact()::export,
+                                         getSessionsView().getIdeProfilerComponents(), getProfilers().getIdeServices());
+    }
   }
 
   private void showHoverState(boolean hover) {
diff --git a/profilers-ui/src/com/android/tools/profilers/sessions/SessionItemView.java b/profilers-ui/src/com/android/tools/profilers/sessions/SessionItemView.java
index ca46247..e313f98 100644
--- a/profilers-ui/src/com/android/tools/profilers/sessions/SessionItemView.java
+++ b/profilers-ui/src/com/android/tools/profilers/sessions/SessionItemView.java
@@ -25,6 +25,8 @@
 import com.android.tools.adtui.stdui.ContextMenuItem;
 import com.android.tools.adtui.stdui.DefaultContextMenuItem;
 import com.android.tools.adtui.stdui.StandardColors;
+import com.android.tools.profilers.ExportArtifactUtils;
+import com.android.tools.profilers.ExportableArtifact;
 import com.android.tools.profilers.SupportLevel;
 import com.google.common.collect.ImmutableList;
 import com.intellij.ide.BrowserUtil;
@@ -184,6 +186,23 @@
     return ImmutableList.of(endAction, ContextMenuItem.SEPARATOR, deleteAction);
   }
 
+  @Override
+  protected void exportArtifact() {
+    assert getArtifact().getCanExport();
+
+    List<SessionArtifact<?>> childArtifacts = getArtifact().getChildArtifacts();
+    assert childArtifacts.size() == 1;
+    SessionArtifact<?> artifact = childArtifacts.get(0);
+
+    assert !artifact.isOngoing();
+
+    assert artifact instanceof ExportableArtifact;
+    ExportableArtifact exportableArtifact = (ExportableArtifact) artifact;
+
+    ExportArtifactUtils.exportArtifact(exportableArtifact, artifact::export, getSessionsView().getIdeProfilerComponents(),
+                                       getProfilers().getIdeServices());
+  }
+
   /**
    * A component for rendering a green dot in {@link SessionItemView} to indicate that the session is ongoing.
    */
diff --git a/app-quality-insights/ide/testSrc/com/android/tools/idea/insights/vcs/TestUtils.kt b/profilers/src/com/android/tools/profilers/ExportableArtifact.kt
similarity index 64%
rename from app-quality-insights/ide/testSrc/com/android/tools/idea/insights/vcs/TestUtils.kt
rename to profilers/src/com/android/tools/profilers/ExportableArtifact.kt
index e890913..6c15ccb 100644
--- a/app-quality-insights/ide/testSrc/com/android/tools/idea/insights/vcs/TestUtils.kt
+++ b/profilers/src/com/android/tools/profilers/ExportableArtifact.kt
@@ -13,12 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.tools.idea.insights.vcs
+package com.android.tools.profilers
 
-import com.android.tools.idea.project.DefaultModuleSystem
-import com.android.tools.idea.projectsystem.getModuleSystem
-import com.intellij.openapi.module.Module
-
-fun Module.updateVcsInfoFlagInModel(enable: Boolean) {
-  (getModuleSystem() as DefaultModuleSystem).enableVcsInfo = enable
-}
+interface ExportableArtifact {
+  val exportableName: String
+  val exportExtension: String
+}
\ No newline at end of file
diff --git a/profilers/src/com/android/tools/profilers/StudioProfilers.java b/profilers/src/com/android/tools/profilers/StudioProfilers.java
index 6b2e094..6e5be0f 100644
--- a/profilers/src/com/android/tools/profilers/StudioProfilers.java
+++ b/profilers/src/com/android/tools/profilers/StudioProfilers.java
@@ -53,6 +53,8 @@
 import com.android.tools.profilers.memory.MemoryProfiler;
 import com.android.tools.profilers.sessions.SessionAspect;
 import com.android.tools.profilers.sessions.SessionsManager;
+import com.android.tools.profilers.tasks.ProfilerTaskType;
+import com.android.tools.profilers.tasks.taskhandlers.ProfilerTaskHandler;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
@@ -60,6 +62,7 @@
 import com.google.common.collect.Sets;
 import com.google.common.hash.Hashing;
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.text.StringUtil;
 import java.io.File;
@@ -133,6 +136,9 @@
   @NotNull
   private final IdeProfilerServices myIdeServices;
 
+  @Nullable
+  private Project myProject;
+
   /**
    * Processes from devices come from the latest update, and are filtered to include only ALIVE ones and {@code myProcess}.
    */
@@ -145,6 +151,8 @@
 
   private Map<Long, Common.Stream> myStreamIdToStreams;
 
+  private final Map<ProfilerTaskType, ProfilerTaskHandler> myTaskHandlers;
+
   @NotNull private final SessionsManager mySessionsManager;
 
   @Nullable
@@ -195,19 +203,44 @@
 
   private TransportEventPoller myTransportPoller;
 
+  @VisibleForTesting
   public StudioProfilers(@NotNull ProfilerClient client, @NotNull IdeProfilerServices ideServices) {
     this(client, ideServices, new FpsTimer(PROFILERS_UPDATE_RATE));
   }
 
+  /**
+   * Under the Task-Based UX, this constructor serves as the primary constructor to create the StudioProfilers instance for the Profiler
+   * tool window. What differentiates it from other StudioProfilers constructors is the addition of the project and taskHandlers parameters.
+   * The project is utilized to interface to the tool window code, allowing us to create and open tabs from StudioProfilers. The
+   * taskHandlers is just a map of task types to their respective handlers. These task handlers and their functionality can now be utilized
+   * in profiler-level code, not just toolwindow code where they are created.
+   */
+  public StudioProfilers(@NotNull ProfilerClient client,
+                         @NotNull IdeProfilerServices ideServices,
+                         @Nullable Project project,
+                         @NotNull HashMap<ProfilerTaskType, ProfilerTaskHandler> taskHandlers) {
+    this(client, ideServices, new FpsTimer(PROFILERS_UPDATE_RATE), project, taskHandlers);
+  }
+
   @VisibleForTesting
   public StudioProfilers(@NotNull ProfilerClient client, @NotNull IdeProfilerServices ideServices, @NotNull StopwatchTimer timer) {
+    this(client, ideServices, timer, null, new HashMap<>());
+  }
+
+  private StudioProfilers(@NotNull ProfilerClient client,
+                         @NotNull IdeProfilerServices ideServices,
+                         @NotNull StopwatchTimer timer,
+                         @Nullable Project project,
+                         @NotNull HashMap<ProfilerTaskType, ProfilerTaskHandler> taskHandlers) {
     myClient = client;
     myIdeServices = ideServices;
+    myProject = project;
     myStage = createDefaultStage();
     mySessionsManager = new SessionsManager(this);
     mySessionChangeListener = new HashMap<>();
     myDeviceToStreamIds = new HashMap<>();
     myStreamIdToStreams = new HashMap<>();
+    myTaskHandlers = taskHandlers;
     myStage.enter();
 
     myUpdater = new Updater(timer);
@@ -821,6 +854,13 @@
   }
 
   /**
+   * @return map of task types to their respective task handlers.
+   */
+  public Map<ProfilerTaskType, ProfilerTaskHandler> getTaskHandlers() {
+    return myTaskHandlers;
+  }
+
+  /**
    * Return the selected app's package name if present, otherwise returns empty string.
    * <p>
    * <p>TODO (78597376): Clean up the method to make it reusable.</p>
diff --git a/profilers/src/com/android/tools/profilers/cpu/CpuCaptureSessionArtifact.java b/profilers/src/com/android/tools/profilers/cpu/CpuCaptureSessionArtifact.java
index 73fbe27..39ec41b 100644
--- a/profilers/src/com/android/tools/profilers/cpu/CpuCaptureSessionArtifact.java
+++ b/profilers/src/com/android/tools/profilers/cpu/CpuCaptureSessionArtifact.java
@@ -19,7 +19,9 @@
 import com.android.tools.adtui.model.formatter.TimeFormatter;
 import com.android.tools.profiler.proto.Common;
 import com.android.tools.profiler.proto.Trace;
+import com.android.tools.profilers.ExportableArtifact;
 import com.android.tools.profilers.StudioProfilers;
+import com.android.tools.profilers.cpu.config.ProfilingConfiguration;
 import com.android.tools.profilers.sessions.SessionArtifact;
 import java.io.OutputStream;
 import java.util.ArrayList;
@@ -30,7 +32,7 @@
 /**
  * An artifact representation of a CPU capture.
  */
-public class CpuCaptureSessionArtifact implements SessionArtifact<Trace.TraceInfo> {
+public class CpuCaptureSessionArtifact implements SessionArtifact<Trace.TraceInfo>, ExportableArtifact {
 
   @NotNull private final StudioProfilers myProfilers;
   @NotNull private final Common.Session mySession;
@@ -165,7 +167,19 @@
   @Override
   public void export(@NotNull OutputStream outputStream) {
     assert getCanExport();
-    CpuProfiler.saveCaptureToFile(myProfilers, getArtifactProto(), outputStream);
+    CpuProfiler.saveCaptureToFile(myProfilers, getSession(), getArtifactProto(), outputStream);
+  }
+
+  @NotNull
+  @Override
+  public String getExportableName() {
+    return CpuProfiler.generateCaptureFileName(ProfilingConfiguration.TraceType.from(getArtifactProto().getConfiguration()));
+  }
+
+  @NotNull
+  @Override
+  public String getExportExtension() {
+    return "trace";
   }
 
   private boolean isImportedSession() {
diff --git a/profilers/src/com/android/tools/profilers/cpu/CpuProfiler.java b/profilers/src/com/android/tools/profilers/cpu/CpuProfiler.java
index c0c84b3..475a9c1 100644
--- a/profilers/src/com/android/tools/profilers/cpu/CpuProfiler.java
+++ b/profilers/src/com/android/tools/profilers/cpu/CpuProfiler.java
@@ -172,11 +172,14 @@
   /**
    * Copies the content of the trace file corresponding to a {@link CpuTraceInfo} to a given {@link FileOutputStream}.
    */
-  static void saveCaptureToFile(@NotNull StudioProfilers profilers, @NotNull TraceInfo info, @NotNull OutputStream outputStream) {
+  static void saveCaptureToFile(@NotNull StudioProfilers profilers,
+                                @NotNull Common.Session session,
+                                @NotNull TraceInfo info,
+                                @NotNull OutputStream outputStream) {
 
     try {
       Transport.BytesRequest traceRequest = Transport.BytesRequest.newBuilder()
-        .setStreamId(profilers.getSession().getStreamId())
+        .setStreamId(session.getStreamId())
         .setId(String.valueOf(info.getTraceId()))
         .build();
       Transport.BytesResponse traceResponse = profilers.getClient().getTransportClient().getBytes(traceRequest);
diff --git a/profilers/src/com/android/tools/profilers/memory/HeapProfdSessionArtifact.java b/profilers/src/com/android/tools/profilers/memory/HeapProfdSessionArtifact.java
index 012ff5f..a309fcd 100644
--- a/profilers/src/com/android/tools/profilers/memory/HeapProfdSessionArtifact.java
+++ b/profilers/src/com/android/tools/profilers/memory/HeapProfdSessionArtifact.java
@@ -29,6 +29,7 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 import org.jetbrains.annotations.NotNull;
 
 public class HeapProfdSessionArtifact extends MemorySessionArtifact<Trace.TraceInfo> {
@@ -63,6 +64,18 @@
     }
   }
 
+  @NotNull
+  @Override
+  public String getExportableName() {
+    return MemoryProfiler.generateCaptureFileName();
+  }
+
+  @NotNull
+  @Override
+  public String getExportExtension() {
+    return "heapprofd";
+  }
+
   public static List<SessionArtifact<?>> getSessionArtifacts(@NotNull StudioProfilers profilers,
                                                           @NotNull Common.Session session,
                                                           @NotNull Common.SessionMetaData sessionMetaData) {
diff --git a/profilers/src/com/android/tools/profilers/memory/HprofSessionArtifact.java b/profilers/src/com/android/tools/profilers/memory/HprofSessionArtifact.java
index 8dc6c24..759d4a9 100644
--- a/profilers/src/com/android/tools/profilers/memory/HprofSessionArtifact.java
+++ b/profilers/src/com/android/tools/profilers/memory/HprofSessionArtifact.java
@@ -24,9 +24,11 @@
 import com.android.tools.profilers.memory.adapters.CaptureObject;
 import com.android.tools.profilers.sessions.SessionArtifact;
 import com.intellij.util.containers.ContainerUtil;
+import java.io.File;
 import java.io.OutputStream;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 import org.jetbrains.annotations.NotNull;
 
 /**
@@ -59,6 +61,18 @@
                        getProfilers().getIdeServices().getFeatureTracker());
   }
 
+  @NotNull
+  @Override
+  public String getExportableName() {
+    return MemoryProfiler.generateCaptureFileName();
+  }
+
+  @NotNull
+  @Override
+  public String getExportExtension() {
+    return "hprof";
+  }
+
   public static List<SessionArtifact<?>> getSessionArtifacts(@NotNull StudioProfilers profilers,
                                                              @NotNull Common.Session session,
                                                              @NotNull Common.SessionMetaData sessionMetaData) {
diff --git a/profilers/src/com/android/tools/profilers/memory/LegacyAllocationsSessionArtifact.java b/profilers/src/com/android/tools/profilers/memory/LegacyAllocationsSessionArtifact.java
index 22358ec..f840fa6 100644
--- a/profilers/src/com/android/tools/profilers/memory/LegacyAllocationsSessionArtifact.java
+++ b/profilers/src/com/android/tools/profilers/memory/LegacyAllocationsSessionArtifact.java
@@ -21,6 +21,7 @@
 import com.android.tools.adtui.model.formatter.TimeFormatter;
 import com.android.tools.profiler.proto.Common;
 import com.android.tools.profiler.proto.Memory;
+import com.android.tools.profilers.ExportableArtifact;
 import com.android.tools.profilers.StudioProfilers;
 import com.android.tools.profilers.sessions.SessionArtifact;
 import java.io.OutputStream;
@@ -30,7 +31,7 @@
 /**
  * A session artifact representation of a memory allocation recording (legacy).
  */
-public class LegacyAllocationsSessionArtifact implements SessionArtifact<Memory.AllocationsInfo> {
+public class LegacyAllocationsSessionArtifact implements SessionArtifact<Memory.AllocationsInfo>, ExportableArtifact {
 
   @NotNull private final StudioProfilers myProfilers;
   @NotNull private final Common.Session mySession;
@@ -137,4 +138,16 @@
     assert getCanExport();
     saveLegacyAllocationToFile(myProfilers.getClient(), mySession, myInfo, outputStream, myProfilers.getIdeServices().getFeatureTracker());
   }
+
+  @NotNull
+  @Override
+  public String getExportableName() {
+    return MemoryProfiler.generateCaptureFileName();
+  }
+
+  @NotNull
+  @Override
+  public String getExportExtension() {
+    return "alloc";
+  }
 }
diff --git a/profilers/src/com/android/tools/profilers/memory/MemorySessionArtifact.java b/profilers/src/com/android/tools/profilers/memory/MemorySessionArtifact.java
index 150f1bf..e53a79d 100644
--- a/profilers/src/com/android/tools/profilers/memory/MemorySessionArtifact.java
+++ b/profilers/src/com/android/tools/profilers/memory/MemorySessionArtifact.java
@@ -19,6 +19,7 @@
 import com.android.tools.adtui.model.formatter.TimeFormatter;
 import com.android.tools.idea.protobuf.GeneratedMessageV3;
 import com.android.tools.profiler.proto.Common;
+import com.android.tools.profilers.ExportableArtifact;
 import com.android.tools.profilers.StudioProfilers;
 import com.android.tools.profilers.sessions.SessionArtifact;
 import java.util.concurrent.TimeUnit;
@@ -27,7 +28,7 @@
 /**
  * An artifact representation of a memory capture.
  */
-public abstract class MemorySessionArtifact<T extends GeneratedMessageV3> implements SessionArtifact<T> {
+public abstract class MemorySessionArtifact<T extends GeneratedMessageV3> implements SessionArtifact<T>, ExportableArtifact {
 
   @NotNull private final StudioProfilers myProfilers;
   @NotNull private final Common.Session mySession;
diff --git a/profilers/src/com/android/tools/profilers/sessions/SessionItem.kt b/profilers/src/com/android/tools/profilers/sessions/SessionItem.kt
index 40da324..7c02df5 100644
--- a/profilers/src/com/android/tools/profilers/sessions/SessionItem.kt
+++ b/profilers/src/com/android/tools/profilers/sessions/SessionItem.kt
@@ -24,6 +24,7 @@
 import com.android.tools.profilers.StudioMonitorStage
 import com.android.tools.profilers.StudioProfilers
 import com.google.common.annotations.VisibleForTesting
+import java.io.OutputStream
 import java.util.concurrent.TimeUnit
 
 /**
@@ -69,7 +70,18 @@
   override val isOngoing
     get() = SessionsManager.isSessionAlive(activeSession)
 
-  override val canExport = false
+  /**
+   * The MEMORY_CAPTURE and CPU_CAPTURE session types are indicative of imported memory and CPU sessions respectively.
+   */
+  override val canExport = sessionMetaData.type == SessionMetaData.SessionType.MEMORY_CAPTURE
+                           || sessionMetaData.type == SessionMetaData.SessionType.CPU_CAPTURE
+
+  override fun export(outputStream: OutputStream) {
+    assert(canExport)
+    assert(childArtifacts.size == 1)
+    val artifact = childArtifacts.first()
+    artifact.export(outputStream)
+  }
 
   /**
    * Update the [Common.Session] object. Note that while the content within the session can change, the new session instance should
diff --git a/profilers/src/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/CallstackSampleTaskHandler.kt b/profilers/src/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/CallstackSampleTaskHandler.kt
new file mode 100644
index 0000000..254564d
--- /dev/null
+++ b/profilers/src/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/CallstackSampleTaskHandler.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.profilers.tasks.taskhandlers.singleartifact.cpu
+
+import com.android.tools.profilers.cpu.CpuCaptureSessionArtifact
+import com.android.tools.profilers.cpu.config.SimpleperfConfiguration
+import com.android.tools.profilers.sessions.SessionArtifact
+import com.android.tools.profilers.sessions.SessionsManager
+
+class CallstackSampleTaskHandler(sessionsManager: SessionsManager) : CpuTaskHandler(sessionsManager) {
+  override fun getCpuRecordingConfig() = SimpleperfConfiguration(getTaskName())
+
+  override fun supportsArtifact(artifact: SessionArtifact<*>?) =
+    artifact is CpuCaptureSessionArtifact
+    && artifact.artifactProto.hasConfiguration()
+    && artifact.artifactProto.configuration.hasSimpleperfOptions()
+
+  override fun getTaskName() = "Callstack Sample"
+}
\ No newline at end of file
diff --git a/profilers/src/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/CpuTaskHandler.kt b/profilers/src/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/CpuTaskHandler.kt
new file mode 100644
index 0000000..d8d0a36
--- /dev/null
+++ b/profilers/src/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/CpuTaskHandler.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.profilers.tasks.taskhandlers.singleartifact.cpu
+
+import com.android.tools.profiler.proto.Common
+import com.android.tools.profilers.cpu.CpuCaptureSessionArtifact
+import com.android.tools.profilers.cpu.CpuProfilerStage
+import com.android.tools.profilers.cpu.config.ProfilingConfiguration
+import com.android.tools.profilers.sessions.SessionItem
+import com.android.tools.profilers.sessions.SessionsManager
+import com.android.tools.profilers.tasks.args.TaskArgs
+import com.android.tools.profilers.tasks.args.singleartifact.cpu.CpuTaskArgs
+import com.android.tools.profilers.tasks.taskhandlers.TaskHandlerUtils.findTaskArtifact
+import com.android.tools.profilers.tasks.taskhandlers.singleartifact.SingleArtifactTaskHandler
+import com.intellij.util.asSafely
+
+abstract class CpuTaskHandler(private val sessionsManager: SessionsManager) : SingleArtifactTaskHandler<CpuProfilerStage>(sessionsManager) {
+  override fun setupStage() {
+    val studioProfilers = sessionsManager.studioProfilers
+    val stage = CpuProfilerStage(studioProfilers, this::stopTask)
+    stage.profilerConfigModel.profilingConfiguration = getCpuRecordingConfig()
+    studioProfilers.stage = stage
+    super.stage = stage
+  }
+
+  override fun startCapture(stage: CpuProfilerStage) {
+    stage.startCpuRecording()
+  }
+
+  override fun stopCapture(stage: CpuProfilerStage) {
+    stage.stopCpuRecording()
+  }
+
+  override fun loadTask(args: TaskArgs?): Boolean {
+    if (args !is CpuTaskArgs) {
+      handleError("The task arguments (TaskArgs) supplied are not of the expected type (CpuTaskArgs)")
+      return false
+    }
+    loadCapture(args.getCpuCaptureArtifact())
+    return true
+  }
+
+  override fun createArgs(
+    sessionItems: Map<Long, SessionItem>,
+    selectedSession: Common.Session
+  ): CpuTaskArgs? {
+    val artifact = findTaskArtifact(selectedSession, sessionItems, ::supportsArtifact)
+
+    // Only if the underlying artifact is non-null should the TaskArgs be non-null
+    return if (supportsArtifact(artifact)) {
+      artifact.asSafely<CpuCaptureSessionArtifact>()?.let { CpuTaskArgs(it) }
+    }
+    else {
+      null
+    }
+  }
+
+  protected abstract fun getCpuRecordingConfig(): ProfilingConfiguration
+}
\ No newline at end of file
diff --git a/profilers/src/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/JavaKotlinMethodSampleTaskHandler.kt b/profilers/src/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/JavaKotlinMethodSampleTaskHandler.kt
new file mode 100644
index 0000000..3973d0d
--- /dev/null
+++ b/profilers/src/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/JavaKotlinMethodSampleTaskHandler.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.profilers.tasks.taskhandlers.singleartifact.cpu
+
+import com.android.tools.profilers.cpu.CpuCaptureSessionArtifact
+import com.android.tools.profilers.cpu.config.ArtSampledConfiguration
+import com.android.tools.profilers.sessions.SessionArtifact
+import com.android.tools.profilers.sessions.SessionsManager
+
+class JavaKotlinMethodSampleTaskHandler(sessionsManager: SessionsManager) : CpuTaskHandler(sessionsManager) {
+  override fun getCpuRecordingConfig() = ArtSampledConfiguration(getTaskName())
+
+  override fun supportsArtifact(artifact: SessionArtifact<*>?) =
+    artifact is CpuCaptureSessionArtifact
+    && artifact.artifactProto.hasConfiguration()
+    && artifact.artifactProto.configuration.hasArtOptions()
+
+  override fun getTaskName() = "Java/Kotlin Method Sample (legacy)"
+}
\ No newline at end of file
diff --git a/profilers/src/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/JavaKotlinMethodTraceTaskHandler.kt b/profilers/src/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/JavaKotlinMethodTraceTaskHandler.kt
new file mode 100644
index 0000000..d932078
--- /dev/null
+++ b/profilers/src/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/JavaKotlinMethodTraceTaskHandler.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.profilers.tasks.taskhandlers.singleartifact.cpu
+
+import com.android.tools.profilers.cpu.CpuCaptureSessionArtifact
+import com.android.tools.profilers.cpu.config.ArtInstrumentedConfiguration
+import com.android.tools.profilers.sessions.SessionArtifact
+import com.android.tools.profilers.sessions.SessionsManager
+
+class JavaKotlinMethodTraceTaskHandler(sessionsManager: SessionsManager) : CpuTaskHandler(sessionsManager) {
+  override fun getCpuRecordingConfig() = ArtInstrumentedConfiguration(getTaskName())
+
+  override fun supportsArtifact(artifact: SessionArtifact<*>?) =
+    artifact is CpuCaptureSessionArtifact
+    && artifact.artifactProto.hasConfiguration()
+    && artifact.artifactProto.configuration.hasArtOptions()
+
+  override fun getTaskName() = "Java/Kotlin Method Trace"
+}
\ No newline at end of file
diff --git a/profilers/src/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/SystemTraceTaskHandler.kt b/profilers/src/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/SystemTraceTaskHandler.kt
new file mode 100644
index 0000000..fed0f97
--- /dev/null
+++ b/profilers/src/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/SystemTraceTaskHandler.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.profilers.tasks.taskhandlers.singleartifact.cpu
+
+import com.android.tools.profilers.cpu.CpuCaptureSessionArtifact
+import com.android.tools.profilers.cpu.config.PerfettoConfiguration
+import com.android.tools.profilers.sessions.SessionArtifact
+import com.android.tools.profilers.sessions.SessionsManager
+
+class SystemTraceTaskHandler(sessionsManager: SessionsManager) : CpuTaskHandler(sessionsManager) {
+  override fun getCpuRecordingConfig() = PerfettoConfiguration(getTaskName(), false)
+
+  override fun supportsArtifact(artifact: SessionArtifact<*>?) =
+    artifact is CpuCaptureSessionArtifact
+    && artifact.artifactProto.hasConfiguration()
+    && (artifact.artifactProto.configuration.hasPerfettoOptions() || artifact.artifactProto.configuration.hasAtraceOptions())
+
+  override fun getTaskName() = "System Trace"
+}
\ No newline at end of file
diff --git a/profilers/testSrc/com/android/tools/profilers/tasks/taskhandlers/TaskHandlerTestUtils.kt b/profilers/testSrc/com/android/tools/profilers/tasks/taskhandlers/TaskHandlerTestUtils.kt
index 5f501e5..07ee822 100644
--- a/profilers/testSrc/com/android/tools/profilers/tasks/taskhandlers/TaskHandlerTestUtils.kt
+++ b/profilers/testSrc/com/android/tools/profilers/tasks/taskhandlers/TaskHandlerTestUtils.kt
@@ -35,14 +35,37 @@
 
 object TaskHandlerTestUtils {
 
+  fun createCpuCaptureSessionArtifactWithConfig(profilers: StudioProfilers,
+                                                session: Common.Session,
+                                                sessionId: Long,
+                                                traceId: Long,
+                                                config: Trace.TraceConfiguration) = createCpuCaptureSessionArtifactWithConfig(profilers,
+                                                                                                                              session,
+                                                                                                                              sessionId,
+                                                                                                                              traceId, 0, 0,
+                                                                                                                              config)
+
+  /**
+   * Overload of createCpuCaptureSessionArtifactWithConfig that takes in from and end timestamps.
+   */
+  fun createCpuCaptureSessionArtifactWithConfig(profilers: StudioProfilers,
+                                                session: Common.Session,
+                                                sessionId: Long,
+                                                traceId: Long,
+                                                fromTimestamp: Long,
+                                                toTimestamp: Long,
+                                                config: Trace.TraceConfiguration): CpuCaptureSessionArtifact {
+    val sessionMetadata = Common.SessionMetaData.newBuilder().setSessionId(sessionId).build()
+    val info = Trace.TraceInfo.newBuilder().setFromTimestamp(fromTimestamp).setToTimestamp(toTimestamp).setTraceId(
+      traceId).setConfiguration(config.toBuilder()).build()
+    return CpuCaptureSessionArtifact(profilers, session, sessionMetadata, info)
+  }
+
   fun createCpuCaptureSessionArtifact(profilers: StudioProfilers,
                                       session: Common.Session,
                                       sessionId: Long,
-                                      traceId: Long): CpuCaptureSessionArtifact {
-    val sessionMetadata = Common.SessionMetaData.newBuilder().setSessionId(sessionId).build()
-    val info = Trace.TraceInfo.newBuilder().setTraceId(traceId).build()
-    return CpuCaptureSessionArtifact(profilers, session, sessionMetadata, info)
-  }
+                                      traceId: Long) = createCpuCaptureSessionArtifactWithConfig(profilers, session, sessionId, traceId,
+                                                                                                 Trace.TraceConfiguration.getDefaultInstance())
 
   fun createHprofSessionArtifact(profilers: StudioProfilers, session: Common.Session,
                                  startTimestamp: Long,
diff --git a/profilers/testSrc/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/CallstackSampleTaskHandlerTest.kt b/profilers/testSrc/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/CallstackSampleTaskHandlerTest.kt
new file mode 100644
index 0000000..b358f39
--- /dev/null
+++ b/profilers/testSrc/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/CallstackSampleTaskHandlerTest.kt
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.profilers.tasks.taskhandlers.singleartifact.cpu
+
+import com.android.tools.adtui.model.FakeTimer
+import com.android.tools.idea.transport.faketransport.FakeGrpcChannel
+import com.android.tools.idea.transport.faketransport.FakeTransportService
+import com.android.tools.idea.transport.faketransport.commands.StartTrace
+import com.android.tools.idea.transport.faketransport.commands.StopTrace
+import com.android.tools.profiler.proto.Commands
+import com.android.tools.profiler.proto.Common
+import com.android.tools.profiler.proto.Common.Process.ExposureLevel
+import com.android.tools.profiler.proto.Trace
+import com.android.tools.profilers.FakeIdeProfilerServices
+import com.android.tools.profilers.ProfilerClient
+import com.android.tools.profilers.StudioProfilers
+import com.android.tools.profilers.cpu.CpuProfilerStage
+import com.android.tools.profilers.event.FakeEventService
+import com.android.tools.profilers.memory.HeapProfdSessionArtifact
+import com.android.tools.profilers.sessions.SessionsManager
+import com.android.tools.profilers.tasks.args.singleartifact.cpu.CpuTaskArgs
+import com.android.tools.profilers.tasks.taskhandlers.TaskHandlerTestUtils
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import kotlin.test.assertFailsWith
+
+@RunWith(Parameterized::class)
+class CallstackSampleTaskHandlerTest(private val myExposureLevel: ExposureLevel) {
+  private val myTimer = FakeTimer()
+  private val myTransportService = FakeTransportService(myTimer, false)
+
+  @get:Rule
+  var myGrpcChannel = FakeGrpcChannel("CallstackSampleTaskHandlerTestChannel", myTransportService, FakeEventService())
+
+  private lateinit var myProfilers: StudioProfilers
+  private lateinit var ideProfilerServices: FakeIdeProfilerServices
+  private lateinit var myManager: SessionsManager
+  private lateinit var myCallstackSampleTaskHandler: CallstackSampleTaskHandler
+
+  @Before
+  fun setup() {
+    ideProfilerServices = FakeIdeProfilerServices()
+    myProfilers = StudioProfilers(
+      ProfilerClient(myGrpcChannel.channel),
+      ideProfilerServices,
+      myTimer
+    )
+    myManager = myProfilers.sessionsManager
+    myCallstackSampleTaskHandler = CallstackSampleTaskHandler(myManager)
+    assertThat(myManager.sessionArtifacts).isEmpty()
+    assertThat(myManager.selectedSession).isEqualTo(Common.Session.getDefaultInstance())
+    assertThat(myManager.profilingSession).isEqualTo(Common.Session.getDefaultInstance())
+    ideProfilerServices.enableTaskBasedUx(true)
+  }
+
+  @Test
+  fun testSupportsArtifactWithCallstackSampleSessionArtifact() {
+    val callstackSampleSessionArtifact = TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers,
+                                                                                                        Common.Session.getDefaultInstance(),
+                                                                                                        1L, 100L,
+                                                                                                        createDefaultSimpleperfTraceConfiguration())
+    assertThat(myCallstackSampleTaskHandler.supportsArtifact(callstackSampleSessionArtifact)).isTrue()
+  }
+
+  @Test
+  fun testSupportsArtifactWithNonCallstackSampleSessionArtifact() {
+    val heapProfdSessionArtifact = HeapProfdSessionArtifact(myProfilers, Common.Session.getDefaultInstance(),
+                                                            Common.SessionMetaData.getDefaultInstance(),
+                                                            Trace.TraceInfo.getDefaultInstance())
+    assertThat(myCallstackSampleTaskHandler.supportsArtifact(heapProfdSessionArtifact)).isFalse()
+  }
+
+  @Test
+  fun testStartTaskInvokedOnEnterWithAliveSession() {
+    TaskHandlerTestUtils.startSession(myExposureLevel, myProfilers, myTransportService, myTimer)
+    val callstackSampleSessionArtifact = TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers,
+                                                                                                        Common.Session.getDefaultInstance(),
+                                                                                                        1L,
+                                                                                                        100L,
+                                                                                                        createDefaultSimpleperfTraceConfiguration())
+    val cpuTaskArgs = CpuTaskArgs(callstackSampleSessionArtifact)
+    myCallstackSampleTaskHandler.enter(cpuTaskArgs)
+    // The session is alive, so startTask and thus startCapture should be called.
+    assertThat(myCallstackSampleTaskHandler.stage!!.recordingModel.isRecording)
+  }
+
+  @Test
+  fun testStartTaskWithSetStage() {
+    TaskHandlerTestUtils.startSession(myExposureLevel, myProfilers, myTransportService, myTimer)
+    // To start the task and thus the capture, the stage must be set up before. This will be taken care of via the setupStage() method call,
+    // on enter of the task handler, but this test is testing the explicit invocation of startTask.
+    myCallstackSampleTaskHandler.setupStage()
+    myCallstackSampleTaskHandler.startTask()
+    assertThat(myCallstackSampleTaskHandler.stage!!.recordingModel.isRecording).isTrue()
+  }
+
+  @Test
+  fun testStartTaskWithUnsetStage() {
+    // To start the task and thus the capture, the stage must be set up before. Here we will test the case where startTask is invoked
+    // without the stage being set precondition being met.
+    val exception = assertFailsWith<Throwable> {
+      myCallstackSampleTaskHandler.startTask()
+    }
+    assertThat(myCallstackSampleTaskHandler.stage).isNull()
+    assertThat(exception.message).isEqualTo(
+      "There was an error with the Callstack Sample task. Error message: Cannot start the task as the InterimStage was null.")
+  }
+
+  @Test
+  fun testStopTaskSuccessfullyTerminatesRecording() {
+    TaskHandlerTestUtils.startSession(myExposureLevel, myProfilers, myTransportService, myTimer)
+    // First start the task successfully.
+    (myTransportService.getRegisteredCommand(Commands.Command.CommandType.START_TRACE) as StartTrace)
+      .startStatus = Trace.TraceStartStatus.newBuilder()
+      .setStatus(Trace.TraceStartStatus.Status.SUCCESS)
+      .build()
+    myCallstackSampleTaskHandler.setupStage()
+    myCallstackSampleTaskHandler.startTask()
+    assertThat(myCallstackSampleTaskHandler.stage!!.recordingModel.isRecording).isTrue()
+
+    // Wait for successful start event to be consumed.
+    myTimer.tick(FakeTimer.ONE_SECOND_IN_NS)
+    // Stop the task successfully.
+    (myTransportService.getRegisteredCommand(Commands.Command.CommandType.STOP_TRACE) as StopTrace)
+      .stopStatus = Trace.TraceStopStatus.newBuilder()
+      .setStatus(Trace.TraceStopStatus.Status.SUCCESS)
+      .build()
+    myCallstackSampleTaskHandler.stopTask()
+    // Wait for successful end event to be consumed.
+    myTimer.tick(FakeTimer.ONE_SECOND_IN_NS)
+    assertThat(myCallstackSampleTaskHandler.stage!!.recordingModel.isRecording).isFalse()
+  }
+
+  @Test
+  fun testLoadTaskInvokedOnEnterWithDeadSession() {
+    TaskHandlerTestUtils.startAndStopSession(myExposureLevel, myProfilers, myManager, myTransportService, myTimer)
+
+    // Before enter + loadTask, the stage should not be set yet.
+    assertThat(myProfilers.stage).isNotInstanceOf(CpuProfilerStage::class.java)
+
+    // Create a fake CpuCaptureSessionArtifact that uses a Simplperf (Callstack Sample) configuration.
+    val callstackSampleSessionArtifact = TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers,
+                                                                                                        Common.Session.getDefaultInstance(),
+                                                                                                        1L,
+                                                                                                        100L,
+                                                                                                        createDefaultSimpleperfTraceConfiguration())
+    val cpuTaskArgs = CpuTaskArgs(callstackSampleSessionArtifact)
+    // The session is not alive (dead) so loadTask and thus loadCapture should be called.
+    val argsSuccessfullyUsed = myCallstackSampleTaskHandler.enter(cpuTaskArgs)
+    assertThat(argsSuccessfullyUsed).isTrue()
+
+    // Verify that the artifact doSelect behavior is called by checking if the stage was set to CpuProfilerStage.
+    assertThat(myProfilers.stage).isInstanceOf(CpuProfilerStage::class.java)
+  }
+
+  @Test
+  fun testLoadTaskWithNonNullTaskArgs() {
+    TaskHandlerTestUtils.startAndStopSession(myExposureLevel, myProfilers, myManager, myTransportService, myTimer)
+
+    // Before enter + loadTask, the stage should not be set yet.
+    assertThat(myProfilers.stage).isNotInstanceOf(CpuProfilerStage::class.java)
+
+    val callstackSampleSessionArtifact = TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers,
+                                                                                                        Common.Session.getDefaultInstance(),
+                                                                                                        1L,
+                                                                                                        100L,
+                                                                                                        createDefaultSimpleperfTraceConfiguration())
+    val cpuTaskArgs = CpuTaskArgs(callstackSampleSessionArtifact)
+    val argsSuccessfullyUsed = myCallstackSampleTaskHandler.loadTask(cpuTaskArgs)
+    assertThat(argsSuccessfullyUsed).isTrue()
+
+    // Verify that the artifact doSelect behavior was called by checking if the stage was set to CpuProfilerStage.
+    assertThat(myProfilers.stage).isInstanceOf(CpuProfilerStage::class.java)
+  }
+
+  @Test
+  fun testLoadTaskWithNullTaskArgs() {
+    TaskHandlerTestUtils.startAndStopSession(myExposureLevel, myProfilers, myManager, myTransportService, myTimer)
+
+    // Before enter + loadTask, the stage should not be set yet.
+    assertThat(myProfilers.stage).isNotInstanceOf(CpuProfilerStage::class.java)
+
+    val exception = assertFailsWith<Throwable> {
+      myCallstackSampleTaskHandler.loadTask(null)
+    }
+
+    assertThat(exception.message).isEqualTo(
+      "There was an error with the Callstack Sample task. Error message: The task arguments (TaskArgs) supplied are not of the expected " +
+      "type (CpuTaskArgs).")
+
+    // Verify that the artifact doSelect behavior was not called by checking if the stage was not set to CpuProfilerStage.
+    assertThat(myProfilers.stage).isNotInstanceOf(CpuProfilerStage::class.java)
+  }
+
+  @Test
+  fun testCreateArgsSuccessfully() {
+    val selectedSession = Common.Session.newBuilder().setSessionId(1).setEndTimestamp(100).build()
+    val sessionIdToSessionItems = mapOf(
+      1L to TaskHandlerTestUtils.createSessionItem(myProfilers, selectedSession, 1, listOf(
+        TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers, selectedSession, 1, 100L,
+                                                                       5L, 500L,
+                                                                       createDefaultSimpleperfTraceConfiguration()))),
+    )
+
+    val cpuTaskArgs = myCallstackSampleTaskHandler.createArgs(sessionIdToSessionItems, selectedSession)
+    assertThat(cpuTaskArgs).isNotNull()
+    assertThat(cpuTaskArgs).isInstanceOf(CpuTaskArgs::class.java)
+    assertThat(cpuTaskArgs!!.getCpuCaptureArtifact()).isNotNull()
+    assertThat(cpuTaskArgs.getCpuCaptureArtifact().artifactProto.configuration.hasSimpleperfOptions()).isTrue()
+    assertThat(cpuTaskArgs.getCpuCaptureArtifact().artifactProto.fromTimestamp).isEqualTo(5L)
+    assertThat(cpuTaskArgs.getCpuCaptureArtifact().artifactProto.toTimestamp).isEqualTo(500L)
+  }
+
+  @Test
+  fun testCreateArgsFails() {
+    // By setting a session id that does not match any of the session items, the task artifact will not be found in the call to createArgs
+    // will fail to be constructed.
+    val selectedSession = Common.Session.newBuilder().setSessionId(0).setEndTimestamp(100).build()
+    val sessionIdToSessionItems = mapOf(
+      1L to TaskHandlerTestUtils.createSessionItem(myProfilers, selectedSession, 1, listOf(
+        TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers, selectedSession, 1, 100L,
+                                                                       5L, 500L,
+                                                                       createDefaultSimpleperfTraceConfiguration()))),
+    )
+
+    val cpuTaskArgs = myCallstackSampleTaskHandler.createArgs(sessionIdToSessionItems, selectedSession)
+    // A return value of null indicates the task args were not constructed correctly (the underlying artifact was not found or supported by
+    // the task).
+    assertThat(cpuTaskArgs).isNull()
+  }
+
+  @Test
+  fun testGetTaskName() {
+    assertThat(myCallstackSampleTaskHandler.getTaskName()).isEqualTo("Callstack Sample")
+  }
+
+  private fun createDefaultSimpleperfTraceConfiguration() = Trace.TraceConfiguration.newBuilder().setSimpleperfOptions(
+    Trace.SimpleperfOptions.getDefaultInstance()).build()
+
+  companion object {
+    @JvmStatic
+    @Parameterized.Parameters
+    fun data(): Collection<ExposureLevel> {
+      return listOf(ExposureLevel.DEBUGGABLE, ExposureLevel.PROFILEABLE)
+    }
+  }
+}
\ No newline at end of file
diff --git a/profilers/testSrc/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/JavaKotlinMethodSampleTaskHandlerTest.kt b/profilers/testSrc/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/JavaKotlinMethodSampleTaskHandlerTest.kt
new file mode 100644
index 0000000..2b3fa6f
--- /dev/null
+++ b/profilers/testSrc/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/JavaKotlinMethodSampleTaskHandlerTest.kt
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.profilers.tasks.taskhandlers.singleartifact.cpu
+
+import com.android.tools.adtui.model.FakeTimer
+import com.android.tools.idea.transport.faketransport.FakeGrpcChannel
+import com.android.tools.idea.transport.faketransport.FakeTransportService
+import com.android.tools.idea.transport.faketransport.commands.StartTrace
+import com.android.tools.idea.transport.faketransport.commands.StopTrace
+import com.android.tools.profiler.proto.Commands
+import com.android.tools.profiler.proto.Common
+import com.android.tools.profiler.proto.Common.Process.ExposureLevel
+import com.android.tools.profiler.proto.Trace
+import com.android.tools.profiler.proto.Trace.TraceMode
+import com.android.tools.profilers.FakeIdeProfilerServices
+import com.android.tools.profilers.ProfilerClient
+import com.android.tools.profilers.StudioProfilers
+import com.android.tools.profilers.cpu.CpuProfilerStage
+import com.android.tools.profilers.event.FakeEventService
+import com.android.tools.profilers.memory.HeapProfdSessionArtifact
+import com.android.tools.profilers.sessions.SessionsManager
+import com.android.tools.profilers.tasks.args.singleartifact.cpu.CpuTaskArgs
+import com.android.tools.profilers.tasks.taskhandlers.TaskHandlerTestUtils
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import kotlin.test.assertFailsWith
+
+@RunWith(Parameterized::class)
+class JavaKotlinMethodSampleTaskHandlerTest(private val myExposureLevel: ExposureLevel) {
+  private val myTimer = FakeTimer()
+  private val myTransportService = FakeTransportService(myTimer, false)
+
+  @get:Rule
+  var myGrpcChannel = FakeGrpcChannel("JavaKotlinMethodSampleTaskHandlerTestChannel", myTransportService, FakeEventService())
+
+  private lateinit var myProfilers: StudioProfilers
+  private lateinit var ideProfilerServices: FakeIdeProfilerServices
+  private lateinit var myManager: SessionsManager
+  private lateinit var myJavaKotlinMethodSampleTaskHandler: JavaKotlinMethodSampleTaskHandler
+
+  @Before
+  fun setup() {
+    ideProfilerServices = FakeIdeProfilerServices()
+    myProfilers = StudioProfilers(
+      ProfilerClient(myGrpcChannel.channel),
+      ideProfilerServices,
+      myTimer
+    )
+    myManager = myProfilers.sessionsManager
+    myJavaKotlinMethodSampleTaskHandler = JavaKotlinMethodSampleTaskHandler(myManager)
+    assertThat(myManager.sessionArtifacts).isEmpty()
+    assertThat(myManager.selectedSession).isEqualTo(Common.Session.getDefaultInstance())
+    assertThat(myManager.profilingSession).isEqualTo(Common.Session.getDefaultInstance())
+    ideProfilerServices.enableTaskBasedUx(true)
+  }
+
+  @Test
+  fun testSupportsArtifactWithJavaKotlinMethodSampleSessionArtifact() {
+    val javaKotlinMethodSampleSessionArtifact = TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers,
+                                                                                                               Common.Session.getDefaultInstance(),
+                                                                                                               1L, 100L,
+                                                                                                               createDefaultArtSampleTraceConfiguration())
+    assertThat(myJavaKotlinMethodSampleTaskHandler.supportsArtifact(javaKotlinMethodSampleSessionArtifact)).isTrue()
+  }
+
+  @Test
+  fun testSupportsArtifactWithNonJavaKotlinMethodSampleSessionArtifact() {
+    val heapProfdSessionArtifact = HeapProfdSessionArtifact(myProfilers, Common.Session.getDefaultInstance(),
+                                                            Common.SessionMetaData.getDefaultInstance(),
+                                                            Trace.TraceInfo.getDefaultInstance())
+    assertThat(myJavaKotlinMethodSampleTaskHandler.supportsArtifact(heapProfdSessionArtifact)).isFalse()
+  }
+
+  @Test
+  fun testStartTaskInvokedOnEnterWithAliveSession() {
+    TaskHandlerTestUtils.startSession(myExposureLevel, myProfilers, myTransportService, myTimer)
+    val javaKotlinMethodSampleSessionArtifact = TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers,
+                                                                                                               Common.Session.getDefaultInstance(),
+                                                                                                               1L,
+                                                                                                               100L,
+                                                                                                               createDefaultArtSampleTraceConfiguration())
+    val cpuTaskArgs = CpuTaskArgs(javaKotlinMethodSampleSessionArtifact)
+    myJavaKotlinMethodSampleTaskHandler.enter(cpuTaskArgs)
+    // The session is alive, so startTask and thus startCapture should be called.
+    assertThat(myJavaKotlinMethodSampleTaskHandler.stage!!.recordingModel.isRecording)
+  }
+
+  @Test
+  fun testStartTaskWithSetStage() {
+    TaskHandlerTestUtils.startSession(myExposureLevel, myProfilers, myTransportService, myTimer)
+    // To start the task and thus the capture, the stage must be set up before. This will be taken care of via the setupStage() method call,
+    // on enter of the task handler, but this test is testing the explicit invocation of startTask.
+    myJavaKotlinMethodSampleTaskHandler.setupStage()
+    myJavaKotlinMethodSampleTaskHandler.startTask()
+    assertThat(myJavaKotlinMethodSampleTaskHandler.stage!!.recordingModel.isRecording).isTrue()
+  }
+
+  @Test
+  fun testStartTaskWithUnsetStage() {
+    // To start the task and thus the capture, the stage must be set up before. Here we will test the case where startTask is invoked
+    // without the stage being set precondition being met.
+    val exception = assertFailsWith<Throwable> {
+      myJavaKotlinMethodSampleTaskHandler.startTask()
+    }
+    assertThat(myJavaKotlinMethodSampleTaskHandler.stage).isNull()
+    assertThat(exception.message).isEqualTo(
+      "There was an error with the Java/Kotlin Method Sample (legacy) task. Error message: Cannot start the task as the InterimStage " +
+      "was null.")
+  }
+
+  @Test
+  fun testStopTaskSuccessfullyTerminatesRecording() {
+    TaskHandlerTestUtils.startSession(myExposureLevel, myProfilers, myTransportService, myTimer)
+    // First start the task successfully.
+    (myTransportService.getRegisteredCommand(Commands.Command.CommandType.START_TRACE) as StartTrace)
+      .startStatus = Trace.TraceStartStatus.newBuilder()
+      .setStatus(Trace.TraceStartStatus.Status.SUCCESS)
+      .build()
+    myJavaKotlinMethodSampleTaskHandler.setupStage()
+    myJavaKotlinMethodSampleTaskHandler.startTask()
+    assertThat(myJavaKotlinMethodSampleTaskHandler.stage!!.recordingModel.isRecording).isTrue()
+
+    // Wait for successful start event to be consumed.
+    myTimer.tick(FakeTimer.ONE_SECOND_IN_NS)
+    // Stop the task successfully.
+    (myTransportService.getRegisteredCommand(Commands.Command.CommandType.STOP_TRACE) as StopTrace)
+      .stopStatus = Trace.TraceStopStatus.newBuilder()
+      .setStatus(Trace.TraceStopStatus.Status.SUCCESS)
+      .build()
+    myJavaKotlinMethodSampleTaskHandler.stopTask()
+    // Wait for successful end event to be consumed.
+    myTimer.tick(FakeTimer.ONE_SECOND_IN_NS)
+    assertThat(myJavaKotlinMethodSampleTaskHandler.stage!!.recordingModel.isRecording).isFalse()
+  }
+
+  @Test
+  fun testLoadTaskInvokedOnEnterWithDeadSession() {
+    TaskHandlerTestUtils.startAndStopSession(myExposureLevel, myProfilers, myManager, myTransportService, myTimer)
+
+    // Before enter + loadTask, the stage should not be set yet.
+    assertThat(myProfilers.stage).isNotInstanceOf(CpuProfilerStage::class.java)
+
+    // Create a fake CpuCaptureSessionArtifact that uses an ART Sampled (Java/Kotlin Method Sample) configuration.
+    val javaKotlinMethodSampleSessionArtifact = TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers,
+                                                                                                               Common.Session.getDefaultInstance(),
+                                                                                                               1L,
+                                                                                                               100L,
+                                                                                                               createDefaultArtSampleTraceConfiguration())
+    val cpuTaskArgs = CpuTaskArgs(javaKotlinMethodSampleSessionArtifact)
+    // The session is not alive (dead) so loadTask and thus loadCapture should be called.
+    val argsSuccessfullyUsed = myJavaKotlinMethodSampleTaskHandler.enter(cpuTaskArgs)
+    assertThat(argsSuccessfullyUsed).isTrue()
+
+    // Verify that the artifact doSelect behavior is called by checking if the stage was set to CpuProfilerStage.
+    assertThat(myProfilers.stage).isInstanceOf(CpuProfilerStage::class.java)
+  }
+
+  @Test
+  fun testLoadTaskWithNonNullTaskArgs() {
+    TaskHandlerTestUtils.startAndStopSession(myExposureLevel, myProfilers, myManager, myTransportService, myTimer)
+
+    // Before enter + loadTask, the stage should not be set yet.
+    assertThat(myProfilers.stage).isNotInstanceOf(CpuProfilerStage::class.java)
+
+    val javaKotlinMethodSampleSessionArtifact = TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers,
+                                                                                                               Common.Session.getDefaultInstance(),
+                                                                                                               1L,
+                                                                                                               100L,
+                                                                                                               createDefaultArtSampleTraceConfiguration())
+    val cpuTaskArgs = CpuTaskArgs(javaKotlinMethodSampleSessionArtifact)
+    val argsSuccessfullyUsed = myJavaKotlinMethodSampleTaskHandler.loadTask(cpuTaskArgs)
+    assertThat(argsSuccessfullyUsed).isTrue()
+
+    // Verify that the artifact doSelect behavior was called by checking if the stage was set to CpuProfilerStage.
+    assertThat(myProfilers.stage).isInstanceOf(CpuProfilerStage::class.java)
+  }
+
+  @Test
+  fun testLoadTaskWithNullTaskArgs() {
+    TaskHandlerTestUtils.startAndStopSession(myExposureLevel, myProfilers, myManager, myTransportService, myTimer)
+
+    // Before enter + loadTask, the stage should not be set yet.
+    assertThat(myProfilers.stage).isNotInstanceOf(CpuProfilerStage::class.java)
+
+    val exception = assertFailsWith<Throwable> {
+      myJavaKotlinMethodSampleTaskHandler.loadTask(null)
+    }
+
+    assertThat(exception.message).isEqualTo(
+      "There was an error with the Java/Kotlin Method Sample (legacy) task. Error message: The task arguments (TaskArgs) supplied are " +
+      "not of the expected type (CpuTaskArgs).")
+
+    // Verify that the artifact doSelect behavior was not called by checking if the stage was not set to CpuProfilerStage.
+    assertThat(myProfilers.stage).isNotInstanceOf(CpuProfilerStage::class.java)
+  }
+
+  @Test
+  fun testCreateArgsSuccessfully() {
+    val selectedSession = Common.Session.newBuilder().setSessionId(1).setEndTimestamp(100).build()
+    val sessionIdToSessionItems = mapOf(
+      1L to TaskHandlerTestUtils.createSessionItem(myProfilers, selectedSession, 1, listOf(
+        TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers, selectedSession, 1, 100L,
+                                                                       5L, 500L,
+                                                                       createDefaultArtSampleTraceConfiguration()))),
+    )
+
+    val cpuTaskArgs = myJavaKotlinMethodSampleTaskHandler.createArgs(sessionIdToSessionItems, selectedSession)
+    assertThat(cpuTaskArgs).isNotNull()
+    assertThat(cpuTaskArgs).isInstanceOf(CpuTaskArgs::class.java)
+    assertThat(cpuTaskArgs!!.getCpuCaptureArtifact()).isNotNull()
+    assertThat(cpuTaskArgs.getCpuCaptureArtifact().artifactProto.configuration.hasArtOptions()).isTrue()
+    assertThat(cpuTaskArgs.getCpuCaptureArtifact().artifactProto.configuration.artOptions.traceMode).isEqualTo(TraceMode.SAMPLED)
+    assertThat(cpuTaskArgs.getCpuCaptureArtifact().artifactProto.fromTimestamp).isEqualTo(5L)
+    assertThat(cpuTaskArgs.getCpuCaptureArtifact().artifactProto.toTimestamp).isEqualTo(500L)
+  }
+
+  @Test
+  fun testCreateArgsFails() {
+    // By setting a session id that does not match any of the session items, the task artifact will not be found in the call to createArgs
+    // will fail to be constructed.
+    val selectedSession = Common.Session.newBuilder().setSessionId(0).setEndTimestamp(100).build()
+    val sessionIdToSessionItems = mapOf(
+      1L to TaskHandlerTestUtils.createSessionItem(myProfilers, selectedSession, 1, listOf(
+        TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers, selectedSession, 1, 100L,
+                                                                       5L, 500L,
+                                                                       createDefaultArtSampleTraceConfiguration()))),
+    )
+
+    val cpuTaskArgs = myJavaKotlinMethodSampleTaskHandler.createArgs(sessionIdToSessionItems, selectedSession)
+    // A return value of null indicates the task args were not constructed correctly (the underlying artifact was not found or supported by
+    // the task).
+    assertThat(cpuTaskArgs).isNull()
+  }
+
+  @Test
+  fun testGetTaskName() {
+    assertThat(myJavaKotlinMethodSampleTaskHandler.getTaskName()).isEqualTo("Java/Kotlin Method Sample (legacy)")
+  }
+
+  private fun createDefaultArtSampleTraceConfiguration() = Trace.TraceConfiguration.newBuilder().setArtOptions(
+    Trace.ArtOptions.newBuilder().setTraceMode(Trace.TraceMode.SAMPLED).build()).build()
+
+  companion object {
+    @JvmStatic
+    @Parameterized.Parameters
+    fun data(): Collection<ExposureLevel> {
+      return listOf(ExposureLevel.DEBUGGABLE, ExposureLevel.PROFILEABLE)
+    }
+  }
+}
\ No newline at end of file
diff --git a/profilers/testSrc/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/JavaKotlinMethodTraceTaskHandlerTest.kt b/profilers/testSrc/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/JavaKotlinMethodTraceTaskHandlerTest.kt
new file mode 100644
index 0000000..0d96010
--- /dev/null
+++ b/profilers/testSrc/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/JavaKotlinMethodTraceTaskHandlerTest.kt
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.profilers.tasks.taskhandlers.singleartifact.cpu
+
+import com.android.tools.adtui.model.FakeTimer
+import com.android.tools.idea.transport.faketransport.FakeGrpcChannel
+import com.android.tools.idea.transport.faketransport.FakeTransportService
+import com.android.tools.idea.transport.faketransport.commands.StartTrace
+import com.android.tools.idea.transport.faketransport.commands.StopTrace
+import com.android.tools.profiler.proto.Commands
+import com.android.tools.profiler.proto.Common
+import com.android.tools.profiler.proto.Common.Process.ExposureLevel
+import com.android.tools.profiler.proto.Trace
+import com.android.tools.profiler.proto.Trace.TraceMode
+import com.android.tools.profilers.FakeIdeProfilerServices
+import com.android.tools.profilers.ProfilerClient
+import com.android.tools.profilers.StudioProfilers
+import com.android.tools.profilers.cpu.CpuProfilerStage
+import com.android.tools.profilers.event.FakeEventService
+import com.android.tools.profilers.memory.HeapProfdSessionArtifact
+import com.android.tools.profilers.sessions.SessionsManager
+import com.android.tools.profilers.tasks.args.singleartifact.cpu.CpuTaskArgs
+import com.android.tools.profilers.tasks.taskhandlers.TaskHandlerTestUtils
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import kotlin.test.assertFailsWith
+
+@RunWith(Parameterized::class)
+class JavaKotlinMethodTraceTaskHandlerTest(private val myExposureLevel: ExposureLevel) {
+  private val myTimer = FakeTimer()
+  private val myTransportService = FakeTransportService(myTimer, false)
+
+  @get:Rule
+  var myGrpcChannel = FakeGrpcChannel("JavaKotlinMethodTraceTaskHandlerTestChannel", myTransportService, FakeEventService())
+
+  private lateinit var myProfilers: StudioProfilers
+  private lateinit var ideProfilerServices: FakeIdeProfilerServices
+  private lateinit var myManager: SessionsManager
+  private lateinit var myJavaKotlinMethodTraceTaskHandler: JavaKotlinMethodTraceTaskHandler
+
+  @Before
+  fun setup() {
+    ideProfilerServices = FakeIdeProfilerServices()
+    myProfilers = StudioProfilers(
+      ProfilerClient(myGrpcChannel.channel),
+      ideProfilerServices,
+      myTimer
+    )
+    myManager = myProfilers.sessionsManager
+    myJavaKotlinMethodTraceTaskHandler = JavaKotlinMethodTraceTaskHandler(myManager)
+    assertThat(myManager.sessionArtifacts).isEmpty()
+    assertThat(myManager.selectedSession).isEqualTo(Common.Session.getDefaultInstance())
+    assertThat(myManager.profilingSession).isEqualTo(Common.Session.getDefaultInstance())
+    ideProfilerServices.enableTaskBasedUx(true)
+  }
+
+  @Test
+  fun testSupportsArtifactWithJavaKotlinMethodTraceSessionArtifact() {
+    val javaKotlinMethodTraceSessionArtifact = TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers,
+                                                                                                              Common.Session.getDefaultInstance(),
+                                                                                                              1L, 100L,
+                                                                                                              createDefaultArtInstrumentedTraceConfiguration())
+    assertThat(myJavaKotlinMethodTraceTaskHandler.supportsArtifact(javaKotlinMethodTraceSessionArtifact)).isTrue()
+  }
+
+  @Test
+  fun testSupportsArtifactWithNonJavaKotlinMethodTraceSessionArtifact() {
+    val heapProfdSessionArtifact = HeapProfdSessionArtifact(myProfilers, Common.Session.getDefaultInstance(),
+                                                            Common.SessionMetaData.getDefaultInstance(),
+                                                            Trace.TraceInfo.getDefaultInstance())
+    assertThat(myJavaKotlinMethodTraceTaskHandler.supportsArtifact(heapProfdSessionArtifact)).isFalse()
+  }
+
+  @Test
+  fun testStartTaskInvokedOnEnterWithAliveSession() {
+    TaskHandlerTestUtils.startSession(myExposureLevel, myProfilers, myTransportService, myTimer)
+    val javaKotlinMethodTraceSessionArtifact = TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers,
+                                                                                                              Common.Session.getDefaultInstance(),
+                                                                                                              1L,
+                                                                                                              100L,
+                                                                                                              createDefaultArtInstrumentedTraceConfiguration())
+    val cpuTaskArgs = CpuTaskArgs(javaKotlinMethodTraceSessionArtifact)
+    myJavaKotlinMethodTraceTaskHandler.enter(cpuTaskArgs)
+    // The session is alive, so startTask and thus startCapture should be called.
+    assertThat(myJavaKotlinMethodTraceTaskHandler.stage!!.recordingModel.isRecording)
+  }
+
+  @Test
+  fun testStartTaskWithSetStage() {
+    TaskHandlerTestUtils.startSession(myExposureLevel, myProfilers, myTransportService, myTimer)
+    // To start the task and thus the capture, the stage must be set up before. This will be taken care of via the setupStage() method call,
+    // on enter of the task handler, but this test is testing the explicit invocation of startTask.
+    myJavaKotlinMethodTraceTaskHandler.setupStage()
+    myJavaKotlinMethodTraceTaskHandler.startTask()
+    assertThat(myJavaKotlinMethodTraceTaskHandler.stage!!.recordingModel.isRecording).isTrue()
+  }
+
+  @Test
+  fun testStartTaskWithUnsetStage() {
+    // To start the task and thus the capture, the stage must be set up before. Here we will test the case where startTask is invoked
+    // without the stage being set precondition being met.
+    val exception = assertFailsWith<Throwable> {
+      myJavaKotlinMethodTraceTaskHandler.startTask()
+    }
+    assertThat(myJavaKotlinMethodTraceTaskHandler.stage).isNull()
+    assertThat(exception.message).isEqualTo(
+      "There was an error with the Java/Kotlin Method Trace task. Error message: Cannot start the task as the InterimStage was null.")
+  }
+
+  @Test
+  fun testStopTaskSuccessfullyTerminatesRecording() {
+    TaskHandlerTestUtils.startSession(myExposureLevel, myProfilers, myTransportService, myTimer)
+    // First start the task successfully.
+    (myTransportService.getRegisteredCommand(Commands.Command.CommandType.START_TRACE) as StartTrace)
+      .startStatus = Trace.TraceStartStatus.newBuilder()
+      .setStatus(Trace.TraceStartStatus.Status.SUCCESS)
+      .build()
+    myJavaKotlinMethodTraceTaskHandler.setupStage()
+    myJavaKotlinMethodTraceTaskHandler.startTask()
+    assertThat(myJavaKotlinMethodTraceTaskHandler.stage!!.recordingModel.isRecording).isTrue()
+
+    // Wait for successful start event to be consumed.
+    myTimer.tick(FakeTimer.ONE_SECOND_IN_NS)
+    // Stop the task successfully.
+    (myTransportService.getRegisteredCommand(Commands.Command.CommandType.STOP_TRACE) as StopTrace)
+      .stopStatus = Trace.TraceStopStatus.newBuilder()
+      .setStatus(Trace.TraceStopStatus.Status.SUCCESS)
+      .build()
+    myJavaKotlinMethodTraceTaskHandler.stopTask()
+    // Wait for successful end event to be consumed.
+    myTimer.tick(FakeTimer.ONE_SECOND_IN_NS)
+    assertThat(myJavaKotlinMethodTraceTaskHandler.stage!!.recordingModel.isRecording).isFalse()
+  }
+
+  @Test
+  fun testLoadTaskInvokedOnEnterWithDeadSession() {
+    TaskHandlerTestUtils.startAndStopSession(myExposureLevel, myProfilers, myManager, myTransportService, myTimer)
+
+    // Before enter + loadTask, the stage should not be set yet.
+    assertThat(myProfilers.stage).isNotInstanceOf(CpuProfilerStage::class.java)
+
+    // Create a fake CpuCaptureSessionArtifact that uses an ART Instrumented (Java/Kotlin Method Sample) configuration.
+    val javaKotlinMethodTraceSessionArtifact = TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers,
+                                                                                                              Common.Session.getDefaultInstance(),
+                                                                                                              1L,
+                                                                                                              100L,
+                                                                                                              createDefaultArtInstrumentedTraceConfiguration())
+    val cpuTaskArgs = CpuTaskArgs(javaKotlinMethodTraceSessionArtifact)
+    // The session is not alive (dead) so loadTask and thus loadCapture should be called.
+    val argsSuccessfullyUsed = myJavaKotlinMethodTraceTaskHandler.enter(cpuTaskArgs)
+    assertThat(argsSuccessfullyUsed).isTrue()
+
+    // Verify that the artifact doSelect behavior is called by checking if the stage was set to CpuProfilerStage.
+    assertThat(myProfilers.stage).isInstanceOf(CpuProfilerStage::class.java)
+  }
+
+  @Test
+  fun testLoadTaskWithNonNullTaskArgs() {
+    TaskHandlerTestUtils.startAndStopSession(myExposureLevel, myProfilers, myManager, myTransportService, myTimer)
+
+    // Before enter + loadTask, the stage should not be set yet.
+    assertThat(myProfilers.stage).isNotInstanceOf(CpuProfilerStage::class.java)
+
+    val javaKotlinMethodTraceSessionArtifact = TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers,
+                                                                                                              Common.Session.getDefaultInstance(),
+                                                                                                              1L,
+                                                                                                              100L,
+                                                                                                              createDefaultArtInstrumentedTraceConfiguration())
+    val cpuTaskArgs = CpuTaskArgs(javaKotlinMethodTraceSessionArtifact)
+    val argsSuccessfullyUsed = myJavaKotlinMethodTraceTaskHandler.loadTask(cpuTaskArgs)
+    assertThat(argsSuccessfullyUsed).isTrue()
+
+    // Verify that the artifact doSelect behavior was called by checking if the stage was set to CpuProfilerStage.
+    assertThat(myProfilers.stage).isInstanceOf(CpuProfilerStage::class.java)
+  }
+
+  @Test
+  fun testLoadTaskWithNullTaskArgs() {
+    TaskHandlerTestUtils.startAndStopSession(myExposureLevel, myProfilers, myManager, myTransportService, myTimer)
+
+    // Before enter + loadTask, the stage should not be set yet.
+    assertThat(myProfilers.stage).isNotInstanceOf(CpuProfilerStage::class.java)
+
+    val exception = assertFailsWith<Throwable> {
+      myJavaKotlinMethodTraceTaskHandler.loadTask(null)
+    }
+
+    assertThat(exception.message).isEqualTo(
+      "There was an error with the Java/Kotlin Method Trace task. Error message: The task arguments (TaskArgs) supplied are not of the " +
+      "expected type (CpuTaskArgs).")
+
+    // Verify that the artifact doSelect behavior was not called by checking if the stage was not set to CpuProfilerStage.
+    assertThat(myProfilers.stage).isNotInstanceOf(CpuProfilerStage::class.java)
+  }
+
+  @Test
+  fun testCreateArgsSuccessfully() {
+    val selectedSession = Common.Session.newBuilder().setSessionId(1).setEndTimestamp(100).build()
+    val sessionIdToSessionItems = mapOf(
+      1L to TaskHandlerTestUtils.createSessionItem(myProfilers, selectedSession, 1, listOf(
+        TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers, selectedSession, 1, 100L,
+                                                                       5L, 500L,
+                                                                       createDefaultArtInstrumentedTraceConfiguration()))),
+    )
+
+    val cpuTaskArgs = myJavaKotlinMethodTraceTaskHandler.createArgs(sessionIdToSessionItems, selectedSession)
+    assertThat(cpuTaskArgs).isNotNull()
+    assertThat(cpuTaskArgs).isInstanceOf(CpuTaskArgs::class.java)
+    assertThat(cpuTaskArgs!!.getCpuCaptureArtifact()).isNotNull()
+    assertThat(cpuTaskArgs.getCpuCaptureArtifact().artifactProto.configuration.hasArtOptions()).isTrue()
+    assertThat(cpuTaskArgs.getCpuCaptureArtifact().artifactProto.configuration.artOptions.traceMode).isEqualTo(TraceMode.INSTRUMENTED)
+    assertThat(cpuTaskArgs.getCpuCaptureArtifact().artifactProto.fromTimestamp).isEqualTo(5L)
+    assertThat(cpuTaskArgs.getCpuCaptureArtifact().artifactProto.toTimestamp).isEqualTo(500L)
+  }
+
+  @Test
+  fun testCreateArgsFails() {
+    // By setting a session id that does not match any of the session items, the task artifact will not be found in the call to createArgs
+    // will fail to be constructed.
+    val selectedSession = Common.Session.newBuilder().setSessionId(0).setEndTimestamp(100).build()
+    val sessionIdToSessionItems = mapOf(
+      1L to TaskHandlerTestUtils.createSessionItem(myProfilers, selectedSession, 1, listOf(
+        TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers, selectedSession, 1, 100L,
+                                                                       5L, 500L,
+                                                                       createDefaultArtInstrumentedTraceConfiguration()))),
+    )
+
+    val cpuTaskArgs = myJavaKotlinMethodTraceTaskHandler.createArgs(sessionIdToSessionItems, selectedSession)
+    // A return value of null indicates the task args were not constructed correctly (the underlying artifact was not found or supported by
+    // the task).
+    assertThat(cpuTaskArgs).isNull()
+  }
+
+  @Test
+  fun testGetTaskName() {
+    assertThat(myJavaKotlinMethodTraceTaskHandler.getTaskName()).isEqualTo("Java/Kotlin Method Trace")
+  }
+
+  private fun createDefaultArtInstrumentedTraceConfiguration() = Trace.TraceConfiguration.newBuilder().setArtOptions(
+    Trace.ArtOptions.newBuilder().setTraceMode(TraceMode.INSTRUMENTED).build()).build()
+
+  companion object {
+    @JvmStatic
+    @Parameterized.Parameters
+    fun data(): Collection<ExposureLevel> {
+      return listOf(ExposureLevel.DEBUGGABLE, ExposureLevel.PROFILEABLE)
+    }
+  }
+}
\ No newline at end of file
diff --git a/profilers/testSrc/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/SystemTraceTaskHandlerTest.kt b/profilers/testSrc/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/SystemTraceTaskHandlerTest.kt
new file mode 100644
index 0000000..be4d6d1
--- /dev/null
+++ b/profilers/testSrc/com/android/tools/profilers/tasks/taskhandlers/singleartifact/cpu/SystemTraceTaskHandlerTest.kt
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.profilers.tasks.taskhandlers.singleartifact.cpu
+
+import com.android.tools.adtui.model.FakeTimer
+import com.android.tools.idea.transport.faketransport.FakeGrpcChannel
+import com.android.tools.idea.transport.faketransport.FakeTransportService
+import com.android.tools.idea.transport.faketransport.commands.StartTrace
+import com.android.tools.idea.transport.faketransport.commands.StopTrace
+import com.android.tools.profiler.proto.Commands
+import com.android.tools.profiler.proto.Common
+import com.android.tools.profiler.proto.Common.Process.ExposureLevel
+import com.android.tools.profiler.proto.Trace
+import com.android.tools.profilers.FakeIdeProfilerServices
+import com.android.tools.profilers.ProfilerClient
+import com.android.tools.profilers.StudioProfilers
+import com.android.tools.profilers.cpu.CpuProfilerStage
+import com.android.tools.profilers.event.FakeEventService
+import com.android.tools.profilers.memory.HeapProfdSessionArtifact
+import com.android.tools.profilers.sessions.SessionsManager
+import com.android.tools.profilers.tasks.args.singleartifact.cpu.CpuTaskArgs
+import com.android.tools.profilers.tasks.taskhandlers.TaskHandlerTestUtils
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+import perfetto.protos.PerfettoConfig
+import kotlin.test.assertFailsWith
+
+@RunWith(Parameterized::class)
+class SystemTraceTaskHandlerTest(private val myExposureLevel: ExposureLevel) {
+  private val myTimer = FakeTimer()
+  private val myTransportService = FakeTransportService(myTimer, false)
+
+  @get:Rule
+  var myGrpcChannel = FakeGrpcChannel("SystemTraceTaskHandlerTestChannel", myTransportService, FakeEventService())
+
+  private lateinit var myProfilers: StudioProfilers
+  private lateinit var ideProfilerServices: FakeIdeProfilerServices
+  private lateinit var myManager: SessionsManager
+  private lateinit var mySystemTraceTaskHandler: SystemTraceTaskHandler
+
+  @Before
+  fun setup() {
+    ideProfilerServices = FakeIdeProfilerServices()
+    myProfilers = StudioProfilers(
+      ProfilerClient(myGrpcChannel.channel),
+      ideProfilerServices,
+      myTimer
+    )
+    myManager = myProfilers.sessionsManager
+    mySystemTraceTaskHandler = SystemTraceTaskHandler(myManager)
+    assertThat(myManager.sessionArtifacts).isEmpty()
+    assertThat(myManager.selectedSession).isEqualTo(Common.Session.getDefaultInstance())
+    assertThat(myManager.profilingSession).isEqualTo(Common.Session.getDefaultInstance())
+    ideProfilerServices.enableTaskBasedUx(true)
+  }
+
+  @Test
+  fun testSupportsArtifactWithSystemTraceSessionArtifact() {
+    val systemTraceSessionArtifact = TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers,
+                                                                                                    Common.Session.getDefaultInstance(),
+                                                                                                    1L, 100L,
+                                                                                                    createDefaultPerfettoTraceConfiguration())
+    assertThat(mySystemTraceTaskHandler.supportsArtifact(systemTraceSessionArtifact)).isTrue()
+  }
+
+  @Test
+  fun testSupportsArtifactWithNonSystemTraceSessionArtifact() {
+    val heapProfdSessionArtifact = HeapProfdSessionArtifact(myProfilers, Common.Session.getDefaultInstance(),
+                                                            Common.SessionMetaData.getDefaultInstance(),
+                                                            Trace.TraceInfo.getDefaultInstance())
+    assertThat(mySystemTraceTaskHandler.supportsArtifact(heapProfdSessionArtifact)).isFalse()
+  }
+
+  @Test
+  fun testStartTaskInvokedOnEnterWithAliveSession() {
+    TaskHandlerTestUtils.startSession(myExposureLevel, myProfilers, myTransportService, myTimer)
+    val systemTraceSessionArtifact = TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers,
+                                                                                                    Common.Session.getDefaultInstance(), 1L,
+                                                                                                    100L,
+                                                                                                    createDefaultPerfettoTraceConfiguration())
+    val cpuTaskArgs = CpuTaskArgs(systemTraceSessionArtifact)
+    mySystemTraceTaskHandler.enter(cpuTaskArgs)
+    // The session is alive, so startTask and thus startCapture should be called.
+    assertThat(mySystemTraceTaskHandler.stage!!.recordingModel.isRecording)
+  }
+
+  @Test
+  fun testStartTaskWithSetStage() {
+    TaskHandlerTestUtils.startSession(myExposureLevel, myProfilers, myTransportService, myTimer)
+    // To start the task and thus the capture, the stage must be set up before. This will be taken care of via the setupStage() method call,
+    // on enter of the task handler, but this test is testing the explicit invocation of startTask.
+    mySystemTraceTaskHandler.setupStage()
+    mySystemTraceTaskHandler.startTask()
+    assertThat(mySystemTraceTaskHandler.stage!!.recordingModel.isRecording).isTrue()
+  }
+
+  @Test
+  fun testStartTaskWithUnsetStage() {
+    // To start the task and thus the capture, the stage must be set up before. Here we will test the case where startTask is invoked
+    // without the stage being set precondition being met.
+    val exception = assertFailsWith<Throwable> {
+      mySystemTraceTaskHandler.startTask()
+    }
+    assertThat(mySystemTraceTaskHandler.stage).isNull()
+    assertThat(exception.message).isEqualTo("There was an error with the System Trace task. Error message: Cannot start the task as the " +
+                                            "InterimStage was null.")
+  }
+
+  @Test
+  fun testStopTaskSuccessfullyTerminatesRecording() {
+    TaskHandlerTestUtils.startSession(myExposureLevel, myProfilers, myTransportService, myTimer)
+    // First start the task successfully.
+    (myTransportService.getRegisteredCommand(Commands.Command.CommandType.START_TRACE) as StartTrace)
+      .startStatus = Trace.TraceStartStatus.newBuilder()
+      .setStatus(Trace.TraceStartStatus.Status.SUCCESS)
+      .build()
+    mySystemTraceTaskHandler.setupStage()
+    mySystemTraceTaskHandler.startTask()
+    assertThat(mySystemTraceTaskHandler.stage!!.recordingModel.isRecording).isTrue()
+
+    // Wait for successful start event to be consumed.
+    myTimer.tick(FakeTimer.ONE_SECOND_IN_NS)
+    // Stop the task successfully.
+    (myTransportService.getRegisteredCommand(Commands.Command.CommandType.STOP_TRACE) as StopTrace)
+      .stopStatus = Trace.TraceStopStatus.newBuilder()
+      .setStatus(Trace.TraceStopStatus.Status.SUCCESS)
+      .build()
+    mySystemTraceTaskHandler.stopTask()
+    // Wait for successful end event to be consumed.
+    myTimer.tick(FakeTimer.ONE_SECOND_IN_NS)
+    assertThat(mySystemTraceTaskHandler.stage!!.recordingModel.isRecording).isFalse()
+  }
+
+  @Test
+  fun testLoadTaskInvokedOnEnterWithDeadSession() {
+    TaskHandlerTestUtils.startAndStopSession(myExposureLevel, myProfilers, myManager, myTransportService, myTimer)
+
+    // Before enter + loadTask, the stage should not be set yet.
+    assertThat(myProfilers.stage).isNotInstanceOf(CpuProfilerStage::class.java)
+
+    // Create a fake CpuCaptureSessionArtifact that uses a Perfetto (System Trace) configuration.
+    val systemTraceSessionArtifact = TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers,
+                                                                                                    Common.Session.getDefaultInstance(), 1L,
+                                                                                                    100L,
+                                                                                                    createDefaultPerfettoTraceConfiguration())
+    val cpuTaskArgs = CpuTaskArgs(systemTraceSessionArtifact)
+    // The session is not alive (dead) so loadTask and thus loadCapture should be called.
+    val argsSuccessfullyUsed = mySystemTraceTaskHandler.enter(cpuTaskArgs)
+    assertThat(argsSuccessfullyUsed).isTrue()
+
+    // Verify that the artifact doSelect behavior is called by checking if the stage was set to CpuProfilerStage.
+    assertThat(myProfilers.stage).isInstanceOf(CpuProfilerStage::class.java)
+  }
+
+  @Test
+  fun testLoadTaskWithNonNullTaskArgs() {
+    TaskHandlerTestUtils.startAndStopSession(myExposureLevel, myProfilers, myManager, myTransportService, myTimer)
+
+    // Before enter + loadTask, the stage should not be set yet.
+    assertThat(myProfilers.stage).isNotInstanceOf(CpuProfilerStage::class.java)
+
+    val systemTraceSessionArtifact = TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers,
+                                                                                                    Common.Session.getDefaultInstance(), 1L,
+                                                                                                    100L,
+                                                                                                    createDefaultPerfettoTraceConfiguration())
+    val cpuTaskArgs = CpuTaskArgs(systemTraceSessionArtifact)
+    val argsSuccessfullyUsed = mySystemTraceTaskHandler.loadTask(cpuTaskArgs)
+    assertThat(argsSuccessfullyUsed).isTrue()
+
+    // Verify that the artifact doSelect behavior was called by checking if the stage was set to CpuProfilerStage.
+    assertThat(myProfilers.stage).isInstanceOf(CpuProfilerStage::class.java)
+  }
+
+  @Test
+  fun testLoadTaskWithNullTaskArgs() {
+    TaskHandlerTestUtils.startAndStopSession(myExposureLevel, myProfilers, myManager, myTransportService, myTimer)
+
+    // Before enter + loadTask, the stage should not be set yet.
+    assertThat(myProfilers.stage).isNotInstanceOf(CpuProfilerStage::class.java)
+
+    val exception = assertFailsWith<Throwable> {
+      mySystemTraceTaskHandler.loadTask(null)
+    }
+
+    assertThat(exception.message).isEqualTo("There was an error with the System Trace task. Error message: The task arguments (TaskArgs) " +
+                                            "supplied are not of the expected type (CpuTaskArgs).")
+
+    // Verify that the artifact doSelect behavior was not called by checking if the stage was not set to CpuProfilerStage.
+    assertThat(myProfilers.stage).isNotInstanceOf(CpuProfilerStage::class.java)
+  }
+
+  @Test
+  fun testCreateArgsSuccessfully() {
+    val selectedSession = Common.Session.newBuilder().setSessionId(1).setEndTimestamp(100).build()
+    val sessionIdToSessionItems = mapOf(
+      1L to TaskHandlerTestUtils.createSessionItem(myProfilers, selectedSession, 1, listOf(
+        TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers, selectedSession, 1, 100L,
+                                                                       5L, 500L,
+                                                                       createDefaultPerfettoTraceConfiguration()))),
+    )
+
+    val cpuTaskArgs = mySystemTraceTaskHandler.createArgs(sessionIdToSessionItems, selectedSession)
+    assertThat(cpuTaskArgs).isNotNull()
+    assertThat(cpuTaskArgs).isInstanceOf(CpuTaskArgs::class.java)
+    assertThat(cpuTaskArgs!!.getCpuCaptureArtifact()).isNotNull()
+    assertThat(cpuTaskArgs.getCpuCaptureArtifact().artifactProto.configuration.hasPerfettoOptions()).isTrue()
+    assertThat(cpuTaskArgs.getCpuCaptureArtifact().artifactProto.fromTimestamp).isEqualTo(5L)
+    assertThat(cpuTaskArgs.getCpuCaptureArtifact().artifactProto.toTimestamp).isEqualTo(500L)
+  }
+
+  @Test
+  fun testCreateArgsFails() {
+    // By setting a session id that does not match any of the session items, the task artifact will not be found in the call to createArgs
+    // will fail to be constructed.
+    val selectedSession = Common.Session.newBuilder().setSessionId(0).setEndTimestamp(100).build()
+    val sessionIdToSessionItems = mapOf(
+      1L to TaskHandlerTestUtils.createSessionItem(myProfilers, selectedSession, 1, listOf(
+        TaskHandlerTestUtils.createCpuCaptureSessionArtifactWithConfig(myProfilers, selectedSession, 1, 100L,
+                                                                       5L, 500L,
+                                                                       createDefaultPerfettoTraceConfiguration()))),
+    )
+
+    val cpuTaskArgs = mySystemTraceTaskHandler.createArgs(sessionIdToSessionItems, selectedSession)
+    // A return value of null indicates the task args were not constructed correctly (the underlying artifact was not found or supported by
+    // the task).
+    assertThat(cpuTaskArgs).isNull()
+  }
+
+  @Test
+  fun testGetTaskName() {
+    assertThat(mySystemTraceTaskHandler.getTaskName()).isEqualTo("System Trace")
+  }
+
+  private fun createDefaultPerfettoTraceConfiguration() = Trace.TraceConfiguration.newBuilder().setPerfettoOptions(
+    PerfettoConfig.TraceConfig.getDefaultInstance()).build()
+
+  companion object {
+    @JvmStatic
+    @Parameterized.Parameters
+    fun data(): Collection<ExposureLevel> {
+      return listOf(ExposureLevel.DEBUGGABLE, ExposureLevel.PROFILEABLE)
+    }
+  }
+}
\ No newline at end of file
diff --git a/project-system-gradle/src/META-INF/project-system-gradle-plugin-androidstudio.xml b/project-system-gradle/src/META-INF/project-system-gradle-plugin-androidstudio.xml
index 185f598..d4d9973 100644
--- a/project-system-gradle/src/META-INF/project-system-gradle-plugin-androidstudio.xml
+++ b/project-system-gradle/src/META-INF/project-system-gradle-plugin-androidstudio.xml
@@ -24,6 +24,12 @@
     <projectService serviceInterface="com.intellij.openapi.externalSystem.autoimport.ExternalSystemProjectTracker"
                     serviceImplementation="com.android.tools.idea.projectsystem.gradle.RefreshOnlyAutoImportProjectTracker"
                     overrides="true"/>
+    <projectService serviceInterface="org.jetbrains.plugins.gradle.settings.GradleSettings"
+                    serviceImplementation="com.android.tools.idea.gradle.project.AndroidStudioGradleSettings"
+                    overrides="true"/>
+    <applicationService serviceInterface="org.jetbrains.plugins.gradle.service.GradleInstallationManager"
+                        serviceImplementation="com.android.tools.idea.gradle.project.AndroidStudioGradleInstallationManager"
+                        overrides="true"/>
 
     <postStartupActivity implementation="com.android.tools.idea.gradle.project.AndroidStudioProjectActivity" />
 
diff --git a/project-system-gradle/src/META-INF/project-system-gradle-plugin.xml b/project-system-gradle/src/META-INF/project-system-gradle-plugin.xml
index 7a4dc7a..290bd29 100644
--- a/project-system-gradle/src/META-INF/project-system-gradle-plugin.xml
+++ b/project-system-gradle/src/META-INF/project-system-gradle-plugin.xml
@@ -110,6 +110,9 @@
     <projectViewNodeDecorator id="android.build.node.decorator" implementation="com.android.tools.idea.gradle.projectView.BuildNodeDecorator"/>
     <generatedSourcesFilter implementation="com.android.tools.idea.gradle.roots.AndroidGeneratedSourcesFilter"/>
     <editorNotificationProvider implementation="com.android.tools.idea.gradle.notification.GeneratedFileNotificationProvider"/>
+    <editorNotificationProvider implementation="com.android.tools.idea.gradle.service.notification.ProjectJarFileTracker$JarFileNotificationProvider"/>
+    <projectService serviceImplementation="com.android.tools.idea.gradle.service.notification.ProjectJarFileTracker"/>
+
     <cachesInvalidator implementation="com.android.tools.idea.gradle.project.sync.idea.data.IdeaSyncCachesInvalidator"/>
     <completion.contributor language="any"
                             implementationClass="com.android.tools.idea.gradle.completions.GradleDependencyCompletionContributor" />
@@ -233,6 +236,9 @@
     <newResourceCreationHandler
       implementation="com.android.tools.idea.gradle.actions.GradleNewResourceCreationHandler" />
   </extensions>
+  <extensions defaultExtensionNs="com.android.tools.idea.model">
+    <mergedManifestInfoToken implementation="com.android.tools.idea.model.MergedManifestInfoGradleToken"/>
+  </extensions>
   <actions>
     <action id="Android.SyncProject" class="com.android.tools.idea.gradle.actions.SyncProjectAction" icon="StudioIcons.Shell.Toolbar.GRADLE_SYNC">
       <add-to-group group-id="Android.MainToolBarActionGroup" anchor="before" relative-to-action="AndroidDeviceManagerPlaceholder"/>
diff --git a/project-system-gradle/src/com/android/tools/idea/gradle/actions/AndroidStudioGradleAction.java b/project-system-gradle/src/com/android/tools/idea/gradle/actions/AndroidStudioGradleAction.java
index 2d1fd8d..d11ac41 100644
--- a/project-system-gradle/src/com/android/tools/idea/gradle/actions/AndroidStudioGradleAction.java
+++ b/project-system-gradle/src/com/android/tools/idea/gradle/actions/AndroidStudioGradleAction.java
@@ -17,6 +17,7 @@
 
 import com.android.tools.idea.gradle.project.GradleProjectInfo;
 import com.intellij.ide.impl.TrustedProjects;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.project.Project;
@@ -37,6 +38,12 @@
     super(text, description, icon);
   }
 
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
   @Override
   public final void update(@NotNull AnActionEvent e) {
     if (!isGradleProject(e)) {
diff --git a/project-system-gradle/src/com/android/tools/idea/gradle/actions/BuildApkAction.java b/project-system-gradle/src/com/android/tools/idea/gradle/actions/BuildApkAction.java
index 8069b5f..e8afa8e 100644
--- a/project-system-gradle/src/com/android/tools/idea/gradle/actions/BuildApkAction.java
+++ b/project-system-gradle/src/com/android/tools/idea/gradle/actions/BuildApkAction.java
@@ -20,6 +20,7 @@
 import com.android.tools.idea.gradle.project.build.invoker.GradleBuildInvoker;
 import com.android.tools.idea.gradle.project.build.invoker.TestCompileType;
 import com.android.tools.idea.gradle.util.GradleProjectSystemUtil;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.project.DumbAwareAction;
@@ -35,6 +36,12 @@
     super(ACTION_TEXT);
   }
 
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
   @Override
   public void update(@NotNull AnActionEvent e) {
     Project project = e.getProject();
diff --git a/project-system-gradle/src/com/android/tools/idea/gradle/actions/BuildBundleAction.java b/project-system-gradle/src/com/android/tools/idea/gradle/actions/BuildBundleAction.java
index 4a6064c..008424a 100644
--- a/project-system-gradle/src/com/android/tools/idea/gradle/actions/BuildBundleAction.java
+++ b/project-system-gradle/src/com/android/tools/idea/gradle/actions/BuildBundleAction.java
@@ -22,6 +22,7 @@
 import com.android.tools.idea.gradle.project.build.invoker.GradleBuildInvoker;
 import com.android.tools.idea.gradle.util.GradleProjectSystemUtil;
 import com.android.tools.idea.project.AndroidNotification;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.project.DumbAwareAction;
@@ -37,6 +38,12 @@
     super(ACTION_TEXT);
   }
 
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
   @Override
   public void update(@NotNull AnActionEvent e) {
     Project project = e.getProject();
diff --git a/project-system-gradle/src/com/android/tools/idea/gradle/actions/LibraryPropertiesAction.java b/project-system-gradle/src/com/android/tools/idea/gradle/actions/LibraryPropertiesAction.java
index 685ec37..da280d1 100644
--- a/project-system-gradle/src/com/android/tools/idea/gradle/actions/LibraryPropertiesAction.java
+++ b/project-system-gradle/src/com/android/tools/idea/gradle/actions/LibraryPropertiesAction.java
@@ -19,6 +19,7 @@
 import com.android.tools.idea.gradle.project.library.LibraryPropertiesDialog;
 import com.intellij.icons.AllIcons;
 import com.intellij.ide.projectView.impl.nodes.NamedLibraryElementNode;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.DataContext;
@@ -38,6 +39,12 @@
     super("Library Properties...", null, AllIcons.Actions.Properties);
   }
 
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
   @Override
   public void update(@NotNull AnActionEvent e) {
     e.getPresentation().setVisible(findLibrary(e) != null);
diff --git a/android/src/com/android/tools/idea/gradle/plugin/AndroidPluginInfo.java b/project-system-gradle/src/com/android/tools/idea/gradle/plugin/AndroidPluginInfo.java
similarity index 100%
rename from android/src/com/android/tools/idea/gradle/plugin/AndroidPluginInfo.java
rename to project-system-gradle/src/com/android/tools/idea/gradle/plugin/AndroidPluginInfo.java
diff --git a/android/src/com/android/tools/idea/gradle/project/AndroidStudioGradleInstallationManager.java b/project-system-gradle/src/com/android/tools/idea/gradle/project/AndroidStudioGradleInstallationManager.java
similarity index 100%
rename from android/src/com/android/tools/idea/gradle/project/AndroidStudioGradleInstallationManager.java
rename to project-system-gradle/src/com/android/tools/idea/gradle/project/AndroidStudioGradleInstallationManager.java
diff --git a/android/src/com/android/tools/idea/gradle/project/AndroidStudioGradleSettings.java b/project-system-gradle/src/com/android/tools/idea/gradle/project/AndroidStudioGradleSettings.java
similarity index 95%
rename from android/src/com/android/tools/idea/gradle/project/AndroidStudioGradleSettings.java
rename to project-system-gradle/src/com/android/tools/idea/gradle/project/AndroidStudioGradleSettings.java
index 1fe50c3..993fab4 100644
--- a/android/src/com/android/tools/idea/gradle/project/AndroidStudioGradleSettings.java
+++ b/project-system-gradle/src/com/android/tools/idea/gradle/project/AndroidStudioGradleSettings.java
@@ -8,7 +8,7 @@
 import org.jetbrains.plugins.gradle.settings.GradleSettings;
 import org.jetbrains.plugins.gradle.settings.TestRunner;
 
-public class AndroidStudioGradleSettings extends GradleSettings{
+public class AndroidStudioGradleSettings extends GradleSettings {
   public AndroidStudioGradleSettings(@NotNull Project project) {
     super(project);
   }
diff --git a/android/src/com/android/tools/idea/gradle/project/build/invoker/BuildStopper.java b/project-system-gradle/src/com/android/tools/idea/gradle/project/build/invoker/BuildStopper.java
similarity index 100%
rename from android/src/com/android/tools/idea/gradle/project/build/invoker/BuildStopper.java
rename to project-system-gradle/src/com/android/tools/idea/gradle/project/build/invoker/BuildStopper.java
diff --git a/project-system-gradle/src/com/android/tools/idea/gradle/project/sync/idea/AndroidGradleProjectResolver.kt b/project-system-gradle/src/com/android/tools/idea/gradle/project/sync/idea/AndroidGradleProjectResolver.kt
index a00e9bf..4b43e5f 100644
--- a/project-system-gradle/src/com/android/tools/idea/gradle/project/sync/idea/AndroidGradleProjectResolver.kt
+++ b/project-system-gradle/src/com/android/tools/idea/gradle/project/sync/idea/AndroidGradleProjectResolver.kt
@@ -20,7 +20,6 @@
 import com.android.ide.gradle.model.artifacts.AdditionalClassifierArtifactsModel
 import com.android.repository.Revision
 import com.android.tools.analytics.UsageTracker.log
-import com.android.tools.analytics.withProjectId
 import com.android.tools.idea.IdeInfo
 import com.android.tools.idea.flags.StudioFlags
 import com.android.tools.idea.gradle.LibraryFilePaths
@@ -83,8 +82,6 @@
 import com.android.utils.appendCapitalized
 import com.android.utils.findGradleSettingsFile
 import com.google.common.annotations.VisibleForTesting
-import com.google.wireless.android.sdk.stats.AndroidStudioEvent
-import com.google.wireless.android.sdk.stats.AndroidStudioEvent.EventCategory
 import com.google.wireless.android.sdk.stats.AndroidStudioEvent.EventKind
 import com.google.wireless.android.sdk.stats.AndroidStudioEvent.GradleSyncFailure
 import com.google.wireless.android.sdk.stats.AndroidStudioEvent.GradleSyncIssueType
@@ -129,7 +126,6 @@
 import org.jetbrains.annotations.SystemIndependent
 import org.jetbrains.kotlin.android.configure.patchFromMppModel
 import org.jetbrains.kotlin.idea.gradleJava.configuration.KotlinMppGradleProjectResolver
-import org.jetbrains.kotlin.idea.gradleTooling.KotlinGradleModel
 import org.jetbrains.kotlin.idea.gradleTooling.KotlinMPPGradleModel
 import org.jetbrains.kotlin.idea.gradleTooling.model.kapt.KaptGradleModel
 import org.jetbrains.kotlin.idea.gradleTooling.model.kapt.KaptModelBuilderService
diff --git a/project-system-gradle/src/com/android/tools/idea/gradle/service/notification/ProjectJarFileTracker.kt b/project-system-gradle/src/com/android/tools/idea/gradle/service/notification/ProjectJarFileTracker.kt
new file mode 100644
index 0000000..3ddd171
--- /dev/null
+++ b/project-system-gradle/src/com/android/tools/idea/gradle/service/notification/ProjectJarFileTracker.kt
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.gradle.service.notification
+
+import com.android.tools.idea.gradle.project.sync.GradleSyncInvoker
+import com.android.tools.idea.projectsystem.PROJECT_SYSTEM_SYNC_TOPIC
+import com.android.tools.idea.projectsystem.ProjectSystemSyncManager
+import com.google.wireless.android.sdk.stats.GradleSyncStats
+import com.intellij.openapi.fileEditor.FileEditor
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.vfs.VirtualFile
+import com.intellij.openapi.vfs.VirtualFileManager
+import com.intellij.openapi.vfs.newvfs.BulkFileListener
+import com.intellij.openapi.vfs.newvfs.events.VFileCopyEvent
+import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent
+import com.intellij.openapi.vfs.newvfs.events.VFileDeleteEvent
+import com.intellij.openapi.vfs.newvfs.events.VFileEvent
+import com.intellij.openapi.vfs.newvfs.events.VFileMoveEvent
+import com.intellij.ui.EditorNotificationPanel
+import com.intellij.ui.EditorNotificationProvider
+import com.intellij.ui.EditorNotifications
+import org.jetbrains.annotations.VisibleForTesting
+import java.util.function.Function
+
+
+class ProjectJarFileTracker(val project: Project) {
+  val editorNotifications:EditorNotifications = EditorNotifications.getInstance(project)
+  @VisibleForTesting
+  var jarFilesChanged = false
+    private set
+
+  private fun resetFlag(){
+    jarFilesChanged = false
+  }
+
+  init {
+    project.messageBus.connect(project).subscribe<BulkFileListener>(VirtualFileManager.VFS_CHANGES, object : BulkFileListener {
+      private val JAR_EXT = ".jar"
+
+      override fun before(events: List<VFileEvent>) {
+        for (event in events) {
+          if (event is VFileMoveEvent) {
+            onChanged(event.file)
+          } else if (event is VFileDeleteEvent) {
+            onChanged(event.file)
+          }
+        }
+      }
+
+      override fun after(events: List<VFileEvent>) {
+        for (event in events) {
+          when (event) {
+            is VFileCreateEvent, is VFileCopyEvent, is VFileMoveEvent -> onChanged(event.file)
+          }
+        }
+      }
+
+      private fun onChanged(file: VirtualFile?) {
+        if (file?.name?.endsWith(JAR_EXT) == true) {
+          jarFilesChanged = true
+          editorNotifications.updateAllNotifications()
+        }
+      }
+    })
+
+    project.messageBus.connect().subscribe(PROJECT_SYSTEM_SYNC_TOPIC,
+                                           ProjectSystemSyncManager.SyncResultListener { result ->
+                                             if (result == ProjectSystemSyncManager.SyncResult.SUCCESS) {
+                                               resetFlag()
+                                             }
+                                           })
+  }
+
+
+  class JarFileNotificationProvider: EditorNotificationProvider {
+
+    override fun collectNotificationData(project: Project, file: VirtualFile): Function<FileEditor, EditorNotificationPanel?>? {
+      val tracker = getInstance(project)
+      if(tracker.jarFilesChanged){
+        return Function { fileEditor -> JarFileSyncNotificationPanel(project, fileEditor) }
+      }
+      return null
+    }
+  }
+
+  internal class JarFileSyncNotificationPanel(project: Project, editor: FileEditor) : EditorNotificationPanel(editor) {
+    init {
+      text("Jar files have been added/removed since last project sync. Sync may be necessary for the IDE to work properly.")
+      createActionLabel("Sync Now") {
+                          GradleSyncInvoker.getInstance()
+                            .requestProjectSync(
+                              project,
+                              GradleSyncInvoker.Request(GradleSyncStats.Trigger.TRIGGER_USER_STALE_CHANGES),
+                              null
+                            )
+                        }
+      createActionLabel("Ignore these changes") {
+        getInstance(project).resetFlag()
+        this.isVisible = false
+      }
+    }
+  }
+
+  companion object {
+    @JvmStatic
+    fun getInstance(project: Project): ProjectJarFileTracker {
+      return project.getService(ProjectJarFileTracker::class.java)
+    }
+  }
+}
diff --git a/project-system-gradle/src/com/android/tools/idea/model/MergedManifestInfoGradleToken.java b/project-system-gradle/src/com/android/tools/idea/model/MergedManifestInfoGradleToken.java
new file mode 100644
index 0000000..c874ef9
--- /dev/null
+++ b/project-system-gradle/src/com/android/tools/idea/model/MergedManifestInfoGradleToken.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.model;
+
+import com.android.manifmerger.ManifestMerger2;
+import com.android.tools.idea.gradle.plugin.AndroidPluginInfo;
+import com.android.tools.idea.projectsystem.GradleToken;
+import com.android.tools.idea.projectsystem.gradle.GradleProjectSystem;
+import com.intellij.openapi.project.Project;
+
+public class MergedManifestInfoGradleToken implements MergedManifestInfoToken<GradleProjectSystem>, GradleToken {
+
+  @Override
+  public ManifestMerger2.Invoker withProjectSystemFeatures(GradleProjectSystem projectSystem, ManifestMerger2.Invoker invoker) {
+    if (!isVersionAtLeast7_4_0(projectSystem.getProject())) {
+      invoker.withFeatures(ManifestMerger2.Invoker.Feature.DISABLE_STRIP_LIBRARY_TARGET_SDK);
+    }
+    return invoker;
+  }
+
+  private static boolean isVersionAtLeast7_4_0(Project project) {
+    AndroidPluginInfo androidPluginInfo = AndroidPluginInfo.findFromModel(project);
+    return androidPluginInfo != null &&
+           androidPluginInfo.getPluginVersion() != null &&
+           androidPluginInfo.getPluginVersion().isAtLeast(7, 4, 0);
+  }
+}
\ No newline at end of file
diff --git a/project-system-gradle/src/com/android/tools/idea/projectsystem/gradle/GradleModuleSystem.kt b/project-system-gradle/src/com/android/tools/idea/projectsystem/gradle/GradleModuleSystem.kt
index f7d2545..7e0f776 100644
--- a/project-system-gradle/src/com/android/tools/idea/projectsystem/gradle/GradleModuleSystem.kt
+++ b/project-system-gradle/src/com/android/tools/idea/projectsystem/gradle/GradleModuleSystem.kt
@@ -579,7 +579,7 @@
    */
   override val useAndroidX: Boolean get() = agpBuildGlobalFlags.useAndroidX
 
-  override val enableVcsInfo: Boolean get() = agpBuildGlobalFlags.enableVcsInfo
+  val enableVcsInfo: Boolean get() = agpBuildGlobalFlags.enableVcsInfo
 
   override val submodules: Collection<Module>
     get() = moduleHierarchyProvider.submodules
diff --git a/project-system-gradle/src/com/android/tools/idea/projectsystem/gradle/GradleProjectSystem.kt b/project-system-gradle/src/com/android/tools/idea/projectsystem/gradle/GradleProjectSystem.kt
index 9c325e8..fcd85a4 100644
--- a/project-system-gradle/src/com/android/tools/idea/projectsystem/gradle/GradleProjectSystem.kt
+++ b/project-system-gradle/src/com/android/tools/idea/projectsystem/gradle/GradleProjectSystem.kt
@@ -86,7 +86,7 @@
 import java.io.File
 import java.nio.file.Path
 
-class GradleProjectSystem(val project: Project) : AndroidProjectSystem {
+open class GradleProjectSystem(val project: Project) : AndroidProjectSystem {
   private val moduleHierarchyProvider: GradleModuleHierarchyProvider = GradleModuleHierarchyProvider(project)
   private val mySyncManager: ProjectSystemSyncManager = GradleProjectSystemSyncManager(project)
   private val myBuildManager: ProjectSystemBuildManager = GradleProjectSystemBuildManager(project)
@@ -168,9 +168,9 @@
     )
   }
 
-  override fun validateRunConfiguration(runConfiguration: RunConfiguration): List<ValidationError> {
+  override fun validateRunConfiguration(runConfiguration: RunConfiguration, quickFixCallback: Runnable?): List<ValidationError> {
     val context = runConfiguration.getGradleContext() ?: return super.validateRunConfiguration(runConfiguration)
-    return GradleApkProvider.doValidate(context.androidFacet, context.isTestConfiguration, context.alwaysDeployApkFromBundle)
+    return GradleApkProvider.doValidate(context.androidFacet, context.isTestConfiguration, context.alwaysDeployApkFromBundle, quickFixCallback)
   }
 
   internal fun getBuiltApksForSelectedVariant(
diff --git a/project-system-gradle/src/com/android/tools/idea/run/GradleApkProvider.java b/project-system-gradle/src/com/android/tools/idea/run/GradleApkProvider.java
index 88bd8c9..5e8017e 100644
--- a/project-system-gradle/src/com/android/tools/idea/run/GradleApkProvider.java
+++ b/project-system-gradle/src/com/android/tools/idea/run/GradleApkProvider.java
@@ -611,7 +611,8 @@
   @NotNull
   public static ImmutableList<ValidationError> doValidate(@NotNull AndroidFacet androidFacet,
                                                           boolean isTest,
-                                                          boolean alwaysDeployApkFromBundle) {
+                                                          boolean alwaysDeployApkFromBundle,
+                                                          @Nullable Runnable quickFixCallback) {
     ImmutableList.Builder<ValidationError> result = ImmutableList.builder();
 
     GradleAndroidModel gradleAndroidModel = GradleAndroidModel.get(androidFacet);
@@ -654,8 +655,10 @@
 
     final String message =
       AndroidBundle.message("run.error.apk.not.signed", gradleAndroidModel.getSelectedVariant().getDisplayName());
-    ConfigurationQuickFix quickFix = new UnsignedApkQuickFix(module, gradleAndroidModel.getSelectedVariant().getBuildType());
-    result.add(ValidationError.fatal(message, quickFix));
+    UnsignedApkQuickFix quickfix = UnsignedApkQuickFix.create(module,
+                                                              gradleAndroidModel.getSelectedVariant().getBuildType(),
+                                                              quickFixCallback);
+    result.add(ValidationError.fatal(message, quickfix));
     return result.build();
   }
 
diff --git a/project-system-gradle/src/com/android/tools/idea/run/UnsignedApkQuickFix.kt b/project-system-gradle/src/com/android/tools/idea/run/UnsignedApkQuickFix.kt
index 54dd639..445e447 100644
--- a/project-system-gradle/src/com/android/tools/idea/run/UnsignedApkQuickFix.kt
+++ b/project-system-gradle/src/com/android/tools/idea/run/UnsignedApkQuickFix.kt
@@ -20,12 +20,14 @@
 import com.android.tools.idea.gradle.dsl.api.android.SigningConfigModel
 import com.android.tools.idea.gradle.dsl.api.ext.ReferenceTo
 import com.android.tools.idea.gradle.project.sync.GradleSyncInvoker
+import com.android.tools.idea.gradle.project.sync.GradleSyncListener
 import com.google.common.annotations.VisibleForTesting
 import com.google.wireless.android.sdk.stats.GradleSyncStats
 import com.intellij.openapi.actionSystem.DataContext
 import com.intellij.openapi.command.WriteCommandAction
 import com.intellij.openapi.module.Module
 import com.intellij.openapi.options.ConfigurationQuickFix
+import com.intellij.openapi.project.Project
 import com.intellij.openapi.ui.ComboBox
 import com.intellij.openapi.ui.DialogWrapper
 import com.intellij.ui.HyperlinkLabel
@@ -37,41 +39,107 @@
 import javax.swing.JComponent
 import javax.swing.JPanel
 
-/**
- * Runnable to fix unsigned APK error.
- */
-class UnsignedApkQuickFix @VisibleForTesting constructor(
-  private val module: Module,
-  private val selectedBuildTypeName: String,
-  private val makeSigningConfigSelector: (GradleBuildModel) -> SigningConfigSelector) : ConfigurationQuickFix {
+/** Runnable to fix unsigned APK error. */
+@Suppress("UnstableApiUsage")
+class UnsignedApkQuickFix
+@VisibleForTesting
+constructor(
+  val module: Module,
+  val selectedBuildTypeName: String,
+  val callback: Runnable?,
+  private val makeSigningConfigSelector: (GradleBuildModel) -> SigningConfigSelector
+) : ConfigurationQuickFix {
   /**
-   * Instantiates a dialog as the quick fix action for unsigned APK error. When user closed the dialog with the OK button, the selected
-   * signing config is picked.
+   * Instantiates a dialog as the quick fix action for unsigned APK error. When user closed the
+   * dialog with the OK button, the selected signing config is picked.
    *
    * @param module an IDEA module
    * @param selectedBuildTypeName name of the currently selected build type, e.g. debug
+   * @param callback a Runnable to execute after Gradle sync finishes
    */
-  constructor(module: Module, selectedBuildTypeName: String) : this(
-    module, selectedBuildTypeName, { gradleBuildModel -> SigningConfigSelectorDialog(gradleBuildModel.android().signingConfigs()) }
+  constructor(
+    module: Module,
+    selectedBuildTypeName: String,
+    callback: Runnable?
+  ) : this(
+    module,
+    selectedBuildTypeName,
+    callback,
+    { gradleBuildModel -> SigningConfigSelectorDialog(gradleBuildModel.android().signingConfigs()) }
   )
 
   override fun applyFix(dataContext: DataContext) {
-    val gradleBuildModel = GradleModelProvider.getInstance().getProjectModel(module.project).getModuleBuildModel(module)
+    val gradleBuildModel =
+      GradleModelProvider.getInstance().getProjectModel(module.project).getModuleBuildModel(module)
     if (gradleBuildModel != null) {
       val signingConfigSelector = makeSigningConfigSelector(gradleBuildModel)
       if (signingConfigSelector.showAndGet()) {
-        gradleBuildModel.android().buildTypes().find { it.name() == selectedBuildTypeName }?.let { selectedBuildType ->
-          selectedBuildType.signingConfig().setValue(ReferenceTo(signingConfigSelector.selectedConfig()))
-          // Write signingConfig to Gradle.
-          WriteCommandAction.runWriteCommandAction(module.project, "Select Signing Config", null, { gradleBuildModel.applyChanges() })
-          // Trigger Gradle sync for the signingConfig to take effect.
-          GradleSyncInvoker.getInstance().requestProjectSync(
-            module.project, GradleSyncInvoker.Request(GradleSyncStats.Trigger.TRIGGER_QF_SIGNING_CONFIG_SELECTED), null)
-        }
+        gradleBuildModel
+          .android()
+          .buildTypes()
+          .find { it.name() == selectedBuildTypeName }
+          ?.let { selectedBuildType ->
+            selectedBuildType
+              .signingConfig()
+              .setValue(ReferenceTo(signingConfigSelector.selectedConfig()))
+            // Write signingConfig to Gradle.
+            WriteCommandAction.runWriteCommandAction(
+              module.project,
+              "Select Signing Config",
+              null,
+              { gradleBuildModel.applyChanges() }
+            )
+            // Trigger Gradle sync for the signingConfig to take effect.
+            GradleSyncInvoker.getInstance()
+              .requestProjectSync(
+                module.project,
+                GradleSyncInvoker.Request(
+                  GradleSyncStats.Trigger.TRIGGER_QF_SIGNING_CONFIG_SELECTED
+                ),
+                object : GradleSyncListener {
+                  override fun syncSucceeded(project: Project) {
+                    callback?.run()
+                  }
+
+                  override fun syncFailed(project: Project, errorMessage: String) {
+                    callback?.run()
+                  }
+                }
+              )
+          }
       }
+    } else {
+      throw IllegalStateException(
+        "Gradle build model should not be null for module: ${module.name}."
+      )
     }
-    else {
-      throw IllegalStateException("Gradle build model should not be null for module: ${module.name}.")
+  }
+
+  companion object {
+    @VisibleForTesting var unsignedApkQuickFix: UnsignedApkQuickFix? = null
+
+    /**
+     * To avoid repeatedly creating a new QuickFix (and losing the calling SettingsEditor's
+     * callback), only instantiate a new UnsignedApkQuickFix if the cached one doesn't match. Null
+     * callbacks also will not overwrite the existing cache if the module and build type remain the
+     * same.
+     */
+    @JvmStatic
+    fun create(
+      module: Module,
+      buildType: String,
+      quickFixCallback: Runnable?
+    ): UnsignedApkQuickFix? {
+      if (
+        unsignedApkQuickFix == null ||
+          unsignedApkQuickFix?.module != module ||
+          unsignedApkQuickFix?.selectedBuildTypeName != buildType ||
+          (quickFixCallback != null && unsignedApkQuickFix?.callback != quickFixCallback)
+      ) {
+        unsignedApkQuickFix = UnsignedApkQuickFix(module, buildType, quickFixCallback)
+      }
+
+      return unsignedApkQuickFix
     }
   }
 }
@@ -84,25 +152,27 @@
    */
   fun showAndGet(): Boolean
 
-  /**
-   * @return the selected signing config model
-   */
+  /** @return the selected signing config model */
   fun selectedConfig(): SigningConfigModel
 }
 
 /**
- * Dialog for selecting an existing signing config, useful for quick-fixing unsigned APK Run config error.
+ * Dialog for selecting an existing signing config, useful for quick-fixing unsigned APK Run config
+ * error.
  */
-class SigningConfigSelectorDialog(signingConfigs: Collection<SigningConfigModel>) : DialogWrapper(false), SigningConfigSelector {
+class SigningConfigSelectorDialog(signingConfigs: Collection<SigningConfigModel>) :
+  DialogWrapper(false), SigningConfigSelector {
   private val rootPanel = JPanel(BorderLayout())
 
-  @VisibleForTesting
-  val signingConfigComboBox = ComboBox<SigningConfigModel>()
+  @VisibleForTesting val signingConfigComboBox = ComboBox<SigningConfigModel>()
 
   init {
     title = "Select Signing Config"
-    signingConfigs.forEach(Consumer { item: SigningConfigModel -> signingConfigComboBox.addItem(item) })
-    signingConfigComboBox.renderer = SimpleListCellRenderer.create("<unnamed>", SigningConfigModel::name)
+    signingConfigs.forEach(
+      Consumer { item: SigningConfigModel -> signingConfigComboBox.addItem(item) }
+    )
+    signingConfigComboBox.renderer =
+      SimpleListCellRenderer.create("<unnamed>", SigningConfigModel::name)
     init()
   }
 
@@ -110,12 +180,13 @@
 
   override fun createCenterPanel(): JComponent {
     return rootPanel.apply {
-      add(JPanel(FlowLayout()).apply {
-        add(JBLabel("Debug keys should be strictly used for development purposes only."))
-        add(HyperlinkLabel("Learn more").apply {
-          setHyperlinkTarget(DOC_URL)
-        })
-      }, BorderLayout.NORTH)
+      add(
+        JPanel(FlowLayout()).apply {
+          add(JBLabel("Debug keys should be strictly used for development purposes only."))
+          add(HyperlinkLabel("Learn more").apply { setHyperlinkTarget(DOC_URL) })
+        },
+        BorderLayout.NORTH
+      )
       add(signingConfigComboBox, BorderLayout.CENTER)
     }
   }
@@ -123,4 +194,4 @@
   companion object {
     const val DOC_URL = "https://developer.android.com/studio/publish/app-signing#debug-mode"
   }
-}
\ No newline at end of file
+}
diff --git a/project-system-gradle/src/org/jetbrains/android/actions/GenerateSignedApkAction.java b/project-system-gradle/src/org/jetbrains/android/actions/GenerateSignedApkAction.java
index bf9038a..5686a94 100644
--- a/project-system-gradle/src/org/jetbrains/android/actions/GenerateSignedApkAction.java
+++ b/project-system-gradle/src/org/jetbrains/android/actions/GenerateSignedApkAction.java
@@ -21,6 +21,7 @@
 import com.android.tools.idea.gradle.project.GradleProjectInfo;
 import com.android.tools.idea.project.AndroidProjectInfo;
 import com.android.tools.idea.projectsystem.ProjectSystemUtil;
+import com.intellij.openapi.actionSystem.ActionUpdateThread;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.project.Project;
@@ -34,6 +35,13 @@
 import org.jetbrains.annotations.VisibleForTesting;
 
 public class GenerateSignedApkAction extends AnAction {
+
+  @NotNull
+  @Override
+  public ActionUpdateThread getActionUpdateThread() {
+    return ActionUpdateThread.BGT;
+  }
+
   public GenerateSignedApkAction() {
     super(AndroidBundle.message(StudioFlags.RUNDEBUG_ANDROID_BUILD_BUNDLE_ENABLED.get() ? "android.generate.signed.apk.action.bundle.text" : "android.generate.signed.apk.action.text"));
   }
diff --git a/project-system-gradle/src/org/jetbrains/android/exportSignedPackage/ApkStep.java b/project-system-gradle/src/org/jetbrains/android/exportSignedPackage/ApkStep.java
index 1bffbda..7d8a956 100644
--- a/project-system-gradle/src/org/jetbrains/android/exportSignedPackage/ApkStep.java
+++ b/project-system-gradle/src/org/jetbrains/android/exportSignedPackage/ApkStep.java
@@ -109,7 +109,11 @@
   @Override
   public void _init() {
     if (myInited) return;
-    final AndroidFacet facet = myWizard.getFacet();
+    _init(myWizard.getFacet());
+  }
+
+  @VisibleForTesting
+  void _init(AndroidFacet facet) {
     Module module = facet.getModule();
 
     PropertiesComponent properties = PropertiesComponent.getInstance(module.getProject());
@@ -210,7 +214,7 @@
 
   @Override
   public void _commit(boolean finishChosen) throws CommitStepException {
-    final String apkPath = myApkPathField.getText().trim();
+    final String apkPath = myApkPathField.getText().stripLeading();
     if (apkPath.isEmpty()) {
       throw new CommitStepException(AndroidBundle.message("android.extract.package.specify.apk.path.error"));
     }
diff --git a/project-system-gradle/src/org/jetbrains/android/exportSignedPackage/GradleSignStep.java b/project-system-gradle/src/org/jetbrains/android/exportSignedPackage/GradleSignStep.java
index 43ffd66..72c07bd 100644
--- a/project-system-gradle/src/org/jetbrains/android/exportSignedPackage/GradleSignStep.java
+++ b/project-system-gradle/src/org/jetbrains/android/exportSignedPackage/GradleSignStep.java
@@ -46,7 +46,8 @@
 public class GradleSignStep extends ExportSignedPackageWizardStep {
   @NonNls private static final String PROPERTY_APK_PATH = "ExportApk.ApkPath";
   @NonNls private static final String PROPERTY_BUNDLE_PATH = "ExportBundle.BundlePath";
-  @NonNls private static final String PROPERTY_BUILD_VARIANTS = "ExportApk.BuildVariants";
+  @VisibleForTesting
+  @NonNls static final String PROPERTY_BUILD_VARIANTS = "ExportApk.BuildVariants";
 
   private JPanel myContentPanel;
   private TextFieldWithBrowseButton myApkPathField;
@@ -69,7 +70,12 @@
 
   @Override
   public void _init() {
-    myAndroidModel = GradleAndroidModel.get(myWizard.getFacet());
+    _init(GradleAndroidModel.get(myWizard.getFacet()));
+  }
+
+  @VisibleForTesting
+  void _init(GradleAndroidModel androidModel) {
+    myAndroidModel = androidModel;
 
     PropertiesComponent properties = PropertiesComponent.getInstance(myWizard.getProject());
 
@@ -111,7 +117,7 @@
       throw new CommitStepException(AndroidBundle.message("android.apk.sign.gradle.no.model"));
     }
 
-    final String apkFolder = myApkPathField.getText().trim();
+    final String apkFolder = myApkPathField.getText().stripLeading();
     if (apkFolder.isEmpty()) {
       throw new CommitStepException(AndroidBundle.message("android.apk.sign.gradle.missing.destination", myWizard.getTargetType()));
     }
diff --git a/android/gradle/testSrc/com/android/tools/idea/gradle/project/build/invoker/BuildStopperTest.java b/project-system-gradle/testSrc/com/android/tools/idea/gradle/project/build/invoker/BuildStopperTest.java
similarity index 100%
rename from android/gradle/testSrc/com/android/tools/idea/gradle/project/build/invoker/BuildStopperTest.java
rename to project-system-gradle/testSrc/com/android/tools/idea/gradle/project/build/invoker/BuildStopperTest.java
diff --git a/project-system-gradle/testSrc/com/android/tools/idea/gradle/service/notification/ProjectJarFileTrackerTest.java b/project-system-gradle/testSrc/com/android/tools/idea/gradle/service/notification/ProjectJarFileTrackerTest.java
new file mode 100644
index 0000000..edb1f1a
--- /dev/null
+++ b/project-system-gradle/testSrc/com/android/tools/idea/gradle/service/notification/ProjectJarFileTrackerTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.gradle.service.notification;
+
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import com.android.tools.idea.gradle.service.notification.ProjectJarFileTracker;
+import com.android.tools.idea.gradle.service.notification.ProjectJarFileTracker.JarFileNotificationProvider;
+import com.android.tools.idea.testing.IdeComponents;
+import com.intellij.openapi.application.WriteAction;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.testFramework.LightPlatformTestCase;
+import com.intellij.testFramework.PlatformTestUtil;
+import com.intellij.ui.EditorNotificationPanel;
+import com.intellij.ui.EditorNotifications;
+import java.io.IOException;
+import org.junit.Test;
+import org.mockito.Mock;
+
+public class ProjectJarFileTrackerTest extends LightPlatformTestCase {
+  @Mock private FileEditor myFileEditor;
+  @Mock private EditorNotifications myEditorNotifications;
+  private JarFileNotificationProvider myNotificationProvider;
+
+  private ProjectJarFileTracker myProjectJarFileTracker;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    initMocks(this);
+
+    new IdeComponents(getProject(), getTestRootDisposable()).replaceProjectService(EditorNotifications.class, myEditorNotifications);
+
+    myProjectJarFileTracker = ProjectJarFileTracker.getInstance(getProject());
+    myNotificationProvider = new JarFileNotificationProvider();
+  }
+
+  @Test
+  public void testAddFile() throws IOException {
+    VirtualFile projectDir = PlatformTestUtil.getOrCreateProjectBaseDir(getProject());
+    VirtualFile jarFile =  WriteAction.computeAndWait(() -> projectDir.createChildData(projectDir, "test.jar"));
+    assertTrue(myProjectJarFileTracker.getJarFilesChanged());
+    EditorNotificationPanel panel = myNotificationProvider.collectNotificationData(getProject(), jarFile).apply(myFileEditor);
+    assertEquals(panel.getText(), "Jar files have been added/removed since last project sync. Sync may be necessary for the IDE to work properly.");
+  }
+
+
+
+}
\ No newline at end of file
diff --git a/project-system-integration-tests/testSrc/com/android/tools/idea/projectsystem/gradle/GradleTokensTest.kt b/project-system-integration-tests/testSrc/com/android/tools/idea/projectsystem/gradle/GradleTokensTest.kt
index ce11acc..e530f6d 100644
--- a/project-system-integration-tests/testSrc/com/android/tools/idea/projectsystem/gradle/GradleTokensTest.kt
+++ b/project-system-integration-tests/testSrc/com/android/tools/idea/projectsystem/gradle/GradleTokensTest.kt
@@ -37,7 +37,7 @@
       val matches = system.installation.ideaLog.waitForMatchingLine(".*VerifyGradleTokens - ([0-9]+)/([0-9]+) problems? found.*", 900, TimeUnit.SECONDS)
       assertThat(matches.groupCount()).isEqualTo(2)
       assertThat(matches.group(1)).isEqualTo("0")
-      assertThat(matches.group(2)).isEqualTo("3")
+      assertThat(matches.group(2)).isEqualTo("5")
     }
   }
 }
\ No newline at end of file
diff --git a/project-system/src/META-INF/project-system-plugin.xml b/project-system/src/META-INF/project-system-plugin.xml
index 4c8347c..d807885 100644
--- a/project-system/src/META-INF/project-system-plugin.xml
+++ b/project-system/src/META-INF/project-system-plugin.xml
@@ -20,6 +20,9 @@
                     area="IDEA_PROJECT"/>
     <extensionPoint qualifiedName="com.android.androidStartupActivity"
                     interface="com.android.tools.idea.AndroidStartupActivity"/>
+    <extensionPoint qualifiedName="com.android.tools.idea.model.mergedManifestInfoToken"
+                    interface="com.android.tools.idea.model.MergedManifestInfoToken"
+                    area="IDEA_PROJECT"/>
   </extensionPoints>
   <extensions defaultExtensionNs="com.intellij">
     <projectService serviceImplementation="com.android.tools.idea.projectsystem.ProjectSystemService"/>
diff --git a/project-system/src/com/android/tools/idea/model/MergedManifestInfoToken.java b/project-system/src/com/android/tools/idea/model/MergedManifestInfoToken.java
new file mode 100644
index 0000000..64203cc
--- /dev/null
+++ b/project-system/src/com/android/tools/idea/model/MergedManifestInfoToken.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tools.idea.model;
+
+import com.android.manifmerger.ManifestMerger2;
+import com.android.tools.idea.projectsystem.AndroidProjectSystem;
+import com.android.tools.idea.projectsystem.Token;
+import com.intellij.openapi.extensions.ExtensionPointName;
+
+public interface MergedManifestInfoToken<P extends AndroidProjectSystem> extends Token {
+  ExtensionPointName<MergedManifestInfoToken<AndroidProjectSystem>>
+    EP_NAME = new ExtensionPointName<>("com.android.tools.idea.model.mergedManifestInfoToken");
+
+  /**
+   * Allows the {@param projectSystem} to affect the manifest merger invoker builder {@param invoker} according
+   * to build-system-specific project aspects.
+   * <p>
+   * Note that this method cannot remove features from the invoker builder; if any features need to be conditionally
+   * included in any build system, those features must be handled within these methods for all build systems.
+   *
+   * @param projectSystem
+   * @param invoker
+   * @return the modified invoker
+   */
+  ManifestMerger2.Invoker withProjectSystemFeatures(P projectSystem, ManifestMerger2.Invoker invoker);
+}
diff --git a/project-system/src/com/android/tools/idea/projectsystem/AndroidModuleSystem.kt b/project-system/src/com/android/tools/idea/projectsystem/AndroidModuleSystem.kt
index 742d260..146f055 100644
--- a/project-system/src/com/android/tools/idea/projectsystem/AndroidModuleSystem.kt
+++ b/project-system/src/com/android/tools/idea/projectsystem/AndroidModuleSystem.kt
@@ -366,8 +366,6 @@
   /** Whether AndroidX libraries should be used instead of legacy support libraries. */
   val useAndroidX: Boolean get() = false // TODO(270044829): fix tests to make this true by default
 
-  val enableVcsInfo: Boolean get() = false
-
   /** Whether [desugarLibraryConfigFiles] can be determined for this AGP version */
   val desugarLibraryConfigFilesKnown: Boolean get() = false
 
diff --git a/project-system/src/com/android/tools/idea/projectsystem/AndroidProjectSystem.kt b/project-system/src/com/android/tools/idea/projectsystem/AndroidProjectSystem.kt
index 7593315..14d4ed4 100644
--- a/project-system/src/com/android/tools/idea/projectsystem/AndroidProjectSystem.kt
+++ b/project-system/src/com/android/tools/idea/projectsystem/AndroidProjectSystem.kt
@@ -93,7 +93,11 @@
   fun getApkProvider(runConfiguration: RunConfiguration): ApkProvider? = null
 
   fun validateRunConfiguration(runConfiguration: RunConfiguration): List<ValidationError> {
-    return listOf(ValidationError.fatal("Run configuration ${runConfiguration.name} is not supported in this project"));
+    return validateRunConfiguration(runConfiguration, null)
+  }
+
+  fun validateRunConfiguration(runConfiguration: RunConfiguration, quickFixCallback: Runnable?): List<ValidationError> {
+    return listOf(ValidationError.fatal("Run configuration ${runConfiguration.name} is not supported in this project"))
   }
 
   /**
diff --git a/streaming/screen-sharing-agent/app/src/main/cpp/accessors/display_manager.cc b/streaming/screen-sharing-agent/app/src/main/cpp/accessors/display_manager.cc
index e3c7a3a..03935f8 100644
--- a/streaming/screen-sharing-agent/app/src/main/cpp/accessors/display_manager.cc
+++ b/streaming/screen-sharing-agent/app/src/main/cpp/accessors/display_manager.cc
@@ -127,10 +127,13 @@
 }
 
 void DisplayManager::UnregisterDisplayListener(Jni jni, DisplayManager::DisplayListener* listener) {
-  InitializeStatics(jni);
-  if (display_listener_dispatcher_ == nullptr) {
-    return;
+  {
+    scoped_lock lock(static_initialization_mutex);
+    if (display_listener_dispatcher_ == nullptr) {
+      return;
+    }
   }
+
   for (;;) {
     auto old_listeners = display_listeners_.load();
     auto new_listeners = new vector<DisplayListener*>(*old_listeners);
@@ -138,10 +141,10 @@
     if (pos != new_listeners->end()) {
       new_listeners->erase(pos);
     }
-    if (new_listeners->empty()) {
-      display_listener_dispatcher_->Stop();
-    }
     if (display_listeners_.compare_exchange_strong(old_listeners, new_listeners)) {
+      if (new_listeners->empty()) {
+        display_listener_dispatcher_->Stop();
+      }
       delete old_listeners;
       break;
     }
@@ -149,6 +152,25 @@
   }
 }
 
+void DisplayManager::UnregisterAllDisplayListeners(Jni jni) {
+  {
+    scoped_lock lock(static_initialization_mutex);
+    if (display_listener_dispatcher_ == nullptr) {
+      return;
+    }
+  }
+
+  auto empty_listeners = new vector<DisplayListener*>();
+  for (;;) {
+    auto old_listeners = display_listeners_.load();
+    if (display_listeners_.compare_exchange_strong(old_listeners, empty_listeners)) {
+      display_listener_dispatcher_->Stop();
+      delete old_listeners;
+      break;
+    }
+  }
+}
+
 void DisplayManager::OnDisplayAdded(Jni jni, int32_t display_id) {
   InitializeStatics(jni);
   Log::D("DisplayManager::OnDisplayAdded %d", display_id);
diff --git a/streaming/screen-sharing-agent/app/src/main/cpp/accessors/display_manager.h b/streaming/screen-sharing-agent/app/src/main/cpp/accessors/display_manager.h
index 44d9580..360f314 100644
--- a/streaming/screen-sharing-agent/app/src/main/cpp/accessors/display_manager.h
+++ b/streaming/screen-sharing-agent/app/src/main/cpp/accessors/display_manager.h
@@ -43,6 +43,7 @@
   static std::vector<int32_t> GetDisplayIds(Jni jni);
   static void RegisterDisplayListener(Jni jni, DisplayListener* listener);
   static void UnregisterDisplayListener(Jni jni, DisplayListener* listener);
+  static void UnregisterAllDisplayListeners(Jni jni);
 
   static void OnDisplayAdded(Jni jni, int32_t display_id);
   static void OnDisplayChanged(Jni jni, int32_t display_id);
diff --git a/streaming/screen-sharing-agent/app/src/main/cpp/agent.cc b/streaming/screen-sharing-agent/app/src/main/cpp/agent.cc
index 5c176d5..85ace6e 100644
--- a/streaming/screen-sharing-agent/app/src/main/cpp/agent.cc
+++ b/streaming/screen-sharing-agent/app/src/main/cpp/agent.cc
@@ -231,13 +231,13 @@
 
 void Agent::Shutdown() {
   if (!shutting_down_.exchange(true)) {
-    if (controller_ != nullptr) {
-      controller_->Stop();
-    }
-    close(control_socket_fd_);
     for (auto& it : display_streamers_) {
       it.second.Stop();
     }
+    DisplayManager::UnregisterAllDisplayListeners(Jvm::GetJni());
+    if (controller_ != nullptr) {
+      controller_->Stop();
+    }
     close(video_socket_fd_);
     RestoreEnvironment();
   }
diff --git a/streaming/screen-sharing-agent/app/src/main/cpp/controller.cc b/streaming/screen-sharing-agent/app/src/main/cpp/controller.cc
index 55c9db0..34f1a76 100644
--- a/streaming/screen-sharing-agent/app/src/main/cpp/controller.cc
+++ b/streaming/screen-sharing-agent/app/src/main/cpp/controller.cc
@@ -116,6 +116,8 @@
 
 Controller::~Controller() {
   Stop();
+  input_stream_.Close();
+  output_stream_.Close();
   delete pointer_helper_;
   delete key_character_map_;
 }
@@ -124,8 +126,7 @@
   if (device_supports_multiple_states_) {
     DeviceStateManager::RemoveDeviceStateListener(&device_state_listener_);
   }
-  input_stream_.Close();
-  output_stream_.Close();
+  stopped = true;
 }
 
 void Controller::Initialize() {
@@ -179,15 +180,17 @@
 
   try {
     for (;;) {
-      if (max_synced_clipboard_length_ != 0) {
-        SendClipboardChangedNotification();
-      }
+      if (!stopped) {
+        if (max_synced_clipboard_length_ != 0) {
+          SendClipboardChangedNotification();
+        }
 
-      if (device_supports_multiple_states_) {
-        SendDeviceStateNotification();
-      }
+        if (device_supports_multiple_states_) {
+          SendDeviceStateNotification();
+        }
 
-      SendPendingDisplayEvents();
+        SendPendingDisplayEvents();
+      }
 
       SetReceiveTimeoutMillis(SOCKET_RECEIVE_TIMEOUT_MILLIS, socket_fd_);  // Set a receive timeout to avoid blocking for a long time.
       int32_t message_type;
@@ -198,7 +201,9 @@
       }
       SetReceiveTimeoutMillis(0, socket_fd_);  // Remove receive timeout for reading the rest of the message.
       unique_ptr<ControlMessage> message = ControlMessage::Deserialize(message_type, input_stream_);
-      ProcessMessage(*message);
+      if (!stopped) {
+        ProcessMessage(*message);
+      }
     }
   } catch (EndOfFile& e) {
     Log::D("Controller::Run: End of command stream");
diff --git a/streaming/screen-sharing-agent/app/src/main/cpp/controller.h b/streaming/screen-sharing-agent/app/src/main/cpp/controller.h
index e5e2dfa..335172f 100644
--- a/streaming/screen-sharing-agent/app/src/main/cpp/controller.h
+++ b/streaming/screen-sharing-agent/app/src/main/cpp/controller.h
@@ -111,6 +111,7 @@
   int socket_fd_;  // Owned.
   Base128InputStream input_stream_;
   Base128OutputStream output_stream_;
+  volatile bool stopped = false;
   PointerHelper* pointer_helper_;  // Owned.
   JObjectArray pointer_properties_;  // MotionEvent.PointerProperties[]
   JObjectArray pointer_coordinates_;  // MotionEvent.PointerCoords[]
diff --git a/streaming/screen-sharing-agent/app/src/main/cpp/log.cc b/streaming/screen-sharing-agent/app/src/main/cpp/log.cc
index 5957d1c..0992afc 100644
--- a/streaming/screen-sharing-agent/app/src/main/cpp/log.cc
+++ b/streaming/screen-sharing-agent/app/src/main/cpp/log.cc
@@ -26,7 +26,19 @@
 
 using namespace std;
 
-static constexpr char TAG[] = "studio.screen.sharing";
+namespace {
+
+constexpr char TAG[] = "studio.screen.sharing";
+
+// Calls the System.exit method.
+[[noreturn]] void Exit(int exitCode) {
+  Jni jni = Jvm::GetJni();
+  JClass system = jni.GetClass("java/lang/System");
+  jmethodID exit_method = system.GetStaticMethod(jni, "exit", "(I)V");
+  system.CallStaticVoidMethod(exit_method, exitCode);
+}
+
+}
 
 Log::Level Log::level_ = Log::Level::INFO;
 
@@ -81,8 +93,8 @@
   va_start(args, message);
   vfprintf(stderr, message, args);
   va_end(args);
-  Agent::RestoreEnvironment();
-  exit(EXIT_FAILURE);
+  Agent::Shutdown();
+  Exit(EXIT_FAILURE);
 }
 
 void Log::Fatal(ExitCode exit_code, const char* message, ...) {
@@ -93,8 +105,8 @@
   va_start(args, message);
   vfprintf(stderr, message, args);
   va_end(args);
-  Agent::RestoreEnvironment();
-  exit(exit_code);
+  Agent::Shutdown();
+  Exit(exit_code);
 }
 
 }  // namespace screensharing
diff --git a/streaming/screen-sharing-agent/app/src/main/cpp/main.cc b/streaming/screen-sharing-agent/app/src/main/cpp/main.cc
index c2dbe71..e746c11 100644
--- a/streaming/screen-sharing-agent/app/src/main/cpp/main.cc
+++ b/streaming/screen-sharing-agent/app/src/main/cpp/main.cc
@@ -37,6 +37,4 @@
 
   Agent::Run(args);
   Log::I("Screen sharing agent stopped");
-  // Exit explicitly to bypass the final JVM cleanup that for some unclear reason sometimes crashes with SIGSEGV.
-  exit(EXIT_SUCCESS);
 }
diff --git a/streaming/screen-sharing-agent/app/src/main/cpp/session_environment.cc b/streaming/screen-sharing-agent/app/src/main/cpp/session_environment.cc
index 1112950..239a166 100644
--- a/streaming/screen-sharing-agent/app/src/main/cpp/session_environment.cc
+++ b/streaming/screen-sharing-agent/app/src/main/cpp/session_environment.cc
@@ -32,17 +32,6 @@
 constexpr int BATTERY_PLUGGED_USB = 2;
 constexpr int BATTERY_PLUGGED_WIRELESS = 4;
 
-// Names an location of the screen sharing agent's files.
-#define SCREEN_SHARING_AGENT_JAR_NAME "screen-sharing-agent.jar"
-#define SCREEN_SHARING_AGENT_SO_NAME "libscreen-sharing-agent.so"
-#define DEVICE_PATH_BASE "/data/local/tmp/.studio"
-
-// Removes files of the screen sharing agent from the persistent storage.
-void RemoveAgentFiles() {
-  remove(DEVICE_PATH_BASE "/" SCREEN_SHARING_AGENT_JAR_NAME);
-  remove(DEVICE_PATH_BASE "/" SCREEN_SHARING_AGENT_SO_NAME);
-}
-
 }  // namespace
 
 SessionEnvironment::SessionEnvironment(bool turn_off_display)
@@ -64,8 +53,6 @@
       Log::W("Unable to get display token to turn off display");
     }
   }
-
-  RemoveAgentFiles();
 }
 
 SessionEnvironment::~SessionEnvironment() {
diff --git a/streaming/src/com/android/tools/idea/streaming/core/RunningDevicePanel.kt b/streaming/src/com/android/tools/idea/streaming/core/RunningDevicePanel.kt
index 5d599ad..47cfbdd 100644
--- a/streaming/src/com/android/tools/idea/streaming/core/RunningDevicePanel.kt
+++ b/streaming/src/com/android/tools/idea/streaming/core/RunningDevicePanel.kt
@@ -21,10 +21,12 @@
 import com.android.tools.adtui.util.ActionToolbarUtil
 import com.android.tools.idea.streaming.SERIAL_NUMBER_KEY
 import com.intellij.ide.ui.customization.CustomActionsSchema
+import com.intellij.openapi.Disposable
 import com.intellij.openapi.actionSystem.ActionManager
 import com.intellij.openapi.actionSystem.ActionToolbar
 import com.intellij.openapi.actionSystem.DataProvider
 import com.intellij.openapi.actionSystem.DefaultActionGroup
+import com.intellij.openapi.util.Disposer
 import com.intellij.ui.EditorNotificationPanel
 import com.intellij.ui.IdeBorderFactory
 import com.intellij.ui.JBColor
@@ -44,7 +46,7 @@
   val id: DeviceId,
   mainToolbarId: String,
   secondaryToolbarId: String,
-) : BorderLayoutPanel(), DataProvider {
+) : BorderLayoutPanel(), DataProvider, Disposable {
 
   /** Plain text name of the device. */
   internal abstract val title: String
@@ -118,6 +120,10 @@
     }
   }
 
+  override fun dispose() {
+    destroyContent()
+  }
+
   @Suppress("SameParameterValue")
   private fun createToolbar(toolbarId: String, horizontal: Boolean): ActionToolbar {
     val actions = listOf(CustomActionsSchema.getInstance().getCorrectedAction(toolbarId)!!)
diff --git a/streaming/src/com/android/tools/idea/streaming/core/StreamingToolWindowFactory.kt b/streaming/src/com/android/tools/idea/streaming/core/StreamingToolWindowFactory.kt
index 248032f..0504ecc 100644
--- a/streaming/src/com/android/tools/idea/streaming/core/StreamingToolWindowFactory.kt
+++ b/streaming/src/com/android/tools/idea/streaming/core/StreamingToolWindowFactory.kt
@@ -40,11 +40,8 @@
   override fun init(toolWindow: ToolWindow) {
     if (StudioFlags.DEVICE_MIRRORING_TAB_DND.get()) {
       toolWindow.component.putClientProperty(ToolWindowContentUi.ALLOW_DND_FOR_TABS, true)
-      StreamingToolWindowManager(toolWindow)
     }
-    else {
-      StreamingToolWindowManagerNoDnd(toolWindow)
-    }
+    StreamingToolWindowManager(toolWindow)
   }
 
   private class MoveToWindowAction(private val toolWindow: ToolWindow) : ToolWindowWindowAction() {
diff --git a/streaming/src/com/android/tools/idea/streaming/core/StreamingToolWindowManager.kt b/streaming/src/com/android/tools/idea/streaming/core/StreamingToolWindowManager.kt
index d062326..95870e7 100644
--- a/streaming/src/com/android/tools/idea/streaming/core/StreamingToolWindowManager.kt
+++ b/streaming/src/com/android/tools/idea/streaming/core/StreamingToolWindowManager.kt
@@ -116,7 +116,9 @@
 import java.awt.Component
 import java.awt.EventQueue
 import java.awt.event.KeyEvent
+import java.text.Collator
 import java.time.Duration
+import java.util.Arrays
 
 private const val DEVICE_FRAME_VISIBLE_PROPERTY = "com.android.tools.idea.streaming.emulator.frame.visible"
 private const val DEVICE_FRAME_VISIBLE_DEFAULT = true
@@ -128,6 +130,10 @@
 
 private val ATTENTION_REQUEST_EXPIRATION = Duration.ofSeconds(30)
 
+private val COLLATOR = Collator.getInstance()
+
+private val TAB_COMPARATOR = compareBy<Content, Any?>(COLLATOR) { it.tabName ?: "" }.thenBy { ID_KEY.get(it) }
+
 /**
  * Manages contents of the Running Devices tool window. Listens to device connections and
  * disconnections and maintains [RunningDevicePanel]s, one per running AVD or a mirrored physical
@@ -390,7 +396,7 @@
     }
     for (deviceClient in deviceClients.values) {
       if (findContentBySerialNumberOfPhysicalDevice(deviceClient.deviceSerialNumber) == null) {
-        addPanel(DeviceToolWindowPanel(project, deviceClient))
+        addPanel(DeviceToolWindowPanel(toolWindow.disposable, project, deviceClient))
       }
     }
 
@@ -419,7 +425,9 @@
       // Restore content of visible panels.
       for (content in contentManager.selectedContents) {
         val panel = content.component as? RunningDevicePanel ?: continue
-        panel.createContent(deviceFrameVisible, savedUiState[panel.id])
+        if (!panel.hasContent) {
+          panel.createContent(deviceFrameVisible, savedUiState[panel.id])
+        }
       }
     }
 
@@ -460,7 +468,7 @@
 
   private fun addEmulatorPanel(emulator: EmulatorController) {
     emulator.addConnectionStateListener(connectionStateListener)
-    addPanel(EmulatorToolWindowPanel(project, emulator))
+    addPanel(EmulatorToolWindowPanel(toolWindow.disposable, project, emulator))
   }
 
   private fun addPanel(panel: RunningDevicePanel) {
@@ -480,13 +488,29 @@
 
     panel.zoomToolbarVisible = zoomToolbarIsVisible
 
-    if (findContentByDeviceId(panel.id) != null) {
-      thisLogger().error("An attempt to add a duplicate panel ${TraceUtils.getSimpleId(content)} ${content.displayName}\n" +
-                         TraceUtils.getCurrentStack() +
-                         "Panel creation history:\n${FlightRecorder.getAndClear().joinToString("\n")}")
+    if (StudioFlags.DEVICE_MIRRORING_TAB_DND.get()) {
+      if (findContentByDeviceId(panel.id) != null) {
+        thisLogger().error("An attempt to add a duplicate panel ${TraceUtils.getSimpleId(content)} ${content.displayName}\n" +
+                           TraceUtils.getCurrentStack() +
+                           "Panel creation history:\n${FlightRecorder.getAndClear().joinToString("\n")}")
+        return
+      }
+
+      // Add panel to the end.
+      contentManager.addContent(content)
+    }
+    else {
+      val index = Arrays.binarySearch(contentManager.contents, content, TAB_COMPARATOR).inv()
+      if (index < 0) {
+        thisLogger().error("An attempt to add a duplicate panel ${TraceUtils.getSimpleId(panel)} ${panel.title}\n" +
+                           FlightRecorder.getAndClear())
+        return
+      }
+
+      // Insert panel in alphabetical order of the title.
+      contentManager.addContent(content, index)
     }
 
-    contentManager.addContent(content)
     FlightRecorder.log { "${TraceUtils.getSimpleId(this)}: added panel ${TraceUtils.getSimpleId(content)} ${content.displayName}\n" +
                          TraceUtils.getCurrentStack() }
 
@@ -737,7 +761,7 @@
       if (contentShown) {
         updateMirroringHandlesFlow()
         deviceClient.establishAgentConnectionWithoutVideoStreamAsync() // Start the agent and connect to it proactively.
-        val panel = DeviceToolWindowPanel(project, deviceClient)
+        val panel = DeviceToolWindowPanel(toolWindow.disposable, project, deviceClient)
         addPanel(panel)
         if (activationLevel >= ActivationLevel.SELECT_TAB) {
           selectContent(panel, requestFocus = activationLevel >= ActivationLevel.ACTIVATE_TAB)
diff --git a/streaming/src/com/android/tools/idea/streaming/core/StreamingToolWindowManagerNoDnd.kt b/streaming/src/com/android/tools/idea/streaming/core/StreamingToolWindowManagerNoDnd.kt
deleted file mode 100644
index 3c47651..0000000
--- a/streaming/src/com/android/tools/idea/streaming/core/StreamingToolWindowManagerNoDnd.kt
+++ /dev/null
@@ -1,1153 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tools.idea.streaming.core
-
-import com.android.adblib.serialNumber
-import com.android.annotations.concurrency.AnyThread
-import com.android.annotations.concurrency.UiThread
-import com.android.sdklib.SdkVersionInfo
-import com.android.sdklib.deviceprovisioner.DeviceHandle
-import com.android.sdklib.deviceprovisioner.DeviceProvisioner
-import com.android.sdklib.deviceprovisioner.DeviceState
-import com.android.sdklib.deviceprovisioner.DeviceType
-import com.android.sdklib.deviceprovisioner.ReservationState
-import com.android.sdklib.deviceprovisioner.mapStateNotNull
-import com.android.sdklib.internal.avd.AvdInfo
-import com.android.tools.idea.adb.wireless.PairDevicesUsingWiFiAction
-import com.android.tools.idea.avdmanager.AvdLaunchListener
-import com.android.tools.idea.avdmanager.AvdLaunchListener.RequestType
-import com.android.tools.idea.avdmanager.AvdManagerConnection
-import com.android.tools.idea.concurrency.AndroidCoroutineScope
-import com.android.tools.idea.concurrency.addCallback
-import com.android.tools.idea.deviceprovisioner.DeviceProvisionerService
-import com.android.tools.idea.flags.StudioFlags
-import com.android.tools.idea.run.DeviceHeadsUpListener
-import com.android.tools.idea.streaming.DeviceMirroringSettings
-import com.android.tools.idea.streaming.EmulatorSettings
-import com.android.tools.idea.streaming.MirroringHandle
-import com.android.tools.idea.streaming.MirroringManager
-import com.android.tools.idea.streaming.MirroringState
-import com.android.tools.idea.streaming.RUNNING_DEVICES_TOOL_WINDOW_ID
-import com.android.tools.idea.streaming.core.RunningDevicePanel.UiState
-import com.android.tools.idea.streaming.device.DeviceClient
-import com.android.tools.idea.streaming.device.DeviceConfiguration
-import com.android.tools.idea.streaming.device.DeviceToolWindowPanel
-import com.android.tools.idea.streaming.device.composeDeviceName
-import com.android.tools.idea.streaming.device.dialogs.MirroringConfirmationDialog
-import com.android.tools.idea.streaming.emulator.EmulatorController
-import com.android.tools.idea.streaming.emulator.EmulatorController.ConnectionState
-import com.android.tools.idea.streaming.emulator.EmulatorController.ConnectionStateListener
-import com.android.tools.idea.streaming.emulator.EmulatorId
-import com.android.tools.idea.streaming.emulator.EmulatorToolWindowPanel
-import com.android.tools.idea.streaming.emulator.RunningEmulatorCatalog
-import com.android.utils.FlightRecorder
-import com.android.utils.TraceUtils
-import com.google.common.cache.CacheBuilder
-import com.intellij.collaboration.async.disposingScope
-import com.intellij.execution.configurations.GeneralCommandLine
-import com.intellij.execution.runners.ExecutionUtil
-import com.intellij.icons.AllIcons
-import com.intellij.ide.actions.ToggleToolbarAction
-import com.intellij.ide.util.PropertiesComponent
-import com.intellij.openapi.Disposable
-import com.intellij.openapi.actionSystem.ActionButtonComponent
-import com.intellij.openapi.actionSystem.ActionManager
-import com.intellij.openapi.actionSystem.ActionPlaces
-import com.intellij.openapi.actionSystem.ActionUpdateThread
-import com.intellij.openapi.actionSystem.AnActionEvent
-import com.intellij.openapi.actionSystem.DataContext
-import com.intellij.openapi.actionSystem.DefaultActionGroup
-import com.intellij.openapi.actionSystem.Separator
-import com.intellij.openapi.actionSystem.ToggleAction
-import com.intellij.openapi.application.EDT
-import com.intellij.openapi.components.service
-import com.intellij.openapi.diagnostic.thisLogger
-import com.intellij.openapi.project.DumbAware
-import com.intellij.openapi.project.DumbAwareAction
-import com.intellij.openapi.project.Project
-import com.intellij.openapi.ui.ex.MessagesEx.showErrorDialog
-import com.intellij.openapi.ui.popup.JBPopupFactory
-import com.intellij.openapi.ui.popup.JBPopupFactory.ActionSelectionAid
-import com.intellij.openapi.util.Disposer
-import com.intellij.openapi.util.Key
-import com.intellij.openapi.util.text.StringUtil
-import com.intellij.openapi.wm.ToolWindow
-import com.intellij.openapi.wm.ToolWindowManager
-import com.intellij.openapi.wm.ex.ToolWindowEx
-import com.intellij.openapi.wm.ex.ToolWindowManagerListener
-import com.intellij.ui.content.Content
-import com.intellij.ui.content.ContentFactory
-import com.intellij.ui.content.ContentManagerEvent
-import com.intellij.ui.content.ContentManagerListener
-import com.intellij.ui.popup.list.ListPopupImpl
-import com.intellij.util.Alarm
-import com.intellij.util.IncorrectOperationException
-import com.intellij.util.concurrency.AppExecutorUtil.createBoundedApplicationPoolExecutor
-import com.intellij.util.concurrency.EdtExecutorService
-import com.intellij.util.ui.UIUtil
-import icons.StudioIcons
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.asCoroutineDispatcher
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.guava.asDeferred
-import kotlinx.coroutines.guava.await
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
-import java.awt.Component
-import java.awt.EventQueue
-import java.awt.event.KeyEvent
-import java.text.Collator
-import java.time.Duration
-
-private const val DEVICE_FRAME_VISIBLE_PROPERTY = "com.android.tools.idea.streaming.emulator.frame.visible"
-private const val DEVICE_FRAME_VISIBLE_DEFAULT = true
-private const val ZOOM_TOOLBAR_VISIBLE_PROPERTY = "com.android.tools.idea.streaming.zoom.toolbar.visible"
-private const val ZOOM_TOOLBAR_VISIBLE_DEFAULT = true
-private const val EMULATOR_DISCOVERY_INTERVAL_MILLIS = 1000
-
-private val ID_KEY = Key.create<DeviceId>("device-id")
-
-private val ATTENTION_REQUEST_EXPIRATION = Duration.ofSeconds(30)
-
-private val COLLATOR = Collator.getInstance()
-
-private val PANEL_COMPARATOR = compareBy<RunningDevicePanel, Any?>(COLLATOR) { it.title }.thenBy { it.id }
-
-/**
- * Manages contents of the Running Devices tool window. Listens to device connections and
- * disconnections and maintains [RunningDevicePanel]s, one per running AVD or a mirrored physical
- * device.
- */
-@UiThread
-internal class StreamingToolWindowManagerNoDnd @AnyThread constructor(
-  private val toolWindow: ToolWindow,
-) : RunningEmulatorCatalog.Listener, DumbAware, Disposable {
-
-  private val project
-    @AnyThread get() = toolWindow.project
-  private val properties = PropertiesComponent.getInstance(project)
-  private val emulatorSettings = EmulatorSettings.getInstance()
-  private val deviceMirroringSettings = DeviceMirroringSettings.getInstance()
-  private val deviceProvisioner
-    @AnyThread get() = project.service<DeviceProvisionerService>().deviceProvisioner
-  private var initialized = false
-  private var contentCreated = false
-  private var mirroringConfirmationDialogShowing = false
-  private var physicalDeviceWatcher: PhysicalDeviceWatcher
-  private val panels = arrayListOf<RunningDevicePanel>()
-  private var selectedPanel: RunningDevicePanel? = null
-
-  /** When the tool window is hidden, the ID of the last selected device, otherwise null. */
-  private var lastSelectedDeviceId: DeviceId? = null
-
-  /** When the tool window is hidden, the state of the UI for all emulators, otherwise empty. */
-  private val savedUiState = hashMapOf<DeviceId, UiState>()
-  private val emulators = hashSetOf<EmulatorController>()
-
-  private var onlineDevices = mapOf<String, ConnectedDeviceNoDnd>()
-  /** Clients for mirrorable devices keyed by serial numbers. */
-  private var deviceClients = mutableMapOf<String, DeviceClient>()
-
-  /** Serial numbers of mirrored devices. */
-  private var mirroredDevices = mutableSetOf<String>()
-  /** Handles of devices excluded from mirroring keyed by serial numbers. */
-  private var devicesExcludedFromMirroring = mutableMapOf<String, DeviceDescription>()
-
-  /** Requested activation levels of devices that recently requested attention keyed by their serial numbers. */
-  private val recentAttentionRequests =
-      CacheBuilder.newBuilder().expireAfterWrite(ATTENTION_REQUEST_EXPIRATION).build<String, ActivationLevel>()
-  /** Requested activation levels of AVDs keyed by their IDs. */
-  private val recentEmulatorLaunches =
-      CacheBuilder.newBuilder().expireAfterWrite(ATTENTION_REQUEST_EXPIRATION).build<String, ActivationLevel>()
-
-  private val alarm = Alarm(Alarm.ThreadToUse.SWING_THREAD, this)
-  @Suppress("UnstableApiUsage")
-  private val toolWindowScope = disposingScope(Dispatchers.EDT)
-
-  private val contentManagerListener = object : ContentManagerListener {
-    override fun selectionChanged(event: ContentManagerEvent) {
-      viewSelectionChanged()
-    }
-
-    override fun contentRemoveQuery(event: ContentManagerEvent) {
-      val panel = event.content.component as? RunningDevicePanel ?: return
-      when (panel) {
-        is EmulatorToolWindowPanel -> panel.emulator.shutdown()
-        is DeviceToolWindowPanel -> panelClosed(panel)
-      }
-
-      panels.remove(panel)
-      savedUiState.remove(panel.id)
-      if (panels.isEmpty()) {
-        if (contentCreated) {
-          createEmptyStatePanel()
-        }
-        hideLiveIndicator()
-      }
-    }
-  }
-
-  private val connectionStateListener = object : ConnectionStateListener {
-    @AnyThread
-    override fun connectionStateChanged(emulator: EmulatorController, connectionState: ConnectionState) {
-      if (connectionState == ConnectionState.DISCONNECTED) {
-        EventQueue.invokeLater { // This is safe because this code doesn't touch PSI or VFS.
-          if (contentCreated && emulators.remove(emulator)) {
-            removeEmulatorPanel(emulator)
-          }
-        }
-      }
-    }
-  }
-
-  private var deviceFrameVisible
-    get() = properties.getBoolean(DEVICE_FRAME_VISIBLE_PROPERTY, DEVICE_FRAME_VISIBLE_DEFAULT)
-    set(value) {
-      properties.setValue(DEVICE_FRAME_VISIBLE_PROPERTY, value, DEVICE_FRAME_VISIBLE_DEFAULT)
-      for (panel in panels) {
-        panel.setDeviceFrameVisible(value)
-      }
-    }
-
-  private var zoomToolbarIsVisible
-    get() = properties.getBoolean(ZOOM_TOOLBAR_VISIBLE_PROPERTY, ZOOM_TOOLBAR_VISIBLE_DEFAULT)
-    set(value) {
-      properties.setValue(ZOOM_TOOLBAR_VISIBLE_PROPERTY, value, ZOOM_TOOLBAR_VISIBLE_DEFAULT)
-      for (panel in panels) {
-        panel.zoomToolbarVisible = value
-      }
-    }
-
-  init {
-    FlightRecorder.initialize(1000)
-    Disposer.register(toolWindow.disposable, this)
-
-    // Lazily initialize content since we can only have one frame.
-    val messageBusConnection = project.messageBus.connect(this)
-    messageBusConnection.subscribe(ToolWindowManagerListener.TOPIC, object : ToolWindowManagerListener {
-
-      override fun stateChanged(toolWindowManager: ToolWindowManager) {
-        val toolWindow = toolWindowManager.getToolWindow(RUNNING_DEVICES_TOOL_WINDOW_ID) ?: return
-
-        toolWindowManager.invokeLater {
-          if (!toolWindow.isDisposed) {
-            if (toolWindow.isVisible) {
-              createContent()
-            }
-            else {
-              destroyContent()
-            }
-          }
-        }
-      }
-    })
-
-    messageBusConnection.subscribe(AvdLaunchListener.TOPIC,
-                                   AvdLaunchListener { avd, commandLine, requestType, project ->
-                                     if (project == toolWindow.project && isEmbeddedEmulator(commandLine)) {
-                                       RunningEmulatorCatalog.getInstance().updateNow()
-                                       EventQueue.invokeLater { // This is safe because this code doesn't touch PSI or VFS.
-                                         showLiveIndicator()
-                                         if (requestType != RequestType.INDIRECT) {
-                                           onEmulatorHeadsUp(avd.name, ActivationLevel.ACTIVATE_TAB)
-                                         }
-                                       }
-                                     }
-                                   })
-
-    messageBusConnection.subscribe(DeviceHeadsUpListener.TOPIC, MyDeviceHeadsUpListener())
-
-    physicalDeviceWatcher = PhysicalDeviceWatcher(this)
-  }
-
-  override fun dispose() {
-    destroyContent()
-  }
-
-  @AnyThread
-  private fun onDeviceHeadsUp(serialNumber: String, activationLevel: ActivationLevel, project: Project) {
-    if (project == toolWindow.project) {
-      UIUtil.invokeLaterIfNeeded {
-        val excludedDevice = devicesExcludedFromMirroring.remove(serialNumber)
-        when {
-          excludedDevice != null -> activateMirroring(serialNumber, excludedDevice.handle, excludedDevice.config, activationLevel)
-          serialNumber in deviceClients -> onPhysicalDeviceHeadsUp(serialNumber, activationLevel)
-          else -> addAttentionRequestAndTriggerEmulatorCatalogUpdate(serialNumber, activationLevel)
-        }
-      }
-    }
-  }
-
-  private fun addAttentionRequestAndTriggerEmulatorCatalogUpdate(serialNumber: String, activationLevel: ActivationLevel) {
-    recentAttentionRequests.put(serialNumber, activationLevel)
-    alarm.addRequest(recentAttentionRequests::cleanUp, ATTENTION_REQUEST_EXPIRATION.toMillis())
-    if (isLocalEmulator(serialNumber)) {
-      val future = RunningEmulatorCatalog.getInstance().updateNow()
-      future.addCallback(EdtExecutorService.getInstance(),
-                         success = { emulators ->
-                           if (emulators != null) {
-                             onEmulatorHeadsUp(serialNumber, emulators, activationLevel)
-                           }
-                         },
-                         failure = {})
-    }
-  }
-
-  private fun onPhysicalDeviceHeadsUp(serialNumber: String, activationLevel: ActivationLevel) {
-    if (toolWindow.isVisible) {
-      val panel = findPanelBySerialNumber(serialNumber)
-      if (panel != null) {
-        selectPanel(panel)
-        toolWindow.activate(activationLevel)
-      }
-    }
-    else {
-      recentAttentionRequests.put(serialNumber, activationLevel)
-      toolWindow.activate(activationLevel)
-    }
-  }
-
-  private fun onEmulatorHeadsUp(serialNumber: String, runningEmulators: Set<EmulatorController>, activationLevel: ActivationLevel) {
-    val emulator = runningEmulators.find { it.emulatorId.serialNumber == serialNumber } ?: return
-    // Ignore standalone emulators.
-    if (emulator.emulatorId.isEmbedded) {
-      onEmulatorHeadsUp(emulator.emulatorId.avdId, activationLevel)
-    }
-  }
-
-  private fun onEmulatorHeadsUp(avdId: String, activationLevel: ActivationLevel) {
-    toolWindow.activate(activationLevel)
-
-    val panel = findPanelByAvdId(avdId)
-    if (panel == null) {
-      RunningEmulatorCatalog.getInstance().updateNow()
-      recentEmulatorLaunches.put(avdId, activationLevel)
-      alarm.addRequest(recentEmulatorLaunches::cleanUp, ATTENTION_REQUEST_EXPIRATION.toMillis())
-    }
-    else {
-      selectPanel(panel)
-    }
-  }
-
-  private fun selectPanel(panel: RunningDevicePanel) {
-    if (selectedPanel != panel) {
-      val contentManager = toolWindow.contentManager
-      val content = contentManager.getContent(panel)
-      contentManager.setSelectedContent(content)
-    }
-  }
-
-  private fun createContent() {
-    if (!initialized) {
-      initialized = true
-
-      val newTabAction = NewTabAction()
-      newTabAction.registerCustomShortcutSet(KeyEvent.VK_T, KeyEvent.CTRL_DOWN_MASK, toolWindow.component)
-      (toolWindow as ToolWindowEx).setTabActions(newTabAction)
-
-      toolWindow.contentManager.addDataProvider { dataId -> getDataFromSelectedPanel(dataId) }
-      val actionGroup = DefaultActionGroup()
-      actionGroup.addAction(ToggleZoomToolbarAction())
-      actionGroup.addAction(ToggleDeviceFrameAction())
-      toolWindow.setAdditionalGearActions(actionGroup)
-    }
-
-    if (contentCreated) {
-      return
-    }
-    contentCreated = true
-
-    val emulatorCatalog = RunningEmulatorCatalog.getInstance()
-    emulatorCatalog.updateNow()
-    emulatorCatalog.addListener(this, EMULATOR_DISCOVERY_INTERVAL_MILLIS)
-    // Ignore standalone emulators.
-    emulators.addAll(emulatorCatalog.emulators.filter { it.emulatorId.isEmbedded })
-
-    // Create the panel for the last selected device before other panels so that it becomes selected.
-    when (val activeDeviceId = lastSelectedDeviceId) {
-      is DeviceId.EmulatorDeviceId -> {
-        val activeEmulator = emulators.find { it.emulatorId == activeDeviceId.emulatorId }
-        if (activeEmulator != null && !activeEmulator.isShuttingDown) {
-          addEmulatorPanel(activeEmulator)
-        }
-      }
-
-      is DeviceId.PhysicalDeviceId -> {
-        val deviceClient = deviceClients[activeDeviceId.serialNumber]
-        if (deviceClient != null) {
-          activateMirroring(activeDeviceId.serialNumber, deviceClient, ActivationLevel.ACTIVATE_TAB)
-        }
-      }
-
-      else -> {}
-    }
-
-    for (emulator in emulators) {
-      if (emulator.emulatorId.serialNumber != lastSelectedDeviceId?.serialNumber && !emulator.isShuttingDown) {
-        addEmulatorPanel(emulator)
-      }
-    }
-
-    for ((serialNumber, deviceClient) in deviceClients) {
-      if (serialNumber != lastSelectedDeviceId?.serialNumber) {
-        activateMirroring(serialNumber, deviceClient, ActivationLevel.CREATE_TAB)
-      }
-    }
-
-    // Not maintained when the tool window is visible.
-    lastSelectedDeviceId = null
-
-    val contentManager = toolWindow.contentManager
-    if (contentManager.contentCount == 0) {
-      createEmptyStatePanel()
-    }
-
-    contentManager.addContentManagerListener(contentManagerListener)
-    viewSelectionChanged()
-  }
-
-  private fun destroyContent() {
-    if (!contentCreated) {
-      return
-    }
-    contentCreated = false
-
-    lastSelectedDeviceId = selectedPanel?.id
-
-    RunningEmulatorCatalog.getInstance().removeListener(this)
-    for (emulator in emulators) {
-      emulator.removeConnectionStateListener(connectionStateListener)
-    }
-    emulators.clear()
-    mirroredDevices.clear()
-    selectedPanel?.let {
-      savedUiState[it.id] = it.destroyContent()
-    }
-    selectedPanel = null
-    panels.clear()
-    recentAttentionRequests.invalidateAll()
-    recentEmulatorLaunches.invalidateAll()
-    val contentManager = toolWindow.contentManager
-    contentManager.removeContentManagerListener(contentManagerListener)
-    contentManager.removeAllContents(true)
-  }
-
-  private fun addEmulatorPanel(emulator: EmulatorController) {
-    emulator.addConnectionStateListener(connectionStateListener)
-    addPanel(EmulatorToolWindowPanel(project, emulator))
-  }
-
-  private fun addPanel(panel: RunningDevicePanel) {
-    FlightRecorder.log { "${TraceUtils.getSimpleId(this)}.addPanel(${TraceUtils.getSimpleId(panel)} ${panel.title})\n" +
-                         TraceUtils.getCurrentStack() }
-    val contentManager = toolWindow.contentManager
-    var placeholderContent: Content? = null
-    if (panels.isEmpty()) {
-      showLiveIndicator()
-      if (!contentManager.isEmpty) {
-        // Remember the placeholder panel content to remove it later. Deleting it now would leave
-        // the tool window empty and cause the contentRemoved method in ToolWindowContentUi to
-        // hide it.
-        placeholderContent = contentManager.getContent(0)
-      }
-    }
-
-    val contentFactory = ContentFactory.getInstance()
-    val content = contentFactory.createContent(panel, shortenTitleText(panel.title), false).apply {
-      putUserData(ToolWindow.SHOW_CONTENT_ICON, true)
-      tabName = panel.title
-      description = panel.description
-      icon = panel.icon
-      popupIcon = panel.icon
-      setPreferredFocusedComponent(panel::preferredFocusableComponent)
-      putUserData(ID_KEY, panel.id)
-    }
-
-    panel.zoomToolbarVisible = zoomToolbarIsVisible
-
-    val index = panels.binarySearch(panel, PANEL_COMPARATOR).inv()
-    if (index < 0) {
-      thisLogger().error("An attempt to add a duplicate panel ${TraceUtils.getSimpleId(panel)} ${panel.title}\n" +
-                         FlightRecorder.getAndClear())
-    }
-
-    if (index >= 0) {
-      panels.add(index, panel)
-      contentManager.addContent(content, index)
-
-      if (selectedPanel != panel) {
-        // Activate the newly added panel if it corresponds to a recently launched or used Emulator.
-        val deviceId = panel.id
-        if (deviceId is DeviceId.EmulatorDeviceId) {
-          val avdId = deviceId.emulatorId.avdId
-          if (recentEmulatorLaunches.getIfPresent(avdId) != null) {
-            recentEmulatorLaunches.invalidate(avdId)
-            contentManager.setSelectedContent(content)
-          }
-        }
-      }
-
-      placeholderContent?.let { contentManager.removeContent(it, true) } // Remove the placeholder panel if it was present.
-    }
-  }
-
-  private fun removeEmulatorPanel(emulator: EmulatorController) {
-    emulator.removeConnectionStateListener(connectionStateListener)
-
-    val panel = findPanelByEmulatorId(emulator.emulatorId) ?: return
-    removePanel(panel)
-  }
-
-  private fun removePhysicalDevicePanel(serialNumber: String) {
-    val panel = findPanelBySerialNumber(serialNumber) as? DeviceToolWindowPanel ?: return
-    removePhysicalDevicePanel(panel)
-  }
-
-  private fun removePhysicalDevicePanel(panel: DeviceToolWindowPanel) {
-    val serialNumber = panel.id.serialNumber
-    deviceClients.remove(serialNumber)?.let {
-      Disposer.dispose(it)
-      updateMirroringHandlesFlow()
-    }
-    mirroredDevices.remove(serialNumber)
-    removePanel(panel)
-  }
-
-  private fun removeAllPhysicalDevicePanels() {
-    panels.filterIsInstance<DeviceToolWindowPanel>().forEach(::removePhysicalDevicePanel)
-  }
-
-  private fun removePanel(panel: RunningDevicePanel) {
-    val contentManager = toolWindow.contentManager
-    val content = contentManager.getContent(panel)
-    if (content != null) {
-      contentManager.removeContent(content, true)
-    }
-  }
-
-  private fun createEmptyStatePanel() {
-    val panel = try {
-      EmptyStatePanel(project, this)
-    }
-    catch (e: IncorrectOperationException) {
-      // This object has been disposed already.
-      return
-    }
-    val contentFactory = ContentFactory.getInstance()
-    val content = contentFactory.createContent(panel, null, false).apply {
-      isCloseable = false
-    }
-    val contentManager = toolWindow.contentManager
-    try {
-      contentManager.addContent(content)
-      contentManager.setSelectedContent(content)
-    }
-    catch (e: IncorrectOperationException) {
-      // Content manager has been disposed already.
-      Disposer.dispose(content)
-    }
-  }
-
-  private fun viewSelectionChanged() {
-    val contentManager = toolWindow.contentManager
-    val content = contentManager.selectedContent
-    val id = content?.getUserData(ID_KEY)
-    if (id != selectedPanel?.id) {
-      selectedPanel?.let { panel ->
-        savedUiState[panel.id] = panel.destroyContent()
-        selectedPanel = null
-      }
-
-      if (id != null) {
-        selectedPanel = findPanelByDeviceId(id)
-        selectedPanel?.createContent(deviceFrameVisible, savedUiState.remove(id))
-        ToggleToolbarAction.setToolbarVisible(toolWindow, PropertiesComponent.getInstance(project), null)
-      }
-    }
-  }
-
-  private fun getDataFromSelectedPanel(dataId: String): Any? {
-    val selectedContent = toolWindow.contentManager.selectedContent ?: return null
-    val panelId = selectedContent.getUserData(ID_KEY) ?: return null
-    val panel = findPanelByDeviceId(panelId) ?: return null
-    return panel.getData(dataId)
-  }
-
-  private fun findPanelByDeviceId(deviceId: DeviceId): RunningDevicePanel? {
-    return panels.firstOrNull { it.id == deviceId }
-  }
-
-  private fun findPanelByEmulatorId(emulatorId: EmulatorId): RunningDevicePanel? {
-    return panels.firstOrNull { it.id is DeviceId.EmulatorDeviceId && it.id.emulatorId == emulatorId }
-  }
-
-  private fun findPanelByAvdId(avdId: String): RunningDevicePanel? {
-    return panels.firstOrNull { it.id is DeviceId.EmulatorDeviceId && it.id.emulatorId.avdId == avdId }
-  }
-
-  private fun findPanelBySerialNumber(serialNumber: String): RunningDevicePanel? {
-    return panels.firstOrNull { it.id.serialNumber == serialNumber }
-  }
-
-  private fun showLiveIndicator() {
-    toolWindow.setIcon(ExecutionUtil.getLiveIndicator(StudioIcons.Shell.ToolWindows.EMULATOR))
-  }
-
-  private fun hideLiveIndicator() {
-    toolWindow.setIcon(StudioIcons.Shell.ToolWindows.EMULATOR)
-  }
-
-  @AnyThread
-  override fun emulatorAdded(emulator: EmulatorController) {
-    if (emulator.emulatorId.isEmbedded) {
-      EventQueue.invokeLater { // This is safe because this code doesn't touch PSI or VFS.
-        if (contentCreated && emulators.add(emulator)) {
-          addEmulatorPanel(emulator)
-        }
-      }
-    }
-  }
-
-  @AnyThread
-  override fun emulatorRemoved(emulator: EmulatorController) {
-    if (emulator.emulatorId.isEmbedded) {
-      EventQueue.invokeLater { // This is safe because this code doesn't touch PSI or VFS.
-        if (contentCreated && emulators.remove(emulator)) {
-          removeEmulatorPanel(emulator)
-        }
-      }
-    }
-  }
-
-  private fun panelClosed(panel: DeviceToolWindowPanel) {
-    val deviceHandle = panel.deviceClient.deviceHandle
-    if (deviceHandle.state.isOnline()) {
-      val deactivationAction = if (isLocalEmulator(panel.deviceSerialNumber)) null else deviceHandle.deactivationAction
-      deactivationAction?.let { CoroutineScope(Dispatchers.IO).launch { it.deactivate() } } ?: stopMirroring(panel.deviceSerialNumber)
-    }
-  }
-
-  private fun deactivateMirroring(serialNumber: String) {
-    if (contentCreated) {
-      val panel = findPanelBySerialNumber(serialNumber) as? DeviceToolWindowPanel ?: return
-      mirroredDevices.remove(serialNumber)
-      removePanel(panel)
-    }
-    else {
-      stopMirroring(serialNumber)
-    }
-  }
-
-  private fun stopMirroring(serialNumber: String) {
-    mirroredDevices.remove(serialNumber)
-    val deviceClient = deviceClients.remove(serialNumber)
-    if (deviceClient != null) {
-      devicesExcludedFromMirroring[serialNumber] =
-          DeviceDescription(deviceClient.deviceName, serialNumber, deviceClient.deviceHandle, deviceClient.deviceConfig)
-      Disposer.dispose(deviceClient)
-      updateMirroringHandlesFlow()
-    }
-  }
-
-  private fun ToolWindow.activate(activationLevel: ActivationLevel) {
-    if (isVisible) {
-      if (activationLevel >= ActivationLevel.ACTIVATE_TAB) {
-        activate(null)
-      }
-    }
-    else {
-      show {
-        if (activationLevel >= ActivationLevel.ACTIVATE_TAB) {
-          activate(null)
-        }
-      }
-    }
-  }
-
-  private fun activateMirroring(deviceDescription: DeviceDescription) {
-    val serialNumber = deviceDescription.serialNumber
-    val deviceClient = getOrCreateDeviceClient(serialNumber, deviceDescription.handle, deviceDescription.config)
-    if (serialNumber !in mirroredDevices) {
-      startMirroringIfConfirmed(serialNumber, deviceClient, ActivationLevel.ACTIVATE_TAB)
-    }
-  }
-
-  private fun activateMirroring(serialNumber: String, device: DeviceHandle, config: DeviceConfiguration, activationLevel: ActivationLevel) {
-    recentAttentionRequests.invalidate(serialNumber)
-    val deviceClient = getOrCreateDeviceClient(serialNumber, device, config)
-    if (contentCreated) {
-      activateMirroring(serialNumber, deviceClient, activationLevel)
-      if (activationLevel >= ActivationLevel.SELECT_TAB) {
-        onPhysicalDeviceHeadsUp(serialNumber, activationLevel)
-      }
-    }
-    else if (activationLevel >= ActivationLevel.SHOW_TOOL_WINDOW) {
-      recentAttentionRequests.put(serialNumber, activationLevel)
-      toolWindow.activate(activationLevel)
-    }
-  }
-
-  private fun activateMirroring(serialNumber: String, deviceClient: DeviceClient, activationLevel: ActivationLevel) {
-    if (serialNumber !in mirroredDevices && serialNumber !in devicesExcludedFromMirroring) {
-      startMirroringIfConfirmed(serialNumber, deviceClient, activationLevel)
-    }
-  }
-
-  private fun startMirroringIfConfirmed(serialNumber: String, deviceClient: DeviceClient, activationLevel: ActivationLevel) {
-    // Reservable devices are assumed to be privacy protected.
-    if (deviceMirroringSettings.confirmationDialogShown || deviceClient.deviceHandle.reservationAction != null) {
-      startMirroring(serialNumber, deviceClient, activationLevel)
-    }
-    else if (!mirroringConfirmationDialogShowing) { // Ignore a recursive call inside the dialog's event loop.
-      mirroringConfirmationDialogShowing = true
-      val title = "About to Start Mirroring of ${deviceClient.deviceName}"
-      val dialogWrapper = MirroringConfirmationDialog(title).createWrapper(project).apply { show() }
-      mirroringConfirmationDialogShowing = false
-      when (dialogWrapper.exitCode) {
-        MirroringConfirmationDialog.ACCEPT_EXIT_CODE -> {
-          deviceMirroringSettings.confirmationDialogShown = true
-          startMirroring(serialNumber, deviceClient, activationLevel)
-        }
-        MirroringConfirmationDialog.REJECT_EXIT_CODE -> stopMirroring(serialNumber)
-        else -> return
-      }
-    }
-  }
-
-  private fun startMirroring(serialNumber: String, deviceClient: DeviceClient, activationLevel: ActivationLevel) {
-    devicesExcludedFromMirroring.remove(serialNumber)
-    if (serialNumber in onlineDevices) {
-      if (contentCreated) {
-        if (mirroredDevices.add(serialNumber)) {
-          updateMirroringHandlesFlow()
-          deviceClient.establishAgentConnectionWithoutVideoStreamAsync() // Start the agent and connect to it proactively.
-          showLiveIndicator()
-          val panel = DeviceToolWindowPanel(project, deviceClient)
-          addPanel(panel)
-          if (activationLevel >= ActivationLevel.SELECT_TAB) {
-            selectPanel(panel, requestFocus = activationLevel >= ActivationLevel.ACTIVATE_TAB)
-          }
-        }
-      }
-      else if (activationLevel >= ActivationLevel.SHOW_TOOL_WINDOW) {
-        recentAttentionRequests.put(serialNumber, activationLevel)
-        toolWindow.activate(activationLevel)
-      }
-    }
-  }
-
-  private fun selectPanel(panel: DeviceToolWindowPanel, requestFocus: Boolean) {
-    val contentManager = toolWindow.contentManager
-    val content = contentManager.getContent(panel) ?: return
-    contentManager.setSelectedContent(content, requestFocus)
-  }
-
-  private fun updateMirroringHandlesFlow() {
-    if (project.isDisposed) {
-      return
-    }
-    val mirroringHandles = mutableMapOf<DeviceHandle, MirroringHandle>()
-    for (device in devicesExcludedFromMirroring.values) {
-      if (device.handle.reservationAction == null) {
-        mirroringHandles[device.handle] = MirroringActivator(device)
-      }
-    }
-    for (client in deviceClients.values) {
-      if (client.deviceHandle.reservationAction == null) {
-        mirroringHandles[client.deviceHandle] = MirroringDeactivator(client.deviceSerialNumber)
-      }
-    }
-    project.service<MirroringManager>().mirroringHandles.value = mirroringHandles
-  }
-
-  @AnyThread
-  private fun deviceConnected(serialNumber: String, device: ConnectedDeviceNoDnd) {
-    val config = DeviceConfiguration(device.state.properties, useTitleAsName = isLocalEmulator(serialNumber))
-    UIUtil.invokeLaterIfNeeded { // This is safe because this code doesn't touch PSI or VFS.
-      deviceConnected(serialNumber, device.handle, config)
-    }
-  }
-
-  private fun deviceConnected(serialNumber: String, deviceHandle: DeviceHandle, config: DeviceConfiguration) {
-    if (serialNumber in onlineDevices && serialNumber !in mirroredDevices) {
-      if (deviceMirroringSettings.activateOnConnection || recentAttentionRequests.getIfPresent(serialNumber) != null) {
-        val activationLevel = if (recentAttentionRequests.getIfPresent(serialNumber) != null) ActivationLevel.SELECT_TAB
-                              else ActivationLevel.SHOW_TOOL_WINDOW
-        activateMirroring(serialNumber, deviceHandle, config, activationLevel)
-      }
-      else {
-        // The device is excluded from mirroring.
-        val deviceDescription = devicesExcludedFromMirroring[serialNumber]
-        if (deviceDescription == null) {
-          devicesExcludedFromMirroring[serialNumber] = DeviceDescription(config.deviceName, serialNumber, deviceHandle, config)
-          updateMirroringHandlesFlow()
-        }
-      }
-    }
-  }
-
-  private fun getOrCreateDeviceClient(serialNumber: String, deviceHandle: DeviceHandle, config: DeviceConfiguration): DeviceClient {
-    val disposable = physicalDeviceWatcher
-    var deviceClient = deviceClients[serialNumber]
-    if (deviceClient == null) {
-      deviceClient = DeviceClient(disposable, serialNumber, deviceHandle, config, config.deviceProperties.abi.toString(), project)
-      deviceClients[serialNumber] = deviceClient
-      updateMirroringHandlesFlow()
-    }
-    return deviceClient
-  }
-
-  private suspend fun showDeviceActionPopup(anchorComponent: Component?, dataContext: DataContext) {
-    val actionGroup = createDeviceActions()
-
-    val popup = JBPopupFactory.getInstance().createActionGroupPopup(
-        null, actionGroup, dataContext, ActionSelectionAid.SPEEDSEARCH, true, null, -1, null,
-        ActionPlaces.getActionGroupPopupPlace(ActionPlaces.TOOLWINDOW_TOOLBAR_BAR))
-
-    if (anchorComponent == null) {
-      popup.showInFocusCenter()
-    }
-    else {
-      popup.showUnderneathOf(anchorComponent)
-    }
-    // Clear initial selection.
-    (popup as? ListPopupImpl)?.list?.clearSelection()
-  }
-
-  private suspend fun createDeviceActions(): DefaultActionGroup {
-    return DefaultActionGroup().apply {
-      val deviceDescriptions = devicesExcludedFromMirroring.values.toTypedArray().sortedBy { it.deviceName }
-      if (deviceDescriptions.isNotEmpty()) {
-        add(Separator("Connected Devices"))
-        for (deviceDescription in deviceDescriptions) {
-          add(StartDeviceMirroringAction(deviceDescription))
-        }
-        add(Separator.getInstance())
-      }
-
-      val remoteDevices = deviceProvisioner.reservedAndStartableDevices()
-      if (remoteDevices.isNotEmpty()) {
-        add(Separator("Remote Devices"))
-        for (device in remoteDevices) {
-          add(StartRemoteDeviceAction(device))
-        }
-        add(Separator.getInstance())
-      }
-
-      val avds = getStartableAvds().sortedBy { it.displayName }
-      if (avds.isNotEmpty()) {
-        add(Separator("Virtual Devices"))
-        for (avd in avds) {
-          add(StartAvdAction(avd, project))
-        }
-        add(Separator.getInstance())
-      }
-
-      add(ActionManager.getInstance().getAction(PairDevicesUsingWiFiAction.ID))
-    }
-  }
-
-  private suspend fun getStartableAvds(): List<AvdInfo> {
-    return withContext(Dispatchers.IO) {
-      val runningAvdFolders = RunningEmulatorCatalog.getInstance().emulators.map { it.emulatorId.avdFolder }.toSet()
-      val avdManager = AvdManagerConnection.getDefaultAvdManagerConnection()
-      avdManager.getAvds(false).filter { it.dataFolderPath !in runningAvdFolders }
-    }
-  }
-
-  private inner class MyDeviceHeadsUpListener : DeviceHeadsUpListener {
-
-    override fun userInvolvementRequired(deviceSerialNumber: String, project: Project) {
-      onDeviceHeadsUp(deviceSerialNumber, ActivationLevel.ACTIVATE_TAB, project)
-    }
-
-    override fun launchingApp(deviceSerialNumber: String, project: Project) {
-      val activate = if (isNonMirrorableLocalEmulator(deviceSerialNumber)) emulatorSettings.activateOnAppLaunch
-                     else deviceMirroringSettings.activateOnAppLaunch
-      if (activate) {
-        onDeviceHeadsUp(deviceSerialNumber, ActivationLevel.SELECT_TAB, project)
-      }
-    }
-
-    override fun launchingTest(deviceSerialNumber: String, project: Project) {
-      val activate = if (isNonMirrorableLocalEmulator(deviceSerialNumber)) emulatorSettings.activateOnTestLaunch
-                     else deviceMirroringSettings.activateOnTestLaunch
-      if (activate) {
-        onDeviceHeadsUp(deviceSerialNumber, ActivationLevel.SELECT_TAB, project)
-      }
-    }
-
-    private fun isNonMirrorableLocalEmulator(deviceSerialNumber: String): Boolean {
-      return isLocalEmulator(deviceSerialNumber) &&
-             deviceSerialNumber !in deviceClients && deviceSerialNumber !in devicesExcludedFromMirroring
-    }
-  }
-
-  private inner class ToggleDeviceFrameAction : ToggleAction("Show Device Frame"), DumbAware {
-
-    override fun update(event: AnActionEvent) {
-      super.update(event)
-      val panel = selectedPanel
-      event.presentation.isEnabledAndVisible = panel is EmulatorToolWindowPanel && panel.emulator.emulatorConfig.skinFolder != null
-    }
-
-    override fun isSelected(event: AnActionEvent): Boolean {
-      return deviceFrameVisible
-    }
-
-    override fun setSelected(event: AnActionEvent, state: Boolean) {
-      deviceFrameVisible = state
-    }
-
-    override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.EDT
-  }
-
-  private inner class ToggleZoomToolbarAction : ToggleAction("Show Zoom Controls"), DumbAware {
-
-    override fun isSelected(event: AnActionEvent): Boolean {
-      return zoomToolbarIsVisible
-    }
-
-    override fun setSelected(event: AnActionEvent, state: Boolean) {
-      zoomToolbarIsVisible = state
-    }
-
-    override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.EDT
-  }
-
-  private inner class PhysicalDeviceWatcher(disposableParent: Disposable) : Disposable {
-    private val coroutineScope: CoroutineScope
-
-    init {
-      Disposer.register(disposableParent, this)
-      val executor = createBoundedApplicationPoolExecutor("EmulatorToolWindowManager.PhysicalDeviceWatcher", 1)
-      coroutineScope = AndroidCoroutineScope(this, executor.asCoroutineDispatcher())
-      coroutineScope.launch {
-        deviceProvisioner.mirrorableDevicesBySerialNumber().collect { newOnlineDevices ->
-          UIUtil.invokeLaterIfNeeded {
-            onlineDevices = newOnlineDevices
-            onlineDevicesChanged()
-          }
-        }
-      }
-    }
-
-    private fun onlineDevicesChanged() {
-      val removedExcluded = devicesExcludedFromMirroring.keys.retainAll(onlineDevices.keys)
-      val removed = deviceClients.keys.minus(onlineDevices.keys)
-      if (contentCreated) {
-        for (device in removed) {
-          removePhysicalDevicePanel(device)
-        }
-      }
-      else {
-        deviceClients.keys.removeAll(removed)
-      }
-      if (removedExcluded || removed.isNotEmpty()) {
-        updateMirroringHandlesFlow()
-      }
-
-      for ((serialNumber, device) in onlineDevices) {
-        if (serialNumber !in mirroredDevices && serialNumber !in devicesExcludedFromMirroring) {
-          coroutineScope.launch {
-            deviceConnected(serialNumber, device)
-          }
-        }
-      }
-
-      if (!contentCreated) {
-        toolWindowScope.launch(Dispatchers.IO) {
-          val embeddedEmulators = RunningEmulatorCatalog.getInstance().updateNow().await().filter { it.emulatorId.isEmbedded }
-          withContext(Dispatchers.EDT) {
-            if (deviceClients.isEmpty() && embeddedEmulators.isEmpty()) {
-              hideLiveIndicator()
-            }
-          }
-        }
-      }
-    }
-
-    override fun dispose() {
-      deviceClients.clear() // The clients have been disposed already.
-      updateMirroringHandlesFlow()
-      removeAllPhysicalDevicePanels()
-    }
-  }
-
-  private inner class NewTabAction : DumbAwareAction("Add Device", "Show a new device", AllIcons.General.Add), DumbAware {
-
-    override fun actionPerformed(event: AnActionEvent) {
-      val component = event.inputEvent?.component
-      val actionComponent = if (component is ActionButtonComponent) component else event.findComponentForAction(this)
-      val dataContext = event.dataContext
-
-      toolWindowScope.launch {
-        showDeviceActionPopup(actionComponent, dataContext)
-      }
-    }
-
-    override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
-  }
-
-  private inner class StartDeviceMirroringAction(
-    private val device: DeviceDescription,
-  ) : DumbAwareAction(device.deviceName, null, device.config.deviceProperties.icon) {
-
-    override fun actionPerformed(event: AnActionEvent) {
-      activateMirroring(device)
-    }
-
-    override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
-  }
-
-  private inner class StartRemoteDeviceAction(
-    private val device: DeviceHandle,
-  ) : DumbAwareAction(device.sourceTemplate?.properties?.composeDeviceName(), null, device.sourceTemplate?.properties?.icon) {
-
-    override fun actionPerformed(event: AnActionEvent) {
-      device.scope.launch { device.activationAction?.activate() }
-    }
-
-    override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
-  }
-
-  private inner class StartAvdAction(
-    private val avd: AvdInfo,
-    private val project: Project,
-  ) : DumbAwareAction(avd.displayName, null, avd.icon) {
-
-    override fun actionPerformed(event: AnActionEvent) {
-      toolWindowScope.launch(Dispatchers.IO) {
-        val avdManager = AvdManagerConnection.getDefaultAvdManagerConnection()
-        try {
-          avdManager.startAvd(project, avd, RequestType.DIRECT_RUNNING_DEVICES).asDeferred().await()
-        }
-        catch (e: Exception) {
-          val message = e.message?.let { if (it.contains(avd.displayName)) it else "Unable to launch ${avd.displayName} - $it"} ?:
-              "Unable to launch ${avd.displayName}"
-          withContext(Dispatchers.EDT) {
-            showErrorDialog(toolWindow.component, message)
-          }
-        }
-      }
-    }
-
-    override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
-  }
-
-  private inner class MirroringActivator(private val device: DeviceDescription) : MirroringHandle {
-
-    override val mirroringState: MirroringState
-      get() = MirroringState.INACTIVE
-
-    override fun toggleMirroring() {
-      activateMirroring(device)
-    }
-
-    override fun toString(): String {
-      return "MirroringActivator for ${device.serialNumber}"
-    }
-  }
-
-  private inner class MirroringDeactivator(private val serialNumber: String) : MirroringHandle {
-
-    override val mirroringState: MirroringState
-      get() = MirroringState.ACTIVE
-
-    override fun toggleMirroring() {
-      deactivateMirroring(serialNumber)
-    }
-
-    override fun toString(): String {
-      return "MirroringDeactivator for $serialNumber"
-    }
-  }
-
-  private class DeviceDescription(val deviceName: String, val serialNumber: String, val handle: DeviceHandle,
-                                  val config: DeviceConfiguration)
-
-  private enum class ActivationLevel {
-    /** Create tab, but don't select it and don't show the tool window if hidden. */
-    CREATE_TAB,
-    /** Create tab and show the tool window if hidden. */
-    SHOW_TOOL_WINDOW,
-    /** Create tab, show the tool window if hidden and select the new tab. */
-    SELECT_TAB,
-    /** Create tab, show the tool window if hidden, select the new tab and focus on it. */
-    ACTIVATE_TAB,
-  }
-}
-
-private class ConnectedDeviceNoDnd(val handle: DeviceHandle, val state: DeviceState.Connected)
-
-private fun DeviceProvisioner.mirrorableDevicesBySerialNumber(): Flow<Map<String, ConnectedDeviceNoDnd>> {
-  return ConnectedDeviceNoDnds().map { connectedDevices ->
-    connectedDevices.filter { it.state.isMirrorable() }.associateBy { it.state.serialNumber }
-  }
-}
-
-private fun DeviceProvisioner.ConnectedDeviceNoDnds(): Flow<List<ConnectedDeviceNoDnd>> {
-  return mapStateNotNull { handle, state -> (state as? DeviceState.Connected)?.let { ConnectedDeviceNoDnd(handle, it) } }
-}
-
-private fun DeviceProvisioner.reservedAndStartableDevices(): List<DeviceHandle> {
-  return devices.value.filter {
-    it.state.reservation?.state == ReservationState.ACTIVE && it.activationAction?.presentation?.value?.enabled == true
-  }
-}
-
-private suspend fun DeviceState.Connected.isMirrorable(): Boolean {
-  if (!isOnline()) {
-    return false
-  }
-
-  val deviceSerialNumber = serialNumber
-  when {
-    isLocalEmulator(deviceSerialNumber) -> { // Local virtual device.
-      if (!StudioFlags.DEVICE_MIRRORING_STANDALONE_EMULATORS.get()) {
-        return false
-      }
-      val emulators = RunningEmulatorCatalog.getInstance().updateNow().suspendingGet()
-      val emulator = emulators.find { "emulator-${it.emulatorId.serialPort}" == deviceSerialNumber }
-      if (emulator == null || emulator.emulatorId.isEmbedded) {
-        return false
-      }
-    }
-    properties.isVirtual == true -> { // Remote virtual device.
-      if (!StudioFlags.DEVICE_MIRRORING_REMOTE_EMULATORS.get()) {
-        return false
-      }
-    }
-  }
-
-  val apiLevel = properties.androidVersion?.apiLevel ?: SdkVersionInfo.HIGHEST_KNOWN_STABLE_API
-  // Mirroring is supported for API >= 26. Wear OS devices with API < 30 don't support VP8/VP9 video encoders.
-  return apiLevel >= 26 && (properties.deviceType != DeviceType.WEAR || apiLevel >= 30) && properties.abi != null
-}
-
-private val DeviceState.Connected.serialNumber: String
-    get() = connectedDevice.serialNumber
-
-private fun isLocalEmulator(deviceSerialNumber: String) =
-    deviceSerialNumber.startsWith("emulator-")
-
-private fun isEmbeddedEmulator(commandLine: GeneralCommandLine) =
-    commandLine.parametersList.parameters.contains("-qt-hide-window")
-
-private fun shortenTitleText(title: String): String =
-  StringUtil.shortenTextWithEllipsis(title, 25, 6)
diff --git a/streaming/src/com/android/tools/idea/streaming/core/StreamingUtils.kt b/streaming/src/com/android/tools/idea/streaming/core/StreamingUtils.kt
index 68921e7..330b630 100644
--- a/streaming/src/com/android/tools/idea/streaming/core/StreamingUtils.kt
+++ b/streaming/src/com/android/tools/idea/streaming/core/StreamingUtils.kt
@@ -149,20 +149,6 @@
   }
 
 /**
- * If the device is connected by WiFi, extracts the device's own serial number from the serial
- * number returned by ADB, otherwise returns the original serial number. For example, converts
- * "adb-3211105H802MQD-wG1oxA._adb-tls-connect._tcp." to "3211105H802MQD".
- */
-fun normalizeDeviceSerialNumber(serialNumber: String) : String {
-  val prefix = "adb-"
-  if (serialNumber.startsWith(prefix)) {
-    val end = serialNumber.indexOf('-', prefix.length)
-    return if (end > prefix.length) serialNumber.substring(prefix.length, end) else serialNumber.substring(prefix.length)
-  }
-  return serialNumber
-}
-
-/**
  * Returns this integer scaled and rounded to the closest integer.
  *
  * @param scale the scale factor
diff --git a/streaming/src/com/android/tools/idea/streaming/device/DeviceController.kt b/streaming/src/com/android/tools/idea/streaming/device/DeviceController.kt
index c050c01..ceda98a 100644
--- a/streaming/src/com/android/tools/idea/streaming/device/DeviceController.kt
+++ b/streaming/src/com/android/tools/idea/streaming/device/DeviceController.kt
@@ -241,12 +241,12 @@
    * ```
    */
   private fun parseDeviceStates(text: String): List<FoldingState> {
-    val regex = Regex("DeviceState\\{identifier=(?<id>\\d+), name='(?<name>\\w+)', app_accessible=(?<accessible>true|false)}")
+    val regex = Regex("DeviceState\\{identifier=(?<id>\\d+), name='(?<name>\\w+)'(, app_accessible=(?<accessible>true|false))?}")
     return regex.findAll(text).map {
       val groups = it.groups
       val id = groups["id"]?.value?.toInt() ?: throw IllegalArgumentException()
       val name = groups["name"]?.value ?: throw IllegalArgumentException()
-      val accessible = groups["accessible"]?.value == "true"
+      val accessible = groups["accessible"]?.value != "false"
       FoldingState(id, deviceStateNameToFoldingStateName(name), accessible)
     }.toList()
   }
diff --git a/streaming/src/com/android/tools/idea/streaming/device/DeviceToolWindowPanel.kt b/streaming/src/com/android/tools/idea/streaming/device/DeviceToolWindowPanel.kt
index 9bcfc86..e818d47 100644
--- a/streaming/src/com/android/tools/idea/streaming/device/DeviceToolWindowPanel.kt
+++ b/streaming/src/com/android/tools/idea/streaming/device/DeviceToolWindowPanel.kt
@@ -28,8 +28,10 @@
 import com.android.tools.idea.streaming.device.screenshot.DeviceScreenshotOptions
 import com.android.tools.idea.ui.screenrecording.ScreenRecorderAction
 import com.android.tools.idea.ui.screenshot.ScreenshotAction
+import com.android.utils.TraceUtils
 import com.intellij.execution.runners.ExecutionUtil
 import com.intellij.openapi.Disposable
+import com.intellij.openapi.diagnostic.thisLogger
 import com.intellij.openapi.project.Project
 import com.intellij.openapi.util.Disposer
 import com.intellij.ui.JBColor
@@ -41,6 +43,7 @@
  * Provides view of one physical device in the Running Devices tool window.
  */
 internal class DeviceToolWindowPanel(
+  disposableParent: Disposable,
   private val project: Project,
   val deviceClient: DeviceClient,
 ) : RunningDevicePanel(DeviceId.ofPhysicalDevice(deviceClient.deviceSerialNumber), DEVICE_MAIN_TOOLBAR_ID, STREAMING_SECONDARY_TOOLBAR_ID) {
@@ -97,6 +100,10 @@
     }
   }
 
+  init {
+    Disposer.register(disposableParent, this)
+  }
+
   override fun setDeviceFrameVisible(visible: Boolean) {
     // Showing device frame is not supported for physical devices.
   }
@@ -105,7 +112,13 @@
    * Populates the device panel with content.
    */
   override fun createContent(deviceFrameVisible: Boolean, savedUiState: UiState?) {
+    if (contentDisposable != null) {
+      thisLogger().error(IllegalStateException("${title}: content already exists"))
+      return
+    }
+
     val disposable = Disposer.newDisposable()
+    Disposer.register(this, disposable)
     contentDisposable = disposable
 
     val uiState = savedUiState as DeviceUiState? ?: DeviceUiState()
diff --git a/streaming/src/com/android/tools/idea/streaming/device/dialogs/MirroringConfirmationDialog.kt b/streaming/src/com/android/tools/idea/streaming/device/dialogs/MirroringConfirmationDialog.kt
index 7055d163..b20f8f0b 100644
--- a/streaming/src/com/android/tools/idea/streaming/device/dialogs/MirroringConfirmationDialog.kt
+++ b/streaming/src/com/android/tools/idea/streaming/device/dialogs/MirroringConfirmationDialog.kt
@@ -69,7 +69,7 @@
           CloseDialogAction(dialogPanel, "Acknowledge", ACCEPT_EXIT_CODE, isDefault = true),
           CloseDialogAction(dialogPanel, "Cancel", REJECT_EXIT_CODE)
         )
-      })
+      }).apply { pack() }
   }
 
   companion object {
diff --git a/streaming/src/com/android/tools/idea/streaming/emulator/EmulatorToolWindowPanel.kt b/streaming/src/com/android/tools/idea/streaming/emulator/EmulatorToolWindowPanel.kt
index be210be..d453242 100644
--- a/streaming/src/com/android/tools/idea/streaming/emulator/EmulatorToolWindowPanel.kt
+++ b/streaming/src/com/android/tools/idea/streaming/emulator/EmulatorToolWindowPanel.kt
@@ -54,6 +54,7 @@
 import com.intellij.openapi.components.State
 import com.intellij.openapi.components.Storage
 import com.intellij.openapi.diagnostic.Logger
+import com.intellij.openapi.diagnostic.thisLogger
 import com.intellij.openapi.project.Project
 import com.intellij.openapi.ui.DialogWrapper
 import com.intellij.openapi.util.Disposer
@@ -78,6 +79,7 @@
  * Provides view of one AVD in the Running Devices tool window.
  */
 internal class EmulatorToolWindowPanel(
+  disposableParent: Disposable,
   private val project: Project,
   val emulator: EmulatorController
 ) : RunningDevicePanel(DeviceId.ofEmulator(emulator.emulatorId), EMULATOR_MAIN_TOOLBAR_ID, STREAMING_SECONDARY_TOOLBAR_ID),
@@ -147,6 +149,10 @@
   @get:TestOnly
   var lastUiState: EmulatorUiState? = null
 
+  init {
+    Disposer.register(disposableParent, this)
+  }
+
   override fun setDeviceFrameVisible(visible: Boolean) {
     primaryDisplayView?.deviceFrameVisible = visible
   }
@@ -166,8 +172,14 @@
    * Populates the emulator panel with content.
    */
   override fun createContent(deviceFrameVisible: Boolean, savedUiState: UiState?) {
+    if (contentDisposable != null) {
+      thisLogger().error(IllegalStateException("${title}: content already exists"))
+      return
+    }
+
     lastUiState = null
     val disposable = Disposer.newDisposable()
+    Disposer.register(this, disposable)
     contentDisposable = disposable
 
     clipboardSynchronizer = EmulatorClipboardSynchronizer(emulator, disposable)
diff --git a/streaming/testSrc/com/android/tools/idea/streaming/core/DeviceFileDropHandlerTest.kt b/streaming/testSrc/com/android/tools/idea/streaming/core/DeviceFileDropHandlerTest.kt
index fd30906..f2ef68f 100644
--- a/streaming/testSrc/com/android/tools/idea/streaming/core/DeviceFileDropHandlerTest.kt
+++ b/streaming/testSrc/com/android/tools/idea/streaming/core/DeviceFileDropHandlerTest.kt
@@ -166,11 +166,8 @@
     val emulators = catalog.updateNow().get()
     assertThat(emulators).hasSize(1)
     val emulatorController = emulators.first()
-    val panel = EmulatorToolWindowPanel(projectRule.project, emulatorController)
+    val panel = EmulatorToolWindowPanel(testRootDisposable, projectRule.project, emulatorController)
     Disposer.register(testRootDisposable) {
-      if (panel.primaryEmulatorView != null) {
-        panel.destroyContent()
-      }
       emulator.stop()
     }
     panel.zoomToolbarVisible = true
diff --git a/streaming/testSrc/com/android/tools/idea/streaming/core/StreamingToolWindowManagerTest.kt b/streaming/testSrc/com/android/tools/idea/streaming/core/StreamingToolWindowManagerTest.kt
index f0cd29c..3090c46 100644
--- a/streaming/testSrc/com/android/tools/idea/streaming/core/StreamingToolWindowManagerTest.kt
+++ b/streaming/testSrc/com/android/tools/idea/streaming/core/StreamingToolWindowManagerTest.kt
@@ -91,6 +91,7 @@
 import com.intellij.util.ui.UIUtil.dispatchAllInvocationEvents
 import icons.StudioIcons
 import kotlinx.coroutines.runBlocking
+import org.jetbrains.android.UndisposedAndroidObjectsCheckerRule
 import org.junit.After
 import org.junit.Before
 import org.junit.Rule
@@ -299,7 +300,6 @@
 
   @Test
   fun testZoomStatePreservation() {
-
     val tempFolder = emulatorRule.avdRoot
     val emulator = emulatorRule.newEmulator(FakeEmulator.createPhoneAvd(tempFolder))
 
diff --git a/streaming/testSrc/com/android/tools/idea/streaming/device/DeviceToolWindowPanelTest.kt b/streaming/testSrc/com/android/tools/idea/streaming/device/DeviceToolWindowPanelTest.kt
index cd69fba..7e4f8a8 100644
--- a/streaming/testSrc/com/android/tools/idea/streaming/device/DeviceToolWindowPanelTest.kt
+++ b/streaming/testSrc/com/android/tools/idea/streaming/device/DeviceToolWindowPanelTest.kt
@@ -337,15 +337,7 @@
   private fun createToolWindowPanel(): DeviceToolWindowPanel {
     val deviceClient =
         DeviceClient(testRootDisposable, device.serialNumber, device.handle, device.configuration, device.deviceState.cpuAbi, project)
-    val panel = DeviceToolWindowPanel(project, deviceClient)
-    // The panel has to be destroyed before disposal of DeviceClient.
-    val disposable = Disposer.newDisposable()
-    Disposer.register(testRootDisposable, disposable)
-    Disposer.register(disposable) {
-      if (panel.deviceView != null) {
-        panel.destroyContent()
-      }
-    }
+    val panel = DeviceToolWindowPanel(testRootDisposable, project, deviceClient)
     panel.size = Dimension(280, 300)
     panel.zoomToolbarVisible = true
     return panel
diff --git a/streaming/testSrc/com/android/tools/idea/streaming/device/DeviceViewTest.kt b/streaming/testSrc/com/android/tools/idea/streaming/device/DeviceViewTest.kt
index b78abc8..0d31f51 100644
--- a/streaming/testSrc/com/android/tools/idea/streaming/device/DeviceViewTest.kt
+++ b/streaming/testSrc/com/android/tools/idea/streaming/device/DeviceViewTest.kt
@@ -681,6 +681,7 @@
       "\\s*build_api_level_full: \"30\"\n" +
       "\\s*mdns_connection_type: MDNS_NONE\n" +
       "\\s*device_provisioner_id: \"FakeDevicePlugin\"\n" +
+      "\\s*connection_id: \"fakeConnectionId\"\n" +
       "}\n" +
       "ide_brand: ANDROID_STUDIO\n" +
       "idea_is_internal: \\w+\n" +
@@ -713,6 +714,7 @@
       "\\s*build_api_level_full: \"30\"\n" +
       "\\s*mdns_connection_type: MDNS_NONE\n" +
       "\\s*device_provisioner_id: \"FakeDevicePlugin\"\n" +
+      "\\s*connection_id: \"fakeConnectionId\"\n" +
       "}\n" +
       "ide_brand: ANDROID_STUDIO\n" +
       "idea_is_internal: \\w+\n" +
@@ -768,6 +770,7 @@
       "\\s*build_api_level_full: \"30\"\n" +
       "\\s*mdns_connection_type: MDNS_NONE\n" +
       "\\s*device_provisioner_id: \"FakeDevicePlugin\"\n" +
+      "\\s*connection_id: \"fakeConnectionId\"\n" +
       "}\n" +
       "ide_brand: ANDROID_STUDIO\n" +
       "idea_is_internal: \\w+\n" +
@@ -821,6 +824,7 @@
       "\\s*build_api_level_full: \"30\"\n" +
       "\\s*mdns_connection_type: MDNS_NONE\n" +
       "\\s*device_provisioner_id: \"FakeDevicePlugin\"\n" +
+      "\\s*connection_id: \"fakeConnectionId\"\n" +
       "}\n" +
       "ide_brand: ANDROID_STUDIO\n" +
       "idea_is_internal: \\w+\n" +
diff --git a/streaming/testSrc/com/android/tools/idea/streaming/emulator/EmulatorToolWindowPanelTest.kt b/streaming/testSrc/com/android/tools/idea/streaming/emulator/EmulatorToolWindowPanelTest.kt
index d8c4f47..7cf53c4 100644
--- a/streaming/testSrc/com/android/tools/idea/streaming/emulator/EmulatorToolWindowPanelTest.kt
+++ b/streaming/testSrc/com/android/tools/idea/streaming/emulator/EmulatorToolWindowPanelTest.kt
@@ -813,13 +813,7 @@
     val emulators = catalog.updateNow().get()
     assertThat(emulators).hasSize(1)
     val emulatorController = emulators.first()
-    val panel = EmulatorToolWindowPanel(projectRule.project, emulatorController)
-    Disposer.register(testRootDisposable) {
-      if (panel.primaryEmulatorView != null) {
-        panel.destroyContent()
-      }
-      emulator.stop()
-    }
+    val panel = EmulatorToolWindowPanel(testRootDisposable, projectRule.project, emulatorController)
     panel.zoomToolbarVisible = true
     waitForCondition(5, SECONDS) { emulatorController.connectionState == EmulatorController.ConnectionState.CONNECTED }
     return panel
diff --git a/streaming/testUtil/com/android/tools/idea/streaming/device/FakeScreenSharingAgent.kt b/streaming/testUtil/com/android/tools/idea/streaming/device/FakeScreenSharingAgent.kt
index 25cb4b7..f41b980 100644
--- a/streaming/testUtil/com/android/tools/idea/streaming/device/FakeScreenSharingAgent.kt
+++ b/streaming/testUtil/com/android/tools/idea/streaming/device/FakeScreenSharingAgent.kt
@@ -756,7 +756,7 @@
           val supportedStates = """
               Supported states: [
                 DeviceState{identifier=0, name='CLOSE', app_accessible=true},
-                DeviceState{identifier=1, name='TENT', app_accessible=true},
+                DeviceState{identifier=1, name='TENT'},
                 DeviceState{identifier=2, name='HALF_FOLDED', app_accessible=true},
                 DeviceState{identifier=3, name='OPEN', app_accessible=true},
                 DeviceState{identifier=4, name='REAR_DISPLAY_STATE', app_accessible=true},
diff --git a/streaming/testUtil/com/android/tools/idea/streaming/device/FakeScreenSharingAgentRule.kt b/streaming/testUtil/com/android/tools/idea/streaming/device/FakeScreenSharingAgentRule.kt
index d395f7a..68636e4 100644
--- a/streaming/testUtil/com/android/tools/idea/streaming/device/FakeScreenSharingAgentRule.kt
+++ b/streaming/testUtil/com/android/tools/idea/streaming/device/FakeScreenSharingAgentRule.kt
@@ -188,7 +188,7 @@
     private fun createDeviceProperties(): DeviceProperties {
       return DeviceProperties.build {
         readCommonProperties(deviceState.properties)
-        populateDeviceInfoProto("FakeDevicePlugin", serialNumber, deviceState.properties)
+        populateDeviceInfoProto("FakeDevicePlugin", serialNumber, deviceState.properties, "fakeConnectionId")
         readAdbSerialNumber(serialNumber)
         icon = when (deviceType) {
           DeviceType.WEAR -> StudioIcons.DeviceExplorer.PHYSICAL_DEVICE_WEAR
diff --git a/studio/BUILD b/studio/BUILD
index 7f7678b..01a57f7 100644
--- a/studio/BUILD
+++ b/studio/BUILD
@@ -173,6 +173,7 @@
             "//tools/adt/idea/app-inspection/inspectors/backgroundtask/view:app-inspection.inspectors.backgroundtask.view",
             "//tools/adt/idea/app-quality-insights/api:intellij.android.app-quality-insights.api",
             "//tools/adt/idea/app-quality-insights/ide:intellij.android.app-quality-insights.ide",
+            "//tools/adt/idea/app-quality-insights/ide/gradle:intellij.android.app-quality-insights.ide.gradle",
             "//tools/adt/idea/app-quality-insights/ui:intellij.android.app-quality-insights.ui",
             "//tools/adt/idea/app-quality-insights/play-vitals/model:intellij.android.app-quality-insights.play-vitals.model",
             "//tools/adt/idea/app-quality-insights/play-vitals/ide:intellij.android.app-quality-insights.play-vitals.ide",
diff --git a/studio/version.bzl b/studio/version.bzl
index 86abda5..018bab1 100644
--- a/studio/version.bzl
+++ b/studio/version.bzl
@@ -3,5 +3,5 @@
 
 STUDIO_CODENAME = "Iguana"
 STUDIO_VERSION = "Canary"
-STUDIO_MICRO_PATCH = "1.4"
-STUDIO_RELEASE_NUMBER = 4
+STUDIO_MICRO_PATCH = "1.5"
+STUDIO_RELEASE_NUMBER = 5
diff --git a/whats-new-assistant/testSrc/com.android.tools.idea.whatsnew.assistant/WhatsNewBundleCreatorTest.kt b/whats-new-assistant/testSrc/com.android.tools.idea.whatsnew.assistant/WhatsNewBundleCreatorTest.kt
index 541cb77..1a98a2f 100644
--- a/whats-new-assistant/testSrc/com.android.tools.idea.whatsnew.assistant/WhatsNewBundleCreatorTest.kt
+++ b/whats-new-assistant/testSrc/com.android.tools.idea.whatsnew.assistant/WhatsNewBundleCreatorTest.kt
@@ -19,39 +19,48 @@
 import com.android.testutils.MockitoKt.whenever
 import com.android.testutils.TestUtils
 import com.android.tools.idea.assistant.AssistantBundleCreator
+import com.android.tools.idea.testing.AndroidProjectRule
 import com.intellij.openapi.project.ProjectManager
 import com.intellij.openapi.util.io.FileUtil
-import org.jetbrains.android.AndroidTestCase
-import org.junit.Test
-import org.mockito.ArgumentMatchers
-import org.mockito.Mockito.mock
-import org.mockito.stubbing.Answer
-import java.io.File
-import java.io.InputStream
 import java.net.URL
 import java.nio.file.Path
 import java.util.concurrent.TimeoutException
+import org.jetbrains.android.AndroidTestBase
+import org.junit.Assert.*
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.ArgumentMatchers
+import org.mockito.Mockito.mock
 
-class WhatsNewBundleCreatorTest : AndroidTestCase() {
+@RunWith(JUnit4::class)
+class WhatsNewBundleCreatorTest {
+  @get:Rule var projectRule = AndroidProjectRule.inMemory()
+
   private lateinit var mockUrlProvider: WhatsNewURLProvider
   private lateinit var localPath: Path
 
   private val studioRevision = Revision.parseRevision("3.3.0")
 
-  override fun setUp() {
-    super.setUp()
-
+  @Before
+  fun setUp() {
     // Mock url provider to simulate webserver and also class resource file
     mockUrlProvider = mock(WhatsNewURLProvider::class.java)
 
-    val serverFile = File(myFixture.testDataPath).resolve("whatsnewassistant/server-3.3.0.xml")
-    whenever(mockUrlProvider.getWebConfig(ArgumentMatchers.anyString())).thenReturn(URL("file:" + serverFile.path))
+    val serverFile = getTestDataPath().resolve("whatsnewassistant/server-3.3.0.xml")
+    whenever(mockUrlProvider.getWebConfig(ArgumentMatchers.anyString()))
+      .thenReturn(URL("file:$serverFile"))
 
-    val resourceFile = File(myFixture.testDataPath).resolve("whatsnewassistant/defaultresource-3.3.0.xml")
-    whenever(mockUrlProvider.getResourceFileAsStream(ArgumentMatchers.any(), ArgumentMatchers.anyString()))
-      .thenAnswer(Answer<InputStream> {
-        URL("file:" + resourceFile.path).openStream()
-      })
+    val resourceFile = getTestDataPath().resolve("whatsnewassistant/defaultresource-3.3.0.xml")
+    whenever(
+        mockUrlProvider.getResourceFileAsStream(
+          ArgumentMatchers.any(),
+          ArgumentMatchers.anyString()
+        )
+      )
+      .thenAnswer { URL("file:$resourceFile").openStream() }
 
     val tmpDir = TestUtils.createTempDirDeletedOnExit()
     localPath = tmpDir.resolve("local-3.3.0.xml")
@@ -59,7 +68,7 @@
   }
 
   @Test
-  fun testEnabled() {
+  fun enabled() {
     val mockBundler = mock(AssistantBundleCreator::class.java)
     whenever(mockBundler.bundleId).thenReturn(WhatsNewBundleCreator.BUNDLE_ID)
     whenever(mockBundler.config).thenReturn(URL("file:test.file"))
@@ -70,9 +79,7 @@
     WhatsNewBundleCreator.setTestCreator(null)
   }
 
-  /**
-   * Test with a file that exists, simulating good internet connection
-   */
+  /** Test with a file that exists, simulating good internet connection */
   @Test
   fun testDownloadSuccess() {
     // Expected bundle file is server-3.3.0.xml
@@ -86,13 +93,13 @@
   }
 
   /**
-   * Test with a file that does not exist, simulating no internet, and also
-   * without an already downloaded/unpacked file, so the bundle file will
-   * be from the class resource
+   * Test with a file that does not exist, simulating no internet, and also without an already
+   * downloaded/unpacked file, so the bundle file will be from the class resource
    */
   @Test
-  fun testDownloadDoesNotExist() {
-    whenever(mockUrlProvider.getWebConfig(ArgumentMatchers.anyString())).thenReturn(URL("file:server-doesnotexist-3.3.0.xml"))
+  fun downloadDoesNotExist() {
+    whenever(mockUrlProvider.getWebConfig(ArgumentMatchers.anyString()))
+      .thenReturn(URL("file:server-doesnotexist-3.3.0.xml"))
 
     // Expected bundle file is defaultresource-3.3.0.xml
     val bundleCreator = WhatsNewBundleCreator(mockUrlProvider, studioRevision)
@@ -105,11 +112,11 @@
   }
 
   /**
-   * First test a downloaded file, then with one that doesn't exist, simulating
-   * losing internet connection after having it earlier
+   * First test a downloaded file, then with one that doesn't exist, simulating losing internet
+   * connection after having it earlier
    */
   @Test
-  fun testDownloadDoesNotExistWithExistingDownloaded() {
+  fun downloadDoesNotExistWithExistingDownloaded() {
     // First expected bundle file is server-3.3.0.xml
     val bundleCreator = WhatsNewBundleCreator(mockUrlProvider, studioRevision)
     val bundle = bundleCreator.getBundle(ProjectManager.getInstance().defaultProject)
@@ -120,7 +127,8 @@
     }
 
     // Change server file to one that doesn't exist, meaning no connection
-    whenever(mockUrlProvider.getWebConfig(ArgumentMatchers.anyString())).thenReturn(URL("file:server-doesnotexist-3.3.0.xml"))
+    whenever(mockUrlProvider.getWebConfig(ArgumentMatchers.anyString()))
+      .thenReturn(URL("file:server-doesnotexist-3.3.0.xml"))
     // Expected bundle file is still server-3.3.0.xml because it was downloaded on the first fetch
     val newBundle = bundleCreator.getBundle(ProjectManager.getInstance().defaultProject)
     assertNotNull(newBundle)
@@ -130,14 +138,12 @@
     }
   }
 
-  /**
-   * Test that disabling the download flag will not fetch from "server"
-   */
+  /** Test that disabling the download flag will not fetch from "server" */
   @Test
-  fun testDownloadFlagDisabled() {
+  fun downloadFlagDisabled() {
     // Expected bundle file is defaultresource-3.3.0.xml
-    val bundleCreator = WhatsNewBundleCreator(mockUrlProvider, studioRevision,
-                                              WhatsNewConnectionOpener(), false)
+    val bundleCreator =
+      WhatsNewBundleCreator(mockUrlProvider, studioRevision, WhatsNewConnectionOpener(), false)
     val bundle = bundleCreator.getBundle(ProjectManager.getInstance().defaultProject)
     assertNotNull(bundle)
     if (bundle != null) {
@@ -147,12 +153,16 @@
   }
 
   @Test
-  fun testDownloadTimeout() {
+  fun downloadTimeout() {
     val mockConnectionOpener = mock(WhatsNewConnectionOpener::class.java)
-    whenever(mockConnectionOpener.openConnection(ArgumentMatchers.isNotNull<URL>(), ArgumentMatchers.anyInt())).thenThrow(TimeoutException())
+    whenever(
+        mockConnectionOpener.openConnection(ArgumentMatchers.isNotNull(), ArgumentMatchers.anyInt())
+      )
+      .thenThrow(TimeoutException())
 
     // Expected bundle file is defaultresource-3.3.0.xml
-    val bundleCreator = WhatsNewBundleCreator(mockUrlProvider, studioRevision, mockConnectionOpener, true)
+    val bundleCreator =
+      WhatsNewBundleCreator(mockUrlProvider, studioRevision, mockConnectionOpener, true)
     val bundle = bundleCreator.getBundle(ProjectManager.getInstance().defaultProject)
     assertNotNull(bundle)
     if (bundle != null) {
@@ -161,16 +171,14 @@
     }
   }
 
-  /**
-   * Test that parseBundle correctly deletes local cache and retries once when the parse fails
-   */
+  /** Test that parseBundle correctly deletes local cache and retries once when the parse fails */
   @Test
-  fun testParseBundleRetry() {
+  fun parseBundleRetry() {
     // Trying to read empty xml will cause parser to throw exception...
-    val emptyFile = File(myFixture.testDataPath).resolve("whatsnewassistant/empty.xml")
-    FileUtil.copy(emptyFile, localPath.toFile())
-    val bundleCreator = WhatsNewBundleCreator(mockUrlProvider, studioRevision,
-                                              WhatsNewConnectionOpener(), false)
+    val emptyFile = getTestDataPath().resolve("whatsnewassistant/empty.xml")
+    FileUtil.copy(emptyFile.toFile(), localPath.toFile())
+    val bundleCreator =
+      WhatsNewBundleCreator(mockUrlProvider, studioRevision, WhatsNewConnectionOpener(), false)
 
     // So parseBundle should delete the empty file and retry, resulting in defaultresource-3.3.0.xml
     val bundle = bundleCreator.getBundle(ProjectManager.getInstance().defaultProject)
@@ -182,14 +190,15 @@
   }
 
   /**
-   * Test that WNA bundle creator correctly identifies when an updated config has
-   * a higher version field than the previous existing config
+   * Test that WNA bundle creator correctly identifies when an updated config has a higher version
+   * field than the previous existing config
    */
   @Test
-  fun testNewConfigVersion() {
-    // Since download is disabled, the current file will be defaultresource-3.3.0.xml, version "3.3.0"
-    val bundleCreator = WhatsNewBundleCreator(mockUrlProvider, studioRevision,
-                                              WhatsNewConnectionOpener(), false)
+  fun newConfigVersion() {
+    // Since download is disabled, the current file will be defaultresource-3.3.0.xml, version
+    // "3.3.0"
+    val bundleCreator =
+      WhatsNewBundleCreator(mockUrlProvider, studioRevision, WhatsNewConnectionOpener(), false)
 
     // Disabled download means last seen version is from default resource, so "3.3.0" = "3.3.0"
     assertFalse(bundleCreator.isNewConfigVersion)
@@ -201,15 +210,16 @@
     // And running once again should be false because last seen is now "3.3.10"
     assertFalse(bundleCreator.isNewConfigVersion)
 
-    // Disabling download again should use local-3.3.0.xml, cached from the download, version "3.3.10"
+    // Disabling download again should use local-3.3.0.xml, cached from the download, version
+    // "3.3.10"
     bundleCreator.setAllowDownload(false)
     assertFalse(bundleCreator.isNewConfigVersion)
   }
 
   @Test
-  fun testHasResourceConfig() {
-    val bundleCreator = WhatsNewBundleCreator(mockUrlProvider, studioRevision,
-                                              WhatsNewConnectionOpener(), false)
+  fun hasResourceConfig() {
+    val bundleCreator =
+      WhatsNewBundleCreator(mockUrlProvider, studioRevision, WhatsNewConnectionOpener(), false)
 
     // Both the resource file and the Studio version are 3.3.0
     assertTrue(bundleCreator.hasResourceConfig())
@@ -222,4 +232,8 @@
     bundleCreator.setStudioRevision(Revision.parseRevision("0.0.0rc0"))
     assertTrue(bundleCreator.hasResourceConfig())
   }
+
+  private fun getTestDataPath(): Path {
+    return Path.of(AndroidTestBase.getTestDataPath())
+  }
 }