diff --git a/app-inspection/ide/resources/messages/AppInspectionBundle.properties b/app-inspection/ide/resources/messages/AppInspectionBundle.properties
index f8247b3..b9cf5ae 100644
--- a/app-inspection/ide/resources/messages/AppInspectionBundle.properties
+++ b/app-inspection/ide/resources/messages/AppInspectionBundle.properties
@@ -1,10 +1,8 @@
 select.process=Deploy a debuggable app to a device running API level 26 or higher, or select a debuggable process to inspect.
 device.not.found=AndroidDebugBridge cannot find device (''{0}'', ''{1}'', ''{2}'')
 
-notification.crash={0} has crashed.<br><br>\
-  <a href="restart">Restart</a>
-notification.failed.launch={0}<br><br>\
-  <a href="restart">Restart</a>
+notification.crash={0} has crashed.<br><br>
+notification.restart=Restart
 
 launch.app.inspection.tool.window=Launching App Inspection
 
@@ -26,7 +24,8 @@
   shrunk, obfuscated, or optimized.
 
 inspection.is.running=<b>App Inspection</b> is running in the background.<br>\
-  You can either <a href="stop">stop</a> it, or leave it running and resume your session later.
+  You can either stop it, or leave it running and resume your session later.
+action.stop,inspector=Stop App Inspector
 unresolved.inspector=The inspector jar {0} could not be resolved from maven.
 inspector.stopped={0} has stopped running.
 inspector.forcefully.stopped={0} has been replaced by a different instance launched by another project.
\ No newline at end of file
diff --git a/app-inspection/ide/src/com/android/tools/idea/appinspection/ide/ui/AppInspectionToolWindow.kt b/app-inspection/ide/src/com/android/tools/idea/appinspection/ide/ui/AppInspectionToolWindow.kt
index bfc1cc9..7957f47 100644
--- a/app-inspection/ide/src/com/android/tools/idea/appinspection/ide/ui/AppInspectionToolWindow.kt
+++ b/app-inspection/ide/src/com/android/tools/idea/appinspection/ide/ui/AppInspectionToolWindow.kt
@@ -25,7 +25,6 @@
 import com.intellij.notification.Notifications
 import com.intellij.openapi.Disposable
 import com.intellij.openapi.actionSystem.AnAction
-import com.intellij.openapi.actionSystem.AnActionEvent
 import com.intellij.openapi.application.runReadAction
 import com.intellij.openapi.fileEditor.OpenFileDescriptor
 import com.intellij.openapi.project.Project
@@ -40,6 +39,7 @@
 import com.intellij.psi.util.ClassUtil
 import javax.swing.JComponent
 import kotlinx.coroutines.withContext
+import org.jetbrains.annotations.VisibleForTesting
 
 class AppInspectionToolWindow(toolWindow: ToolWindow, private val project: Project) : Disposable {
   companion object {
@@ -48,7 +48,8 @@
       ToolWindowManagerEx.getInstanceEx(project).getToolWindow(APP_INSPECTION_ID)?.show(callback)
   }
 
-  private val ideServices: AppInspectionIdeServices =
+  @VisibleForTesting
+  val ideServices: AppInspectionIdeServices =
     object : AppInspectionIdeServices {
       private val notificationGroup =
         NotificationGroupManager.getInstance().getNotificationGroup(APP_INSPECTION_NOTIFICATIONS_ID)
@@ -60,23 +61,17 @@
         content: String,
         title: String,
         severity: AppInspectionIdeServices.Severity,
-        hyperlinkClicked: () -> Unit,
+        action: AnAction?,
       ) {
         val type =
           when (severity) {
             AppInspectionIdeServices.Severity.INFORMATION -> NotificationType.INFORMATION
             AppInspectionIdeServices.Severity.ERROR -> NotificationType.ERROR
           }
-        val notification =
-          notificationGroup
-            .createNotification(title, content, type)
-            .addAction(
-              object : AnAction() {
-                override fun actionPerformed(e: AnActionEvent) {
-                  hyperlinkClicked()
-                }
-              }
-            )
+        val notification = notificationGroup.createNotification(title, content, type)
+        if (action != null) {
+          notification.addAction(action)
+        }
         Notifications.Bus.notify(notification, project)
       }
 
diff --git a/app-inspection/ide/src/com/android/tools/idea/appinspection/ide/ui/AppInspectionToolWindowManagerListener.kt b/app-inspection/ide/src/com/android/tools/idea/appinspection/ide/ui/AppInspectionToolWindowManagerListener.kt
index 341cb33..61f3b2b 100644
--- a/app-inspection/ide/src/com/android/tools/idea/appinspection/ide/ui/AppInspectionToolWindowManagerListener.kt
+++ b/app-inspection/ide/src/com/android/tools/idea/appinspection/ide/ui/AppInspectionToolWindowManagerListener.kt
@@ -3,6 +3,8 @@
 import com.android.tools.idea.appinspection.ide.analytics.AppInspectionAnalyticsTrackerService
 import com.android.tools.idea.appinspection.ide.model.AppInspectionBundle
 import com.android.tools.idea.appinspection.inspector.api.AppInspectionIdeServices
+import com.intellij.openapi.actionSystem.AnAction
+import com.intellij.openapi.actionSystem.AnActionEvent
 import com.intellij.openapi.project.Project
 import com.intellij.openapi.wm.ToolWindow
 import com.intellij.openapi.wm.ToolWindowManager
@@ -35,7 +37,12 @@
         if (appInspectionView.isInspectionActive()) {
           ideServices.showNotification(
             AppInspectionBundle.message("inspection.is.running"),
-            hyperlinkClicked = { appInspectionView.stopInspectors() },
+            action =
+              object : AnAction(AppInspectionBundle.message("action.stop,inspector")) {
+                override fun actionPerformed(e: AnActionEvent) {
+                  appInspectionView.stopInspectors()
+                }
+              },
           )
         }
       }
diff --git a/app-inspection/ide/src/com/android/tools/idea/appinspection/ide/ui/AppInspectionView.kt b/app-inspection/ide/src/com/android/tools/idea/appinspection/ide/ui/AppInspectionView.kt
index bfef48d..2249efe 100644
--- a/app-inspection/ide/src/com/android/tools/idea/appinspection/ide/ui/AppInspectionView.kt
+++ b/app-inspection/ide/src/com/android/tools/idea/appinspection/ide/ui/AppInspectionView.kt
@@ -53,6 +53,8 @@
 import com.intellij.ide.ActivityTracker
 import com.intellij.openapi.Disposable
 import com.intellij.openapi.actionSystem.ActionManager
+import com.intellij.openapi.actionSystem.AnAction
+import com.intellij.openapi.actionSystem.AnActionEvent
 import com.intellij.openapi.actionSystem.DefaultActionGroup
 import com.intellij.openapi.diagnostic.Logger
 import com.intellij.openapi.project.Project
@@ -197,12 +199,16 @@
     ideServices.showNotification(
       AppInspectionBundle.message("notification.crash", inspectorName),
       severity = AppInspectionIdeServices.Severity.ERROR,
-    ) {
-      AppInspectionAnalyticsTrackerService.getInstance(project).trackInspectionRestarted()
-      if (currentProcess == process) {
-        tabsLaunchScope.launch { launchInspectorForTab(process, tabShell, true) }
-      }
-    }
+      action =
+        object : AnAction(AppInspectionBundle.message("notification.restart")) {
+          override fun actionPerformed(e: AnActionEvent) {
+            AppInspectionAnalyticsTrackerService.getInstance(project).trackInspectionRestarted()
+            if (currentProcess == process) {
+              tabsLaunchScope.launch { launchInspectorForTab(process, tabShell, true) }
+            }
+          }
+        },
+    )
   }
 
   init {
@@ -290,7 +296,9 @@
   private fun hyperlinkClicked(
     process: ProcessDescriptor,
     tabShell: AppInspectorTabShell,
-  ): () -> Unit = {
+  ): () -> Unit = { restartInspector(process, tabShell) }
+
+  private fun restartInspector(process: ProcessDescriptor, tabShell: AppInspectorTabShell) {
     AppInspectionAnalyticsTrackerService.getInstance(project).trackInspectionRestarted()
     tabsLaunchScope.launch { launchInspectorForTab(process, tabShell, true) }
   }
@@ -385,9 +393,14 @@
           )
         )
         ideServices.showNotification(
-          AppInspectionBundle.message("notification.failed.launch", e.message!!),
+          e.message!!,
           severity = AppInspectionIdeServices.Severity.ERROR,
-          hyperlinkClicked = hyperlinkClicked(process, tabShell),
+          action =
+            object : AnAction(AppInspectionBundle.message("notification.restart")) {
+              override fun actionPerformed(e: AnActionEvent) {
+                restartInspector(process, tabShell)
+              }
+            },
         )
       }
     } catch (e: AppInspectionAppProguardedException) {
diff --git a/app-inspection/ide/testSrc/com/android/tools/idea/appinspection/ide/AppInspectionViewTest.kt b/app-inspection/ide/testSrc/com/android/tools/idea/appinspection/ide/AppInspectionViewTest.kt
index e75c3fd..13659ba 100644
--- a/app-inspection/ide/testSrc/com/android/tools/idea/appinspection/ide/AppInspectionViewTest.kt
+++ b/app-inspection/ide/testSrc/com/android/tools/idea/appinspection/ide/AppInspectionViewTest.kt
@@ -54,12 +54,19 @@
 import com.android.tools.profiler.proto.Common
 import com.google.common.truth.Truth.assertThat
 import com.intellij.openapi.Disposable
+import com.intellij.openapi.actionSystem.AnAction
+import com.intellij.openapi.actionSystem.ex.ActionUtil
 import com.intellij.openapi.application.EDT
 import com.intellij.openapi.project.Project
 import com.intellij.openapi.util.Disposer
 import com.intellij.testFramework.DisposableRule
 import com.intellij.testFramework.ProjectRule
 import com.intellij.testFramework.RuleChain
+import com.intellij.testFramework.TestActionEvent
+import java.nio.file.Path
+import java.nio.file.Paths
+import java.util.concurrent.ArrayBlockingQueue
+import javax.swing.JPanel
 import kotlinx.coroutines.CompletableDeferred
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineStart
@@ -76,10 +83,6 @@
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
-import java.nio.file.Path
-import java.nio.file.Paths
-import java.util.concurrent.ArrayBlockingQueue
-import javax.swing.JPanel
 
 class TestAppInspectorTabProvider1 :
   AppInspectorTabProvider by StubTestAppInspectorTabProvider(INSPECTOR_ID)
@@ -104,14 +107,17 @@
     AppInspectionServiceRule(timer, transportService, grpcServerRule)
   private val projectRule = ProjectRule()
   private val disposableRule = DisposableRule()
-  private val disposable get() = disposableRule.disposable
-  private val uiDispatcher get() = Dispatchers.EDT as CoroutineDispatcher
+  private val disposable
+    get() = disposableRule.disposable
+
+  private val uiDispatcher
+    get() = Dispatchers.EDT as CoroutineDispatcher
 
   private class TestIdeServices : AppInspectionIdeServicesAdapter() {
     class NotificationData(
       val content: String,
       val severity: AppInspectionIdeServices.Severity,
-      val hyperlinkClicked: () -> Unit,
+      val action: AnAction?,
     )
 
     val notificationListeners = mutableListOf<(NotificationData) -> Unit>()
@@ -120,9 +126,9 @@
       content: String,
       title: String,
       severity: AppInspectionIdeServices.Severity,
-      hyperlinkClicked: () -> Unit,
+      action: AnAction?,
     ) {
-      val data = NotificationData(content, severity, hyperlinkClicked)
+      val data = NotificationData(content, severity, action)
       notificationListeners.forEach { listener -> listener(data) }
     }
   }
@@ -141,487 +147,480 @@
   }
 
   @Test
-  fun selectProcessInAppInspectionView_twoTabProvidersAddTwoTabs() =
-    runBlocking {
-      val tabsAdded = CompletableDeferred<Unit>()
-      launch(uiDispatcher) {
-        val inspectionView =
-          AppInspectionView(
-            projectRule.project,
-            appInspectionServiceRule.apiServices,
-            ideServices,
-            appInspectionServiceRule.scope,
-            uiDispatcher,
-          ) {
-            it.name == FakeTransportService.FAKE_PROCESS_NAME
-          }
-        Disposer.register(disposable, inspectionView)
-
-        inspectionView.tabsChangedFlow.first {
-          assertThat(inspectionView.inspectorTabs.size).isEqualTo(2)
-          tabsAdded.complete(Unit)
+  fun selectProcessInAppInspectionView_twoTabProvidersAddTwoTabs() = runBlocking {
+    val tabsAdded = CompletableDeferred<Unit>()
+    launch(uiDispatcher) {
+      val inspectionView =
+        AppInspectionView(
+          projectRule.project,
+          appInspectionServiceRule.apiServices,
+          ideServices,
+          appInspectionServiceRule.scope,
+          uiDispatcher,
+        ) {
+          it.name == FakeTransportService.FAKE_PROCESS_NAME
         }
+      Disposer.register(disposable, inspectionView)
+
+      inspectionView.tabsChangedFlow.first {
+        assertThat(inspectionView.inspectorTabs.size).isEqualTo(2)
+        tabsAdded.complete(Unit)
       }
-
-      // Attach to a fake process.
-      transportService.addDevice(FakeTransportService.FAKE_DEVICE)
-      transportService.addProcess(
-        FakeTransportService.FAKE_DEVICE,
-        FakeTransportService.FAKE_PROCESS,
-      )
-
-      tabsAdded.join()
     }
 
+    // Attach to a fake process.
+    transportService.addDevice(FakeTransportService.FAKE_DEVICE)
+    transportService.addProcess(FakeTransportService.FAKE_DEVICE, FakeTransportService.FAKE_PROCESS)
+
+    tabsAdded.join()
+  }
+
   @Test
-  fun selectProcessInAppInspectionView_tabNotAddedForDisabledTabProvider() =
-    runBlocking {
-      // Disable Inspector2 and only one tab should be added.
-      val tabsAdded = CompletableDeferred<Unit>()
-      launch(uiDispatcher) {
-        val inspectionView =
-          AppInspectionView(
-            projectRule.project,
-            appInspectionServiceRule.apiServices,
-            ideServices,
-            { listOf(TestAppInspectorTabProvider1()) },
-            appInspectionServiceRule.scope,
-            uiDispatcher,
-            TestInspectorArtifactService(),
-          ) {
-            it.name == FakeTransportService.FAKE_PROCESS_NAME
-          }
-        Disposer.register(disposable, inspectionView)
-        inspectionView.tabsChangedFlow.first {
-          assertThat(inspectionView.inspectorTabs.size).isEqualTo(1)
-          tabsAdded.complete(Unit)
+  fun selectProcessInAppInspectionView_tabNotAddedForDisabledTabProvider() = runBlocking {
+    // Disable Inspector2 and only one tab should be added.
+    val tabsAdded = CompletableDeferred<Unit>()
+    launch(uiDispatcher) {
+      val inspectionView =
+        AppInspectionView(
+          projectRule.project,
+          appInspectionServiceRule.apiServices,
+          ideServices,
+          { listOf(TestAppInspectorTabProvider1()) },
+          appInspectionServiceRule.scope,
+          uiDispatcher,
+          TestInspectorArtifactService(),
+        ) {
+          it.name == FakeTransportService.FAKE_PROCESS_NAME
         }
+      Disposer.register(disposable, inspectionView)
+      inspectionView.tabsChangedFlow.first {
+        assertThat(inspectionView.inspectorTabs.size).isEqualTo(1)
+        tabsAdded.complete(Unit)
       }
-
-      // Attach to a fake process.
-      transportService.addDevice(FakeTransportService.FAKE_DEVICE)
-      transportService.addProcess(
-        FakeTransportService.FAKE_DEVICE,
-        FakeTransportService.FAKE_PROCESS,
-      )
-
-      tabsAdded.join()
     }
 
-  @Test
-  fun disposeInspectorWhenSelectionChanges() =
-    runBlocking {
-      lateinit var tabs: List<AppInspectorTab>
-      launch(uiDispatcher) {
-        val inspectionView =
-          AppInspectionView(
-            projectRule.project,
-            appInspectionServiceRule.apiServices,
-            ideServices,
-            appInspectionServiceRule.scope,
-            uiDispatcher,
-          ) {
-            it.name == FakeTransportService.FAKE_PROCESS_NAME
-          }
-        Disposer.register(disposable, inspectionView)
+    // Attach to a fake process.
+    transportService.addDevice(FakeTransportService.FAKE_DEVICE)
+    transportService.addProcess(FakeTransportService.FAKE_DEVICE, FakeTransportService.FAKE_PROCESS)
 
-        inspectionView.tabsChangedFlow.take(2).collectIndexed { i, _ ->
-          if (i == 0) {
-            assertThat(inspectionView.inspectorTabs.size).isEqualTo(2)
-            inspectionView.inspectorTabs.forEach { it.waitForContent() }
-            tabs =
-              inspectionView.inspectorTabs
-                .mapNotNull { it.getUserData(TAB_KEY) }
-                .filter {
-                  it.messengers.iterator().hasNext()
-                } // If a tab is "dead", it won't have any messengers
-
-            assertThat(tabs).hasSize(1)
-            inspectionView.processesModel.selectedProcess =
-              inspectionView.processesModel.processes.first { process ->
-                process != inspectionView.processesModel.selectedProcess
-              }
-          } else if (i == 1) {
-            tabs.forEach { tab -> assertThat(tab.messengers.single().scope.isActive).isFalse() }
-          }
-        }
-      }
-
-      // Launch two processes and wait for them to show up in combobox
-      val fakeDevice =
-        FakeTransportService.FAKE_DEVICE.toBuilder()
-          .setDeviceId(1)
-          .setModel("fakeModel")
-          .setManufacturer("fakeMan")
-          .setSerial("1")
-          .build()
-      val fakeProcess1 =
-        FakeTransportService.FAKE_PROCESS.toBuilder().setPid(1).setDeviceId(1).build()
-      val fakeProcess2 =
-        FakeTransportService.FAKE_PROCESS.toBuilder().setPid(2).setDeviceId(1).build()
-      transportService.addDevice(fakeDevice)
-      transportService.addProcess(fakeDevice, fakeProcess1)
-      transportService.addProcess(fakeDevice, fakeProcess2)
-    }
+    tabsAdded.join()
+  }
 
   @Test
-  fun receivesInspectorDisposedEvent() =
-    runBlocking {
-      val fakeDevice =
-        FakeTransportService.FAKE_DEVICE.toBuilder()
-          .apply {
-            deviceId = 1
-            model = "fakeModel"
-            serial = "1"
-          }
-          .build()
-
-      val fakeProcess =
-        FakeTransportService.FAKE_PROCESS.toBuilder()
-          .apply {
-            pid = 1
-            deviceId = 1
-          }
-          .build()
-
-      lateinit var inspectionView: AppInspectionView
-      launch(uiDispatcher) {
-        inspectionView =
-          AppInspectionView(
-            projectRule.project,
-            appInspectionServiceRule.apiServices,
-            ideServices,
-            { listOf(StubTestAppInspectorTabProvider(INSPECTOR_ID)) },
-            appInspectionServiceRule.scope,
-            uiDispatcher,
-            TestInspectorArtifactService(),
-          ) {
-            it.name == FakeTransportService.FAKE_PROCESS_NAME
-          }
-        Disposer.register(disposable, inspectionView)
-
-        // Test initial tabs added.
-        inspectionView.tabsChangedFlow.first {
-          assertThat(inspectionView.inspectorTabs.size).isEqualTo(1)
-          val tabShell = inspectionView.inspectorTabs[0]
-          val component = tabShell.waitForContent()
-          assertThat(component).isNotInstanceOf(EmptyStatePanel::class.java)
-          launch(start = CoroutineStart.UNDISPATCHED) {
-            assertThat(tabShell.componentUpdates.first()).isInstanceOf(EmptyStatePanel::class.java)
-          }
-          // Generate fake dispose event
-          transportService.addEventToStream(
-            fakeDevice.deviceId,
-            Common.Event.newBuilder()
-              .setPid(fakeProcess.pid)
-              .setKind(Common.Event.Kind.APP_INSPECTION_EVENT)
-              .setTimestamp(timer.currentTimeNs)
-              .setIsEnded(true)
-              .setAppInspectionEvent(
-                AppInspection.AppInspectionEvent.newBuilder()
-                  .setInspectorId(INSPECTOR_ID)
-                  .setDisposedEvent(AppInspection.DisposedEvent.getDefaultInstance())
-                  .build()
-              )
-              .build(),
-          )
-          true
+  fun disposeInspectorWhenSelectionChanges() = runBlocking {
+    lateinit var tabs: List<AppInspectorTab>
+    launch(uiDispatcher) {
+      val inspectionView =
+        AppInspectionView(
+          projectRule.project,
+          appInspectionServiceRule.apiServices,
+          ideServices,
+          appInspectionServiceRule.scope,
+          uiDispatcher,
+        ) {
+          it.name == FakeTransportService.FAKE_PROCESS_NAME
         }
-      }
+      Disposer.register(disposable, inspectionView)
 
-      // Launch a processes and wait for its tab to be created
-      transportService.addDevice(fakeDevice)
-      transportService.addProcess(fakeDevice, fakeProcess)
-    }
-
-  @Test
-  fun inspectorTabsAreDisposed_whenUiIsRefreshed() =
-    runBlocking {
-      val tabDisposedDeferred = CompletableDeferred<Unit>()
-      val offlineTabDisposedDeferred = CompletableDeferred<Unit>()
-      val tabProvider =
-        object : AppInspectorTabProvider by StubTestAppInspectorTabProvider(INSPECTOR_ID) {
-          override fun createTab(
-            project: Project,
-            ideServices: AppInspectionIdeServices,
-            processDescriptor: ProcessDescriptor,
-            messengerTargets: List<AppInspectorMessengerTarget>,
-            parentDisposable: Disposable,
-          ): AppInspectorTab {
-            return object : AppInspectorTab, Disposable {
-              override val messengers: Iterable<AppInspectorMessenger> =
-                listOf(StubTestAppInspectorMessenger())
-              override val component = JPanel()
-
-              override fun dispose() {
-                tabDisposedDeferred.complete(Unit)
-              }
-
-              init {
-                Disposer.register(parentDisposable, this)
-              }
-            }
-          }
-        }
-      val offlineTabProvider =
-        object : AppInspectorTabProvider by StubTestAppInspectorTabProvider(INSPECTOR_ID_2) {
-          override fun supportsOffline() = true
-
-          override fun createTab(
-            project: Project,
-            ideServices: AppInspectionIdeServices,
-            processDescriptor: ProcessDescriptor,
-            messengerTargets: List<AppInspectorMessengerTarget>,
-            parentDisposable: Disposable,
-          ): AppInspectorTab {
-            return object : AppInspectorTab, Disposable {
-              override val messengers = listOf(StubTestAppInspectorMessenger())
-              override val component = JPanel()
-
-              override fun dispose() {
-                offlineTabDisposedDeferred.complete(Unit)
-              }
-
-              init {
-                Disposer.register(parentDisposable, this)
-              }
-            }
-          }
-        }
-
-      launch(uiDispatcher) {
-        val inspectionView =
-          AppInspectionView(
-            projectRule.project,
-            appInspectionServiceRule.apiServices,
-            ideServices,
-            { listOf(tabProvider, offlineTabProvider) },
-            appInspectionServiceRule.scope,
-            uiDispatcher,
-            TestInspectorArtifactService(),
-          ) {
-            it.name == FakeTransportService.FAKE_PROCESS_NAME
-          }
-        Disposer.register(disposable, inspectionView)
-        val previousTabs = mutableListOf<AppInspectorTabShell>()
-        inspectionView.tabsChangedFlow.take(3).collectIndexed { i, _ ->
-          when (i) {
-            0 -> {
-              // Stopping the process should cause the first tab to be disposed, but keep the
-              // offline tab.
-              assertThat(inspectionView.inspectorTabs).hasSize(2)
-              inspectionView.inspectorTabs.forEach { it.waitForContent() }
-              transportService.stopProcess(
-                FakeTransportService.FAKE_DEVICE,
-                FakeTransportService.FAKE_PROCESS,
-              )
-              timer.currentTimeNs += 1
-              previousTabs.addAll(inspectionView.inspectorTabs)
-            }
-            1 -> {
-              // Making the process go back online should cause the tool window to refresh and
-              // dispose of the offline tab.
-              assertThat(inspectionView.inspectorTabs).hasSize(1)
-              // Verify regardless of tab's offline capability, all messengers are disposed.
-              previousTabs.forEach { tab ->
-                assertThat(
-                    tab
-                      .getUserData(TAB_KEY)!!
-                      .messengers
-                      .first()
-                      .scope
-                      .coroutineContext[Job]!!
-                      .isCancelled
-                  )
-                  .isTrue()
-              }
-              transportService.addProcess(
-                FakeTransportService.FAKE_DEVICE,
-                FakeTransportService.FAKE_PROCESS,
-              )
-              timer.currentTimeNs += 1
-            }
-            2 -> {
-              // 2 tabs are added back in the tool window.
-              assertThat(inspectionView.inspectorTabs).hasSize(2)
-            }
-          }
-        }
-      }
-
-      // Launch a processes to start the test
-      transportService.addDevice(FakeTransportService.FAKE_DEVICE)
-      transportService.addProcess(
-        FakeTransportService.FAKE_DEVICE,
-        FakeTransportService.FAKE_PROCESS,
-      )
-      timer.currentTimeNs += 1
-
-      tabDisposedDeferred.await()
-      offlineTabDisposedDeferred.await()
-    }
-
-  @Test
-  fun inspectorCrashNotification() =
-    runBlocking {
-      val fakeDevice =
-        FakeTransportService.FAKE_DEVICE.toBuilder()
-          .setDeviceId(1)
-          .setModel("fakeModel")
-          .setManufacturer("fakeMan")
-          .setSerial("1")
-          .build()
-      val fakeProcess =
-        FakeTransportService.FAKE_PROCESS.toBuilder().setPid(1).setDeviceId(1).build()
-
-      lateinit var inspectionView: AppInspectionView
-      launch(uiDispatcher) {
-        inspectionView =
-          AppInspectionView(
-            projectRule.project,
-            appInspectionServiceRule.apiServices,
-            ideServices,
-            appInspectionServiceRule.scope,
-            uiDispatcher,
-          ) {
-            it.name == FakeTransportService.FAKE_PROCESS_NAME
-          }
-        Disposer.register(disposable, inspectionView)
-
-        // Test initial tabs added.
-        inspectionView.tabsChangedFlow.first {
+      inspectionView.tabsChangedFlow.take(2).collectIndexed { i, _ ->
+        if (i == 0) {
           assertThat(inspectionView.inspectorTabs.size).isEqualTo(2)
           inspectionView.inspectorTabs.forEach { it.waitForContent() }
+          tabs =
+            inspectionView.inspectorTabs
+              .mapNotNull { it.getUserData(TAB_KEY) }
+              .filter {
+                it.messengers.iterator().hasNext()
+              } // If a tab is "dead", it won't have any messengers
 
-          // The tab shell that will be restarted.
-          val crashedTabShell = inspectionView.inspectorTabs.first()
-          launch(start = CoroutineStart.UNDISPATCHED) {
-            assertThat(crashedTabShell.componentUpdates.first())
-              .isInstanceOf(TestAppInspectorTabComponent::class.java)
-          }
-
-          // Test crash notification shown.
-          val notificationDataDeferred = CompletableDeferred<TestIdeServices.NotificationData>()
-          ideServices.notificationListeners += { data -> notificationDataDeferred.complete(data) }
-
-          // Generate fake crash event
-          transportService.addEventToStream(
-            fakeDevice.deviceId,
-            Common.Event.newBuilder()
-              .setPid(fakeProcess.pid)
-              .setKind(Common.Event.Kind.APP_INSPECTION_EVENT)
-              .setTimestamp(timer.currentTimeNs)
-              .setIsEnded(true)
-              .setAppInspectionEvent(
-                AppInspection.AppInspectionEvent.newBuilder()
-                  .setInspectorId(INSPECTOR_ID)
-                  .setDisposedEvent(
-                    AppInspection.DisposedEvent.newBuilder().setErrorMessage("error").build()
-                  )
-                  .build()
-              )
-              .build(),
-          )
-
-          // increment timer manually here because otherwise the new inspector connection created
-          // below will poll the crash event above.
-          timer.currentTimeNs += 1
-
-          val notificationData = notificationDataDeferred.await()
-          assertThat(notificationData.content).contains("$INSPECTOR_ID has crashed")
-          assertThat(notificationData.severity).isEqualTo(AppInspectionIdeServices.Severity.ERROR)
-
-          setUpRelaunchingCommandHandler()
-          launch(uiDispatcher) {
-            // Make sure clicking the notification causes a new tab to get created
-            notificationData.hyperlinkClicked()
-          }
-          true
+          assertThat(tabs).hasSize(1)
+          inspectionView.processesModel.selectedProcess =
+            inspectionView.processesModel.processes.first { process ->
+              process != inspectionView.processesModel.selectedProcess
+            }
+        } else if (i == 1) {
+          tabs.forEach { tab -> assertThat(tab.messengers.single().scope.isActive).isFalse() }
         }
       }
-      // Launch a processes and wait for its tab to be created
-      transportService.addDevice(fakeDevice)
-      transportService.addProcess(fakeDevice, fakeProcess)
     }
 
+    // Launch two processes and wait for them to show up in combobox
+    val fakeDevice =
+      FakeTransportService.FAKE_DEVICE.toBuilder()
+        .setDeviceId(1)
+        .setModel("fakeModel")
+        .setManufacturer("fakeMan")
+        .setSerial("1")
+        .build()
+    val fakeProcess1 =
+      FakeTransportService.FAKE_PROCESS.toBuilder().setPid(1).setDeviceId(1).build()
+    val fakeProcess2 =
+      FakeTransportService.FAKE_PROCESS.toBuilder().setPid(2).setDeviceId(1).build()
+    transportService.addDevice(fakeDevice)
+    transportService.addProcess(fakeDevice, fakeProcess1)
+    transportService.addProcess(fakeDevice, fakeProcess2)
+  }
+
   @Test
-  fun inspectorRestartNotificationShownOnLaunchError() =
-    runBlocking {
-      val fakeDevice =
-        FakeTransportService.FAKE_DEVICE.toBuilder()
-          .setDeviceId(1)
-          .setModel("fakeModel")
-          .setManufacturer("fakeMan")
-          .setSerial("1")
-          .build()
+  fun receivesInspectorDisposedEvent() = runBlocking {
+    val fakeDevice =
+      FakeTransportService.FAKE_DEVICE.toBuilder()
+        .apply {
+          deviceId = 1
+          model = "fakeModel"
+          serial = "1"
+        }
+        .build()
 
-      val fakeProcess =
-        FakeTransportService.FAKE_PROCESS.toBuilder().setPid(1).setDeviceId(1).build()
+    val fakeProcess =
+      FakeTransportService.FAKE_PROCESS.toBuilder()
+        .apply {
+          pid = 1
+          deviceId = 1
+        }
+        .build()
 
-      transportService.addDevice(fakeDevice)
-      transportService.addProcess(fakeDevice, fakeProcess)
+    lateinit var inspectionView: AppInspectionView
+    launch(uiDispatcher) {
+      inspectionView =
+        AppInspectionView(
+          projectRule.project,
+          appInspectionServiceRule.apiServices,
+          ideServices,
+          { listOf(StubTestAppInspectorTabProvider(INSPECTOR_ID)) },
+          appInspectionServiceRule.scope,
+          uiDispatcher,
+          TestInspectorArtifactService(),
+        ) {
+          it.name == FakeTransportService.FAKE_PROCESS_NAME
+        }
+      Disposer.register(disposable, inspectionView)
 
-      // Overwrite the handler to simulate a launch error, e.g. an inspector was left over from a
-      // previous crash
-      transportService.setCommandHandler(
-        Commands.Command.CommandType.APP_INSPECTION,
-        TestAppInspectorCommandHandler(
-          timer,
-          createInspectorResponse =
-            createCreateInspectorResponse(
-              AppInspection.AppInspectionResponse.Status.ERROR,
-              AppInspection.CreateInspectorResponse.Status.GENERIC_SERVICE_ERROR,
-              "error",
-            ),
-        ),
-      )
-
-      val notificationDataDeferred = CompletableDeferred<TestIdeServices.NotificationData>()
-      ideServices.notificationListeners += { data -> notificationDataDeferred.complete(data) }
-
-      lateinit var inspectionView: AppInspectionView
-      val tabsAdded = CompletableDeferred<Unit>()
-      launch(uiDispatcher) {
-        inspectionView =
-          AppInspectionView(
-            projectRule.project,
-            appInspectionServiceRule.apiServices,
-            ideServices,
-            { listOf(StubTestAppInspectorTabProvider(INSPECTOR_ID)) },
-            appInspectionServiceRule.scope,
-            uiDispatcher,
-            TestInspectorArtifactService(),
-          ) {
-            it.name == FakeTransportService.FAKE_PROCESS_NAME
-          }
-        Disposer.register(disposable, inspectionView)
-
-        inspectionView.tabsChangedFlow.first {
-          assertThat(inspectionView.inspectorTabs.size).isEqualTo(1)
-          val tab = inspectionView.inspectorTabs[0]
-          val initialComponent = tab.waitForContent()
-          assertThat((initialComponent as EmptyStatePanel).reasonText)
-            .isEqualTo(
-              AppInspectionBundle.message("inspector.launch.error", tab.provider.displayName)
+      // Test initial tabs added.
+      inspectionView.tabsChangedFlow.first {
+        assertThat(inspectionView.inspectorTabs.size).isEqualTo(1)
+        val tabShell = inspectionView.inspectorTabs[0]
+        val component = tabShell.waitForContent()
+        assertThat(component).isNotInstanceOf(EmptyStatePanel::class.java)
+        launch(start = CoroutineStart.UNDISPATCHED) {
+          assertThat(tabShell.componentUpdates.first()).isInstanceOf(EmptyStatePanel::class.java)
+        }
+        // Generate fake dispose event
+        transportService.addEventToStream(
+          fakeDevice.deviceId,
+          Common.Event.newBuilder()
+            .setPid(fakeProcess.pid)
+            .setKind(Common.Event.Kind.APP_INSPECTION_EVENT)
+            .setTimestamp(timer.currentTimeNs)
+            .setIsEnded(true)
+            .setAppInspectionEvent(
+              AppInspection.AppInspectionEvent.newBuilder()
+                .setInspectorId(INSPECTOR_ID)
+                .setDisposedEvent(AppInspection.DisposedEvent.getDefaultInstance())
+                .build()
             )
+            .build(),
+        )
+        true
+      }
+    }
 
-          val restartedComponent = tab.componentUpdates.first()
-          assertThat(restartedComponent).isNotSameAs(initialComponent)
-          assertThat(restartedComponent).isInstanceOf(TestAppInspectorTabComponent::class.java)
-          tabsAdded.complete(Unit)
+    // Launch a processes and wait for its tab to be created
+    transportService.addDevice(fakeDevice)
+    transportService.addProcess(fakeDevice, fakeProcess)
+  }
+
+  @Test
+  fun inspectorTabsAreDisposed_whenUiIsRefreshed() = runBlocking {
+    val tabDisposedDeferred = CompletableDeferred<Unit>()
+    val offlineTabDisposedDeferred = CompletableDeferred<Unit>()
+    val tabProvider =
+      object : AppInspectorTabProvider by StubTestAppInspectorTabProvider(INSPECTOR_ID) {
+        override fun createTab(
+          project: Project,
+          ideServices: AppInspectionIdeServices,
+          processDescriptor: ProcessDescriptor,
+          messengerTargets: List<AppInspectorMessengerTarget>,
+          parentDisposable: Disposable,
+        ): AppInspectorTab {
+          return object : AppInspectorTab, Disposable {
+            override val messengers: Iterable<AppInspectorMessenger> =
+              listOf(StubTestAppInspectorMessenger())
+            override val component = JPanel()
+
+            override fun dispose() {
+              tabDisposedDeferred.complete(Unit)
+            }
+
+            init {
+              Disposer.register(parentDisposable, this)
+            }
+          }
+        }
+      }
+    val offlineTabProvider =
+      object : AppInspectorTabProvider by StubTestAppInspectorTabProvider(INSPECTOR_ID_2) {
+        override fun supportsOffline() = true
+
+        override fun createTab(
+          project: Project,
+          ideServices: AppInspectionIdeServices,
+          processDescriptor: ProcessDescriptor,
+          messengerTargets: List<AppInspectorMessengerTarget>,
+          parentDisposable: Disposable,
+        ): AppInspectorTab {
+          return object : AppInspectorTab, Disposable {
+            override val messengers = listOf(StubTestAppInspectorMessenger())
+            override val component = JPanel()
+
+            override fun dispose() {
+              offlineTabDisposedDeferred.complete(Unit)
+            }
+
+            init {
+              Disposer.register(parentDisposable, this)
+            }
+          }
         }
       }
 
-      // Verify we crashed on launch, failing to open the UI and triggering the toast.
-      val notificationData = notificationDataDeferred.await()
-      assertThat(notificationData.content).startsWith("Could not launch inspector")
-      assertThat(notificationData.severity).isEqualTo(AppInspectionIdeServices.Severity.ERROR)
-
-      setUpRelaunchingCommandHandler()
-      launch(uiDispatcher) { notificationData.hyperlinkClicked() }
-      tabsAdded.join()
+    launch(uiDispatcher) {
+      val inspectionView =
+        AppInspectionView(
+          projectRule.project,
+          appInspectionServiceRule.apiServices,
+          ideServices,
+          { listOf(tabProvider, offlineTabProvider) },
+          appInspectionServiceRule.scope,
+          uiDispatcher,
+          TestInspectorArtifactService(),
+        ) {
+          it.name == FakeTransportService.FAKE_PROCESS_NAME
+        }
+      Disposer.register(disposable, inspectionView)
+      val previousTabs = mutableListOf<AppInspectorTabShell>()
+      inspectionView.tabsChangedFlow.take(3).collectIndexed { i, _ ->
+        when (i) {
+          0 -> {
+            // Stopping the process should cause the first tab to be disposed, but keep the
+            // offline tab.
+            assertThat(inspectionView.inspectorTabs).hasSize(2)
+            inspectionView.inspectorTabs.forEach { it.waitForContent() }
+            transportService.stopProcess(
+              FakeTransportService.FAKE_DEVICE,
+              FakeTransportService.FAKE_PROCESS,
+            )
+            timer.currentTimeNs += 1
+            previousTabs.addAll(inspectionView.inspectorTabs)
+          }
+          1 -> {
+            // Making the process go back online should cause the tool window to refresh and
+            // dispose of the offline tab.
+            assertThat(inspectionView.inspectorTabs).hasSize(1)
+            // Verify regardless of tab's offline capability, all messengers are disposed.
+            previousTabs.forEach { tab ->
+              assertThat(
+                  tab
+                    .getUserData(TAB_KEY)!!
+                    .messengers
+                    .first()
+                    .scope
+                    .coroutineContext[Job]!!
+                    .isCancelled
+                )
+                .isTrue()
+            }
+            transportService.addProcess(
+              FakeTransportService.FAKE_DEVICE,
+              FakeTransportService.FAKE_PROCESS,
+            )
+            timer.currentTimeNs += 1
+          }
+          2 -> {
+            // 2 tabs are added back in the tool window.
+            assertThat(inspectionView.inspectorTabs).hasSize(2)
+          }
+        }
+      }
     }
 
+    // Launch a processes to start the test
+    transportService.addDevice(FakeTransportService.FAKE_DEVICE)
+    transportService.addProcess(FakeTransportService.FAKE_DEVICE, FakeTransportService.FAKE_PROCESS)
+    timer.currentTimeNs += 1
+
+    tabDisposedDeferred.await()
+    offlineTabDisposedDeferred.await()
+  }
+
+  @Test
+  fun inspectorCrashNotification() = runBlocking {
+    val fakeDevice =
+      FakeTransportService.FAKE_DEVICE.toBuilder()
+        .setDeviceId(1)
+        .setModel("fakeModel")
+        .setManufacturer("fakeMan")
+        .setSerial("1")
+        .build()
+    val fakeProcess = FakeTransportService.FAKE_PROCESS.toBuilder().setPid(1).setDeviceId(1).build()
+
+    lateinit var inspectionView: AppInspectionView
+    launch(uiDispatcher) {
+      inspectionView =
+        AppInspectionView(
+          projectRule.project,
+          appInspectionServiceRule.apiServices,
+          ideServices,
+          appInspectionServiceRule.scope,
+          uiDispatcher,
+        ) {
+          it.name == FakeTransportService.FAKE_PROCESS_NAME
+        }
+      Disposer.register(disposable, inspectionView)
+
+      // Test initial tabs added.
+      inspectionView.tabsChangedFlow.first {
+        assertThat(inspectionView.inspectorTabs.size).isEqualTo(2)
+        inspectionView.inspectorTabs.forEach { it.waitForContent() }
+
+        // The tab shell that will be restarted.
+        val crashedTabShell = inspectionView.inspectorTabs.first()
+        launch(start = CoroutineStart.UNDISPATCHED) {
+          assertThat(crashedTabShell.componentUpdates.first())
+            .isInstanceOf(TestAppInspectorTabComponent::class.java)
+        }
+
+        // Test crash notification shown.
+        val notificationDataDeferred = CompletableDeferred<TestIdeServices.NotificationData>()
+        ideServices.notificationListeners += { data -> notificationDataDeferred.complete(data) }
+
+        // Generate fake crash event
+        transportService.addEventToStream(
+          fakeDevice.deviceId,
+          Common.Event.newBuilder()
+            .setPid(fakeProcess.pid)
+            .setKind(Common.Event.Kind.APP_INSPECTION_EVENT)
+            .setTimestamp(timer.currentTimeNs)
+            .setIsEnded(true)
+            .setAppInspectionEvent(
+              AppInspection.AppInspectionEvent.newBuilder()
+                .setInspectorId(INSPECTOR_ID)
+                .setDisposedEvent(
+                  AppInspection.DisposedEvent.newBuilder().setErrorMessage("error").build()
+                )
+                .build()
+            )
+            .build(),
+        )
+
+        // increment timer manually here because otherwise the new inspector connection created
+        // below will poll the crash event above.
+        timer.currentTimeNs += 1
+
+        val notificationData = notificationDataDeferred.await()
+        assertThat(notificationData.content).contains("$INSPECTOR_ID has crashed")
+        assertThat(notificationData.severity).isEqualTo(AppInspectionIdeServices.Severity.ERROR)
+
+        setUpRelaunchingCommandHandler()
+        launch(uiDispatcher) {
+          // Make sure clicking the notification causes a new tab to get created
+          val action = notificationData.action
+          if (action != null) {
+            ActionUtil.performActionDumbAwareWithCallbacks(
+              action,
+              TestActionEvent.createTestEvent(),
+            )
+          }
+        }
+        true
+      }
+    }
+    // Launch a processes and wait for its tab to be created
+    transportService.addDevice(fakeDevice)
+    transportService.addProcess(fakeDevice, fakeProcess)
+  }
+
+  @Test
+  fun inspectorRestartNotificationShownOnLaunchError() = runBlocking {
+    val fakeDevice =
+      FakeTransportService.FAKE_DEVICE.toBuilder()
+        .setDeviceId(1)
+        .setModel("fakeModel")
+        .setManufacturer("fakeMan")
+        .setSerial("1")
+        .build()
+
+    val fakeProcess = FakeTransportService.FAKE_PROCESS.toBuilder().setPid(1).setDeviceId(1).build()
+
+    transportService.addDevice(fakeDevice)
+    transportService.addProcess(fakeDevice, fakeProcess)
+
+    // Overwrite the handler to simulate a launch error, e.g. an inspector was left over from a
+    // previous crash
+    transportService.setCommandHandler(
+      Commands.Command.CommandType.APP_INSPECTION,
+      TestAppInspectorCommandHandler(
+        timer,
+        createInspectorResponse =
+          createCreateInspectorResponse(
+            AppInspection.AppInspectionResponse.Status.ERROR,
+            AppInspection.CreateInspectorResponse.Status.GENERIC_SERVICE_ERROR,
+            "error",
+          ),
+      ),
+    )
+
+    val notificationDataDeferred = CompletableDeferred<TestIdeServices.NotificationData>()
+    ideServices.notificationListeners += { data -> notificationDataDeferred.complete(data) }
+
+    lateinit var inspectionView: AppInspectionView
+    val tabsAdded = CompletableDeferred<Unit>()
+    launch(uiDispatcher) {
+      inspectionView =
+        AppInspectionView(
+          projectRule.project,
+          appInspectionServiceRule.apiServices,
+          ideServices,
+          { listOf(StubTestAppInspectorTabProvider(INSPECTOR_ID)) },
+          appInspectionServiceRule.scope,
+          uiDispatcher,
+          TestInspectorArtifactService(),
+        ) {
+          it.name == FakeTransportService.FAKE_PROCESS_NAME
+        }
+      Disposer.register(disposable, inspectionView)
+
+      inspectionView.tabsChangedFlow.first {
+        assertThat(inspectionView.inspectorTabs.size).isEqualTo(1)
+        val tab = inspectionView.inspectorTabs[0]
+        val initialComponent = tab.waitForContent()
+        assertThat((initialComponent as EmptyStatePanel).reasonText)
+          .isEqualTo(
+            AppInspectionBundle.message("inspector.launch.error", tab.provider.displayName)
+          )
+
+        val restartedComponent = tab.componentUpdates.first()
+        assertThat(restartedComponent).isNotSameAs(initialComponent)
+        assertThat(restartedComponent).isInstanceOf(TestAppInspectorTabComponent::class.java)
+        tabsAdded.complete(Unit)
+      }
+    }
+
+    // Verify we crashed on launch, failing to open the UI and triggering the toast.
+    val notificationData = notificationDataDeferred.await()
+    assertThat(notificationData.content).startsWith("Could not launch inspector")
+    assertThat(notificationData.severity).isEqualTo(AppInspectionIdeServices.Severity.ERROR)
+
+    setUpRelaunchingCommandHandler()
+    val action = notificationData.action
+    if (action != null) {
+      launch(uiDispatcher) {
+        ActionUtil.performActionDumbAwareWithCallbacks(action, TestActionEvent.createTestEvent())
+      }
+    }
+    tabsAdded.join()
+  }
+
   @Test
   fun inspectorRestartEmptyPanelShownOnLaunchError() = runBlocking {
     val fakeDevice =
@@ -812,282 +811,262 @@
   }
 
   @Test
-  fun launchInspectorFailsDueToIncompatibleVersion_emptyMessageAdded() =
-    runBlocking {
-      val tabsAdded = CompletableDeferred<Unit>()
-      val provider = TestAppInspectorTabProvider2()
-      launch(uiDispatcher) {
-        val inspectionView =
-          AppInspectionView(
-            projectRule.project,
-            appInspectionServiceRule.apiServices,
-            ideServices,
-            { listOf(provider) },
-            appInspectionServiceRule.scope,
-            uiDispatcher,
-            TestInspectorArtifactService(),
-          ) {
-            it.name == FakeTransportService.FAKE_PROCESS_NAME
-          }
-        Disposer.register(disposable, inspectionView)
-        inspectionView.tabsChangedFlow.first {
-          assertThat(inspectionView.inspectorTabs.size).isEqualTo(1)
-          val tab = inspectionView.inspectorTabs[0]
-          tab.waitForContent()
-          val emptyPanel = tab.containerPanel.getComponent(0) as EmptyStatePanel
+  fun launchInspectorFailsDueToIncompatibleVersion_emptyMessageAdded() = runBlocking {
+    val tabsAdded = CompletableDeferred<Unit>()
+    val provider = TestAppInspectorTabProvider2()
+    launch(uiDispatcher) {
+      val inspectionView =
+        AppInspectionView(
+          projectRule.project,
+          appInspectionServiceRule.apiServices,
+          ideServices,
+          { listOf(provider) },
+          appInspectionServiceRule.scope,
+          uiDispatcher,
+          TestInspectorArtifactService(),
+        ) {
+          it.name == FakeTransportService.FAKE_PROCESS_NAME
+        }
+      Disposer.register(disposable, inspectionView)
+      inspectionView.tabsChangedFlow.first {
+        assertThat(inspectionView.inspectorTabs.size).isEqualTo(1)
+        val tab = inspectionView.inspectorTabs[0]
+        tab.waitForContent()
+        val emptyPanel = tab.containerPanel.getComponent(0) as EmptyStatePanel
 
-          assertThat(emptyPanel.reasonText)
-            .isEqualTo(
-              AppInspectionBundle.message(
-                "incompatible.version",
-                (provider.launchConfigs.single().params as LibraryInspectorLaunchParams)
-                  .minVersionLibraryCoordinate
-                  .toString(),
-              )
+        assertThat(emptyPanel.reasonText)
+          .isEqualTo(
+            AppInspectionBundle.message(
+              "incompatible.version",
+              (provider.launchConfigs.single().params as LibraryInspectorLaunchParams)
+                .minVersionLibraryCoordinate
+                .toString(),
             )
+          )
 
-          tabsAdded.complete(Unit)
-        }
+        tabsAdded.complete(Unit)
       }
-
-      transportService.setCommandHandler(
-        Commands.Command.CommandType.APP_INSPECTION,
-        TestAppInspectorCommandHandler(
-          timer,
-          createInspectorResponse =
-            createCreateInspectorResponse(
-              AppInspection.AppInspectionResponse.Status.ERROR,
-              AppInspection.CreateInspectorResponse.Status.VERSION_INCOMPATIBLE,
-              "error",
-            ),
-        ),
-      )
-
-      // Attach to a fake process.
-      transportService.addDevice(FakeTransportService.FAKE_DEVICE)
-      transportService.addProcess(
-        FakeTransportService.FAKE_DEVICE,
-        FakeTransportService.FAKE_PROCESS,
-      )
-
-      tabsAdded.join()
     }
 
+    transportService.setCommandHandler(
+      Commands.Command.CommandType.APP_INSPECTION,
+      TestAppInspectorCommandHandler(
+        timer,
+        createInspectorResponse =
+          createCreateInspectorResponse(
+            AppInspection.AppInspectionResponse.Status.ERROR,
+            AppInspection.CreateInspectorResponse.Status.VERSION_INCOMPATIBLE,
+            "error",
+          ),
+      ),
+    )
+
+    // Attach to a fake process.
+    transportService.addDevice(FakeTransportService.FAKE_DEVICE)
+    transportService.addProcess(FakeTransportService.FAKE_DEVICE, FakeTransportService.FAKE_PROCESS)
+
+    tabsAdded.join()
+  }
+
   @Test
-  fun launchInspectorFailsDueToAppProguarded_emptyMessageAdded() =
-    runBlocking {
-      val tabsAdded = CompletableDeferred<Unit>()
-      val provider = TestAppInspectorTabProvider2()
-      launch(uiDispatcher) {
-        val inspectionView =
-          AppInspectionView(
-            projectRule.project,
-            appInspectionServiceRule.apiServices,
-            ideServices,
-            { listOf(provider) },
-            appInspectionServiceRule.scope,
-            uiDispatcher,
-            TestInspectorArtifactService(),
-          ) {
-            it.name == FakeTransportService.FAKE_PROCESS_NAME
-          }
-        Disposer.register(disposable, inspectionView)
-        inspectionView.tabsChangedFlow.first {
-          assertThat(inspectionView.inspectorTabs.size).isEqualTo(1)
-          val tab = inspectionView.inspectorTabs[0]
-          tab.waitForContent()
-          val emptyPanel = tab.containerPanel.getComponent(0) as EmptyStatePanel
-          assertThat(emptyPanel.reasonText).isEqualTo(AppInspectionBundle.message("app.proguarded"))
-          tabsAdded.complete(Unit)
+  fun launchInspectorFailsDueToAppProguarded_emptyMessageAdded() = runBlocking {
+    val tabsAdded = CompletableDeferred<Unit>()
+    val provider = TestAppInspectorTabProvider2()
+    launch(uiDispatcher) {
+      val inspectionView =
+        AppInspectionView(
+          projectRule.project,
+          appInspectionServiceRule.apiServices,
+          ideServices,
+          { listOf(provider) },
+          appInspectionServiceRule.scope,
+          uiDispatcher,
+          TestInspectorArtifactService(),
+        ) {
+          it.name == FakeTransportService.FAKE_PROCESS_NAME
         }
+      Disposer.register(disposable, inspectionView)
+      inspectionView.tabsChangedFlow.first {
+        assertThat(inspectionView.inspectorTabs.size).isEqualTo(1)
+        val tab = inspectionView.inspectorTabs[0]
+        tab.waitForContent()
+        val emptyPanel = tab.containerPanel.getComponent(0) as EmptyStatePanel
+        assertThat(emptyPanel.reasonText).isEqualTo(AppInspectionBundle.message("app.proguarded"))
+        tabsAdded.complete(Unit)
       }
-
-      transportService.setCommandHandler(
-        Commands.Command.CommandType.APP_INSPECTION,
-        TestAppInspectorCommandHandler(
-          timer,
-          createInspectorResponse =
-            createCreateInspectorResponse(
-              AppInspection.AppInspectionResponse.Status.ERROR,
-              AppInspection.CreateInspectorResponse.Status.APP_PROGUARDED,
-              "error",
-            ),
-        ),
-      )
-
-      // Attach to a fake process.
-      transportService.addDevice(FakeTransportService.FAKE_DEVICE)
-      transportService.addProcess(
-        FakeTransportService.FAKE_DEVICE,
-        FakeTransportService.FAKE_PROCESS,
-      )
-
-      tabsAdded.join()
     }
 
+    transportService.setCommandHandler(
+      Commands.Command.CommandType.APP_INSPECTION,
+      TestAppInspectorCommandHandler(
+        timer,
+        createInspectorResponse =
+          createCreateInspectorResponse(
+            AppInspection.AppInspectionResponse.Status.ERROR,
+            AppInspection.CreateInspectorResponse.Status.APP_PROGUARDED,
+            "error",
+          ),
+      ),
+    )
+
+    // Attach to a fake process.
+    transportService.addDevice(FakeTransportService.FAKE_DEVICE)
+    transportService.addProcess(FakeTransportService.FAKE_DEVICE, FakeTransportService.FAKE_PROCESS)
+
+    tabsAdded.join()
+  }
+
   @Test
-  fun launchInspectorFailsDueToServiceError() =
-    runBlocking {
-      val tabsAdded = CompletableDeferred<Unit>()
-      launch(uiDispatcher) {
-        val inspectionView =
-          AppInspectionView(
-            projectRule.project,
-            appInspectionServiceRule.apiServices,
-            ideServices,
-            { listOf(TestAppInspectorTabProvider1()) },
-            appInspectionServiceRule.scope,
-            uiDispatcher,
-            TestInspectorArtifactService(),
-          ) {
-            it.name == FakeTransportService.FAKE_PROCESS_NAME
-          }
-        Disposer.register(disposable, inspectionView)
-        inspectionView.tabsChangedFlow.first {
-          assertThat(inspectionView.inspectorTabs.size).isEqualTo(1)
-          val tab = inspectionView.inspectorTabs[0]
-          tab.waitForContent()
-          val statePanel = tab.containerPanel.getComponent(0)
-          assertThat(statePanel).isInstanceOf(EmptyStatePanel::class.java)
-          assertThat((statePanel as EmptyStatePanel).reasonText)
-            .isEqualTo(
-              AppInspectionBundle.message("inspector.launch.error", tab.provider.displayName)
+  fun launchInspectorFailsDueToServiceError() = runBlocking {
+    val tabsAdded = CompletableDeferred<Unit>()
+    launch(uiDispatcher) {
+      val inspectionView =
+        AppInspectionView(
+          projectRule.project,
+          appInspectionServiceRule.apiServices,
+          ideServices,
+          { listOf(TestAppInspectorTabProvider1()) },
+          appInspectionServiceRule.scope,
+          uiDispatcher,
+          TestInspectorArtifactService(),
+        ) {
+          it.name == FakeTransportService.FAKE_PROCESS_NAME
+        }
+      Disposer.register(disposable, inspectionView)
+      inspectionView.tabsChangedFlow.first {
+        assertThat(inspectionView.inspectorTabs.size).isEqualTo(1)
+        val tab = inspectionView.inspectorTabs[0]
+        tab.waitForContent()
+        val statePanel = tab.containerPanel.getComponent(0)
+        assertThat(statePanel).isInstanceOf(EmptyStatePanel::class.java)
+        assertThat((statePanel as EmptyStatePanel).reasonText)
+          .isEqualTo(
+            AppInspectionBundle.message("inspector.launch.error", tab.provider.displayName)
+          )
+        tabsAdded.complete(Unit)
+      }
+    }
+
+    transportService.setCommandHandler(
+      Commands.Command.CommandType.APP_INSPECTION,
+      TestAppInspectorCommandHandler(
+        timer,
+        createInspectorResponse =
+          createCreateInspectorResponse(
+            AppInspection.AppInspectionResponse.Status.ERROR,
+            AppInspection.CreateInspectorResponse.Status.GENERIC_SERVICE_ERROR,
+            "error",
+          ),
+      ),
+    )
+
+    // Attach to a fake process.
+    transportService.addDevice(FakeTransportService.FAKE_DEVICE)
+    transportService.addProcess(FakeTransportService.FAKE_DEVICE, FakeTransportService.FAKE_PROCESS)
+
+    tabsAdded.join()
+  }
+
+  @Test
+  fun launchInspectorFailsBecauseProcessNoLongerExists() = runBlocking {
+    val tabsAdded = CompletableDeferred<Unit>()
+
+    val apiServices =
+      object : AppInspectionApiServices by appInspectionServiceRule.apiServices {
+        override suspend fun attachToProcess(
+          process: ProcessDescriptor,
+          projectName: String,
+        ): AppInspectionTarget {
+          throw AppInspectionProcessNoLongerExistsException("process no longer exists!")
+        }
+      }
+    launch(uiDispatcher) {
+      val inspectionView =
+        AppInspectionView(
+          projectRule.project,
+          apiServices,
+          ideServices,
+          { listOf(TestAppInspectorTabProvider2()) },
+          appInspectionServiceRule.scope,
+          uiDispatcher,
+          TestInspectorArtifactService(),
+        ) {
+          it.name == FakeTransportService.FAKE_PROCESS_NAME
+        }
+      Disposer.register(disposable, inspectionView)
+      inspectionView.tabsChangedFlow.first {
+        assertThat(inspectionView.inspectorTabs).isEmpty()
+        val statePanel = inspectionView.inspectorPanel.getComponent(0)
+        assertThat(statePanel).isInstanceOf(EmptyStatePanel::class.java)
+        assertThat((statePanel as EmptyStatePanel).reasonText)
+          .isEqualTo(AppInspectionBundle.message("select.process"))
+        tabsAdded.complete(Unit)
+      }
+    }
+
+    // Attach to a fake process.
+    transportService.addDevice(FakeTransportService.FAKE_DEVICE)
+    transportService.addProcess(FakeTransportService.FAKE_DEVICE, FakeTransportService.FAKE_PROCESS)
+
+    tabsAdded.join()
+  }
+
+  @Test
+  fun launchInspectorFailsDueToMissingLibrary_emptyMessageAdded() = runBlocking {
+    val tabsAdded = CompletableDeferred<Unit>()
+    val provider = TestAppInspectorTabProvider2()
+    launch(uiDispatcher) {
+      val inspectionView =
+        AppInspectionView(
+          projectRule.project,
+          appInspectionServiceRule.apiServices,
+          ideServices,
+          { listOf(provider) },
+          appInspectionServiceRule.scope,
+          uiDispatcher,
+          TestInspectorArtifactService(),
+        ) {
+          it.name == FakeTransportService.FAKE_PROCESS_NAME
+        }
+      Disposer.register(disposable, inspectionView)
+      inspectionView.tabsChangedFlow.first {
+        assertThat(inspectionView.inspectorTabs.size).isEqualTo(1)
+        val tab = inspectionView.inspectorTabs[0]
+        tab.waitForContent()
+        val emptyPanel = tab.containerPanel.getComponent(0) as EmptyStatePanel
+        assertThat(emptyPanel.reasonText)
+          .isEqualTo(
+            AppInspectionBundle.message(
+              "incompatible.version",
+              (provider.launchConfigs.single().params as LibraryInspectorLaunchParams)
+                .minVersionLibraryCoordinate
+                .toString(),
             )
-          tabsAdded.complete(Unit)
-        }
+          )
+
+        tabsAdded.complete(Unit)
       }
-
-      transportService.setCommandHandler(
-        Commands.Command.CommandType.APP_INSPECTION,
-        TestAppInspectorCommandHandler(
-          timer,
-          createInspectorResponse =
-            createCreateInspectorResponse(
-              AppInspection.AppInspectionResponse.Status.ERROR,
-              AppInspection.CreateInspectorResponse.Status.GENERIC_SERVICE_ERROR,
-              "error",
-            ),
-        ),
-      )
-
-      // Attach to a fake process.
-      transportService.addDevice(FakeTransportService.FAKE_DEVICE)
-      transportService.addProcess(
-        FakeTransportService.FAKE_DEVICE,
-        FakeTransportService.FAKE_PROCESS,
-      )
-
-      tabsAdded.join()
     }
 
-  @Test
-  fun launchInspectorFailsBecauseProcessNoLongerExists() =
-    runBlocking {
-      val tabsAdded = CompletableDeferred<Unit>()
+    transportService.setCommandHandler(
+      Commands.Command.CommandType.APP_INSPECTION,
+      TestAppInspectorCommandHandler(
+        timer,
+        createInspectorResponse =
+          createCreateInspectorResponse(
+            AppInspection.AppInspectionResponse.Status.ERROR,
+            AppInspection.CreateInspectorResponse.Status.LIBRARY_MISSING,
+            "error",
+          ),
+      ),
+    )
 
-      val apiServices =
-        object : AppInspectionApiServices by appInspectionServiceRule.apiServices {
-          override suspend fun attachToProcess(
-            process: ProcessDescriptor,
-            projectName: String,
-          ): AppInspectionTarget {
-            throw AppInspectionProcessNoLongerExistsException("process no longer exists!")
-          }
-        }
-      launch(uiDispatcher) {
-        val inspectionView =
-          AppInspectionView(
-            projectRule.project,
-            apiServices,
-            ideServices,
-            { listOf(TestAppInspectorTabProvider2()) },
-            appInspectionServiceRule.scope,
-            uiDispatcher,
-            TestInspectorArtifactService(),
-          ) {
-            it.name == FakeTransportService.FAKE_PROCESS_NAME
-          }
-        Disposer.register(disposable, inspectionView)
-        inspectionView.tabsChangedFlow.first {
-          assertThat(inspectionView.inspectorTabs).isEmpty()
-          val statePanel = inspectionView.inspectorPanel.getComponent(0)
-          assertThat(statePanel).isInstanceOf(EmptyStatePanel::class.java)
-          assertThat((statePanel as EmptyStatePanel).reasonText)
-            .isEqualTo(AppInspectionBundle.message("select.process"))
-          tabsAdded.complete(Unit)
-        }
-      }
+    // Attach to a fake process.
+    transportService.addDevice(FakeTransportService.FAKE_DEVICE)
+    transportService.addProcess(FakeTransportService.FAKE_DEVICE, FakeTransportService.FAKE_PROCESS)
 
-      // Attach to a fake process.
-      transportService.addDevice(FakeTransportService.FAKE_DEVICE)
-      transportService.addProcess(
-        FakeTransportService.FAKE_DEVICE,
-        FakeTransportService.FAKE_PROCESS,
-      )
-
-      tabsAdded.join()
-    }
-
-  @Test
-  fun launchInspectorFailsDueToMissingLibrary_emptyMessageAdded() =
-    runBlocking {
-      val tabsAdded = CompletableDeferred<Unit>()
-      val provider = TestAppInspectorTabProvider2()
-      launch(uiDispatcher) {
-        val inspectionView =
-          AppInspectionView(
-            projectRule.project,
-            appInspectionServiceRule.apiServices,
-            ideServices,
-            { listOf(provider) },
-            appInspectionServiceRule.scope,
-            uiDispatcher,
-            TestInspectorArtifactService(),
-          ) {
-            it.name == FakeTransportService.FAKE_PROCESS_NAME
-          }
-        Disposer.register(disposable, inspectionView)
-        inspectionView.tabsChangedFlow.first {
-          assertThat(inspectionView.inspectorTabs.size).isEqualTo(1)
-          val tab = inspectionView.inspectorTabs[0]
-          tab.waitForContent()
-          val emptyPanel = tab.containerPanel.getComponent(0) as EmptyStatePanel
-          assertThat(emptyPanel.reasonText)
-            .isEqualTo(
-              AppInspectionBundle.message(
-                "incompatible.version",
-                (provider.launchConfigs.single().params as LibraryInspectorLaunchParams)
-                  .minVersionLibraryCoordinate
-                  .toString(),
-              )
-            )
-
-          tabsAdded.complete(Unit)
-        }
-      }
-
-      transportService.setCommandHandler(
-        Commands.Command.CommandType.APP_INSPECTION,
-        TestAppInspectorCommandHandler(
-          timer,
-          createInspectorResponse =
-            createCreateInspectorResponse(
-              AppInspection.AppInspectionResponse.Status.ERROR,
-              AppInspection.CreateInspectorResponse.Status.LIBRARY_MISSING,
-              "error",
-            ),
-        ),
-      )
-
-      // Attach to a fake process.
-      transportService.addDevice(FakeTransportService.FAKE_DEVICE)
-      transportService.addProcess(
-        FakeTransportService.FAKE_DEVICE,
-        FakeTransportService.FAKE_PROCESS,
-      )
-
-      tabsAdded.join()
-    }
+    tabsAdded.join()
+  }
 
   @Test
   fun stopInspectionPressed_onlyOfflineInspectorsRemain() = runBlocking {
@@ -1136,140 +1115,136 @@
   }
 
   @Test
-  fun launchLibraryInspectors() =
-    runBlocking {
-      val resolvedInspector =
-        object : StubTestAppInspectorTabProvider(INSPECTOR_ID) {
-          override val inspectorLaunchParams = LibraryInspectorLaunchParams(TEST_JAR, TEST_ARTIFACT)
-        }
-      val unresolvableLibrary = mockMinimumArtifactCoordinate("unresolvable", "artifact", "1.0.0")
-      val unresolvableInspector =
-        object : StubTestAppInspectorTabProvider(INSPECTOR_ID_2) {
-          override val inspectorLaunchParams =
-            LibraryInspectorLaunchParams(TEST_JAR, unresolvableLibrary)
-        }
-      val incompatibleLibrary =
-        mockMinimumArtifactCoordinate("incompatible", "artifact", "INCOMPATIBLE")
-      val incompatibleInspector =
-        object : StubTestAppInspectorTabProvider(INSPECTOR_ID_3) {
-          override val inspectorLaunchParams =
-            LibraryInspectorLaunchParams(TEST_JAR, incompatibleLibrary)
-        }
-
-      val launchParamsVerifiedDeferred = CompletableDeferred<Unit>()
-      val apiServices =
-        object : AppInspectionApiServices by appInspectionServiceRule.apiServices {
-          override suspend fun launchInspector(params: LaunchParameters): AppInspectorMessenger {
-            // Verify the jar being launched is the one returned by resolver.
-            assertThat(params.inspectorJar.releaseDirectory)
-              .isEqualTo(Paths.get("path", "to").toString())
-            assertThat(params.inspectorJar.name).isEqualTo("inspector.jar")
-            launchParamsVerifiedDeferred.complete(Unit)
-            return appInspectionServiceRule.apiServices.launchInspector(params)
-          }
-        }
-      launch(uiDispatcher) {
-        val inspectionView =
-          AppInspectionView(
-            projectRule.project,
-            apiServices,
-            ideServices,
-            { listOf(resolvedInspector, unresolvableInspector, incompatibleInspector) },
-            appInspectionServiceRule.scope,
-            uiDispatcher,
-            object : InspectorArtifactService {
-              override suspend fun getOrResolveInspectorArtifact(
-                artifactCoordinate: RunningArtifactCoordinate,
-                project: Project,
-              ): Path {
-                return if (artifactCoordinate.groupId == "unresolvable") {
-                  throw AppInspectionArtifactNotFoundException("not resolved", artifactCoordinate)
-                } else {
-                  Paths.get("path/to/inspector.jar")
-                }
-              }
-            },
-          ) {
-            it.name == FakeTransportService.FAKE_PROCESS_NAME
-          }
-        Disposer.register(disposable, inspectionView)
-        inspectionView.tabsChangedFlow.first {
-          assertThat(inspectionView.inspectorTabs.size).isEqualTo(3)
-          inspectionView.inspectorTabs.forEach { inspectorTab ->
-            inspectorTab.waitForContent()
-            when (inspectorTab.provider) {
-              incompatibleInspector -> {
-                val emptyPanel = inspectorTab.containerPanel.getComponent(0) as EmptyStatePanel
-                assertThat(emptyPanel.reasonText)
-                  .isEqualTo(
-                    AppInspectionBundle.message(
-                      "incompatible.version",
-                      (inspectorTab.provider.launchConfigs.single().params
-                          as LibraryInspectorLaunchParams)
-                        .minVersionLibraryCoordinate
-                        .toString(),
-                    )
-                  )
-              }
-              unresolvableInspector -> {
-                val emptyPanel = inspectorTab.containerPanel.getComponent(0) as EmptyStatePanel
-                assertThat(emptyPanel.reasonText)
-                  .isEqualTo(
-                    AppInspectionBundle.message(
-                      "unresolved.inspector",
-                      (inspectorTab.provider.launchConfigs.single().params
-                          as LibraryInspectorLaunchParams)
-                        .minVersionLibraryCoordinate
-                        .toString(),
-                    )
-                  )
-              }
-              else -> {
-                // Verify it's not an info tab - it's an actual inspector tab.
-                assertThat(inspectorTab.containerPanel.getComponent(0))
-                  .isNotInstanceOf(EmptyStatePanel::class.java)
-              }
-            }
-          }
-          true
-        }
+  fun launchLibraryInspectors() = runBlocking {
+    val resolvedInspector =
+      object : StubTestAppInspectorTabProvider(INSPECTOR_ID) {
+        override val inspectorLaunchParams = LibraryInspectorLaunchParams(TEST_JAR, TEST_ARTIFACT)
+      }
+    val unresolvableLibrary = mockMinimumArtifactCoordinate("unresolvable", "artifact", "1.0.0")
+    val unresolvableInspector =
+      object : StubTestAppInspectorTabProvider(INSPECTOR_ID_2) {
+        override val inspectorLaunchParams =
+          LibraryInspectorLaunchParams(TEST_JAR, unresolvableLibrary)
+      }
+    val incompatibleLibrary =
+      mockMinimumArtifactCoordinate("incompatible", "artifact", "INCOMPATIBLE")
+    val incompatibleInspector =
+      object : StubTestAppInspectorTabProvider(INSPECTOR_ID_3) {
+        override val inspectorLaunchParams =
+          LibraryInspectorLaunchParams(TEST_JAR, incompatibleLibrary)
       }
 
-      transportService.setCommandHandler(
-        Commands.Command.CommandType.APP_INSPECTION,
-        TestAppInspectorCommandHandler(
-          timer,
-          getLibraryVersionsResponse = { command ->
-            AppInspection.GetLibraryCompatibilityInfoResponse.newBuilder()
-              .addAllResponses(
-                command.targetLibrariesList.map {
-                  val builder =
-                    AppInspection.LibraryCompatibilityInfo.newBuilder()
-                      .setTargetLibrary(it.coordinate)
-                      .setVersion(it.coordinate.version)
-                  if (it.coordinate.version == "INCOMPATIBLE") {
-                    builder.status = AppInspection.LibraryCompatibilityInfo.Status.INCOMPATIBLE
-                  } else {
-                    builder.status = AppInspection.LibraryCompatibilityInfo.Status.COMPATIBLE
-                  }
-                  builder.build()
-                }
-              )
-              .build()
+    val launchParamsVerifiedDeferred = CompletableDeferred<Unit>()
+    val apiServices =
+      object : AppInspectionApiServices by appInspectionServiceRule.apiServices {
+        override suspend fun launchInspector(params: LaunchParameters): AppInspectorMessenger {
+          // Verify the jar being launched is the one returned by resolver.
+          assertThat(params.inspectorJar.releaseDirectory)
+            .isEqualTo(Paths.get("path", "to").toString())
+          assertThat(params.inspectorJar.name).isEqualTo("inspector.jar")
+          launchParamsVerifiedDeferred.complete(Unit)
+          return appInspectionServiceRule.apiServices.launchInspector(params)
+        }
+      }
+    launch(uiDispatcher) {
+      val inspectionView =
+        AppInspectionView(
+          projectRule.project,
+          apiServices,
+          ideServices,
+          { listOf(resolvedInspector, unresolvableInspector, incompatibleInspector) },
+          appInspectionServiceRule.scope,
+          uiDispatcher,
+          object : InspectorArtifactService {
+            override suspend fun getOrResolveInspectorArtifact(
+              artifactCoordinate: RunningArtifactCoordinate,
+              project: Project,
+            ): Path {
+              return if (artifactCoordinate.groupId == "unresolvable") {
+                throw AppInspectionArtifactNotFoundException("not resolved", artifactCoordinate)
+              } else {
+                Paths.get("path/to/inspector.jar")
+              }
+            }
           },
-        ),
-      )
-
-      // Attach to a fake process.
-      transportService.addDevice(FakeTransportService.FAKE_DEVICE)
-      transportService.addProcess(
-        FakeTransportService.FAKE_DEVICE,
-        FakeTransportService.FAKE_PROCESS,
-      )
-
-      launchParamsVerifiedDeferred.await()
+        ) {
+          it.name == FakeTransportService.FAKE_PROCESS_NAME
+        }
+      Disposer.register(disposable, inspectionView)
+      inspectionView.tabsChangedFlow.first {
+        assertThat(inspectionView.inspectorTabs.size).isEqualTo(3)
+        inspectionView.inspectorTabs.forEach { inspectorTab ->
+          inspectorTab.waitForContent()
+          when (inspectorTab.provider) {
+            incompatibleInspector -> {
+              val emptyPanel = inspectorTab.containerPanel.getComponent(0) as EmptyStatePanel
+              assertThat(emptyPanel.reasonText)
+                .isEqualTo(
+                  AppInspectionBundle.message(
+                    "incompatible.version",
+                    (inspectorTab.provider.launchConfigs.single().params
+                        as LibraryInspectorLaunchParams)
+                      .minVersionLibraryCoordinate
+                      .toString(),
+                  )
+                )
+            }
+            unresolvableInspector -> {
+              val emptyPanel = inspectorTab.containerPanel.getComponent(0) as EmptyStatePanel
+              assertThat(emptyPanel.reasonText)
+                .isEqualTo(
+                  AppInspectionBundle.message(
+                    "unresolved.inspector",
+                    (inspectorTab.provider.launchConfigs.single().params
+                        as LibraryInspectorLaunchParams)
+                      .minVersionLibraryCoordinate
+                      .toString(),
+                  )
+                )
+            }
+            else -> {
+              // Verify it's not an info tab - it's an actual inspector tab.
+              assertThat(inspectorTab.containerPanel.getComponent(0))
+                .isNotInstanceOf(EmptyStatePanel::class.java)
+            }
+          }
+        }
+        true
+      }
     }
 
+    transportService.setCommandHandler(
+      Commands.Command.CommandType.APP_INSPECTION,
+      TestAppInspectorCommandHandler(
+        timer,
+        getLibraryVersionsResponse = { command ->
+          AppInspection.GetLibraryCompatibilityInfoResponse.newBuilder()
+            .addAllResponses(
+              command.targetLibrariesList.map {
+                val builder =
+                  AppInspection.LibraryCompatibilityInfo.newBuilder()
+                    .setTargetLibrary(it.coordinate)
+                    .setVersion(it.coordinate.version)
+                if (it.coordinate.version == "INCOMPATIBLE") {
+                  builder.status = AppInspection.LibraryCompatibilityInfo.Status.INCOMPATIBLE
+                } else {
+                  builder.status = AppInspection.LibraryCompatibilityInfo.Status.COMPATIBLE
+                }
+                builder.build()
+              }
+            )
+            .build()
+        },
+      ),
+    )
+
+    // Attach to a fake process.
+    transportService.addDevice(FakeTransportService.FAKE_DEVICE)
+    transportService.addProcess(FakeTransportService.FAKE_DEVICE, FakeTransportService.FAKE_PROCESS)
+
+    launchParamsVerifiedDeferred.await()
+  }
+
   @Test
   fun appInspectionView_canToggleAutoConnectedState() = runBlocking {
     val inspectionView =
diff --git a/app-inspection/ide/testSrc/com/android/tools/idea/appinspection/ide/ui/AppInspectionToolWindowManagerListenerTest.kt b/app-inspection/ide/testSrc/com/android/tools/idea/appinspection/ide/ui/AppInspectionToolWindowManagerListenerTest.kt
index 2304f17..b1cb601 100644
--- a/app-inspection/ide/testSrc/com/android/tools/idea/appinspection/ide/ui/AppInspectionToolWindowManagerListenerTest.kt
+++ b/app-inspection/ide/testSrc/com/android/tools/idea/appinspection/ide/ui/AppInspectionToolWindowManagerListenerTest.kt
@@ -25,6 +25,7 @@
 import com.android.tools.idea.transport.faketransport.FakeTransportService
 import com.android.tools.profiler.proto.Commands
 import com.google.common.truth.Truth.assertThat
+import com.intellij.openapi.actionSystem.AnAction
 import com.intellij.openapi.application.EDT
 import com.intellij.openapi.project.Project
 import com.intellij.openapi.util.Disposer
@@ -95,7 +96,7 @@
         content: String,
         title: String,
         severity: AppInspectionIdeServices.Severity,
-        hyperlinkClicked: () -> Unit,
+        action: AnAction?,
       ) {
         notificationText = content
       }
diff --git a/app-inspection/inspector/api/src/com/android/tools/idea/appinspection/inspector/api/AppInspectionIdeServices.kt b/app-inspection/inspector/api/src/com/android/tools/idea/appinspection/inspector/api/AppInspectionIdeServices.kt
index 77bbe6d..a07c8c2 100644
--- a/app-inspection/inspector/api/src/com/android/tools/idea/appinspection/inspector/api/AppInspectionIdeServices.kt
+++ b/app-inspection/inspector/api/src/com/android/tools/idea/appinspection/inspector/api/AppInspectionIdeServices.kt
@@ -16,6 +16,7 @@
 package com.android.tools.idea.appinspection.inspector.api
 
 import com.android.annotations.concurrency.UiThread
+import com.intellij.openapi.actionSystem.AnAction
 
 /**
  * A set of utility methods used for communicating requests to the IDE.
@@ -50,7 +51,7 @@
     content: String,
     title: String = "",
     severity: Severity = Severity.INFORMATION,
-    @UiThread hyperlinkClicked: () -> Unit = {},
+    action: AnAction? = null,
   )
 
   class CodeLocation
@@ -87,7 +88,7 @@
     content: String,
     title: String,
     severity: AppInspectionIdeServices.Severity,
-    hyperlinkClicked: () -> Unit,
+    action: AnAction?,
   ) {}
 
   override suspend fun navigateTo(codeLocation: AppInspectionIdeServices.CodeLocation) {}
diff --git a/app-inspection/inspectors/database/resources/messages/DatabaseInspectorBundle.properties b/app-inspection/inspectors/database/resources/messages/DatabaseInspectorBundle.properties
index 7bd454a..1a59ef9 100644
--- a/app-inspection/inspectors/database/resources/messages/DatabaseInspectorBundle.properties
+++ b/app-inspection/inspectors/database/resources/messages/DatabaseInspectorBundle.properties
@@ -27,7 +27,6 @@
 export.progress.dialog.title=Exporting
 export.progress.dialog.caption=Exporting data...
 export.notification.success.title=<b>Data exported</b>
-export.notification.success.message.reveal=<a href=reveal>{0}</a>
 export.notification.error.title=<b>Issue while exporting data</b>
 export.dialog.file.type.db=DB
 export.dialog.file.type.sql=SQL
diff --git a/app-inspection/inspectors/database/src/com/android/tools/idea/sqlite/controllers/DatabaseInspectorController.kt b/app-inspection/inspectors/database/src/com/android/tools/idea/sqlite/controllers/DatabaseInspectorController.kt
index b8417a7..c6e8c0c 100644
--- a/app-inspection/inspectors/database/src/com/android/tools/idea/sqlite/controllers/DatabaseInspectorController.kt
+++ b/app-inspection/inspectors/database/src/com/android/tools/idea/sqlite/controllers/DatabaseInspectorController.kt
@@ -67,6 +67,7 @@
 import com.google.wireless.android.sdk.stats.AppInspectionEvent
 import com.intellij.ide.actions.RevealFileAction
 import com.intellij.openapi.Disposable
+import com.intellij.openapi.actionSystem.AnActionEvent
 import com.intellij.openapi.application.invokeAndWaitIfNeeded
 import com.intellij.openapi.diagnostic.thisLogger
 import com.intellij.openapi.project.Project
@@ -747,16 +748,17 @@
         notifyExportComplete = { request ->
           appInspectionIdeServices?.showNotification( // TODO(161081452):  replace with a Toast
             title = DatabaseInspectorBundle.message("export.notification.success.title"),
-            content =
+            content = "",
+            action =
               when (RevealFileAction.isSupported()) {
                 true ->
-                  DatabaseInspectorBundle.message(
-                    "export.notification.success.message.reveal",
-                    RevealFileAction.getActionName(),
-                  )
-                else -> ""
+                  object : RevealFileAction() {
+                    override fun actionPerformed(e: AnActionEvent) {
+                      openFile(request.dstPath)
+                    }
+                  }
+                false -> null
               },
-            hyperlinkClicked = { RevealFileAction.openFile(request.dstPath) },
           )
         },
         notifyExportError = { _, throwable ->
diff --git a/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/TestNetworkInspectorServices.kt b/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/TestNetworkInspectorServices.kt
index 94a80aa..475cb01 100644
--- a/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/TestNetworkInspectorServices.kt
+++ b/app-inspection/inspectors/network/model/testSrc/com/android/tools/idea/appinspection/inspectors/network/model/TestNetworkInspectorServices.kt
@@ -21,6 +21,7 @@
 import com.android.tools.idea.appinspection.inspectors.network.model.analytics.NetworkInspectorTracker
 import com.android.tools.idea.appinspection.inspectors.network.model.analytics.StubNetworkInspectorTracker
 import com.google.common.util.concurrent.MoreExecutors
+import com.intellij.openapi.actionSystem.AnAction
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.asCoroutineDispatcher
 import studio.network.inspection.NetworkInspectorProtocol
@@ -52,7 +53,7 @@
         content: String,
         title: String,
         severity: AppInspectionIdeServices.Severity,
-        hyperlinkClicked: () -> Unit,
+        action: AnAction?,
       ) {
         TODO("Not yet implemented")
       }
