diff --git a/package-lock.json b/package-lock.json
index 00125520..db19d990 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,8 +13,8 @@
                 "@azure/arm-resources-profile-2020-09-01-hybrid": "^2.1.0",
                 "@azure/ms-rest-js": "^2.7.0",
                 "@microsoft/vscode-azext-azureauth": "^4.0.3",
-                "@microsoft/vscode-azext-azureutils": "^3.1.4",
-                "@microsoft/vscode-azext-utils": "^2.6.3",
+                "@microsoft/vscode-azext-azureutils": "^3.2.0",
+                "@microsoft/vscode-azext-utils": "^3.0.1",
                 "buffer": "^6.0.3",
                 "form-data": "^4.0.1",
                 "jsonc-parser": "^2.2.1",
@@ -1047,9 +1047,9 @@
             }
         },
         "node_modules/@microsoft/vscode-azext-azureutils": {
-            "version": "3.1.4",
-            "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-azureutils/-/vscode-azext-azureutils-3.1.4.tgz",
-            "integrity": "sha512-hExl+AL4lpBZ++ejSyuvpxLurGcRgIQVAC8UfWLZnPWqdfUrW9sAqpjrZBjOSpQ72Jr/E+3GnB2lVW7U1T5J2w==",
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-azureutils/-/vscode-azext-azureutils-3.2.0.tgz",
+            "integrity": "sha512-GiEMWjtzAo3Lrg1t02rPQa/OEDAj35PguFQEk3N5QoBubezK38oL5QNJDe2IxAvYniZwNU+XfjHxdFZtI2+PUA==",
             "dependencies": {
                 "@azure/arm-authorization": "^9.0.0",
                 "@azure/arm-authorization-profile-2020-09-01-hybrid": "^2.1.0",
@@ -1062,7 +1062,7 @@
                 "@azure/core-client": "^1.6.0",
                 "@azure/core-rest-pipeline": "^1.9.0",
                 "@azure/logger": "^1.0.4",
-                "@microsoft/vscode-azext-utils": "^2.5.14",
+                "@microsoft/vscode-azext-utils": "^3.0.0",
                 "semver": "^7.3.7",
                 "uuid": "^9.0.0"
             },
@@ -1172,10 +1172,9 @@
             }
         },
         "node_modules/@microsoft/vscode-azext-utils": {
-            "version": "2.6.3",
-            "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-utils/-/vscode-azext-utils-2.6.3.tgz",
-            "integrity": "sha512-eogbgZH1KQkGWstl9qb1Tq4DQH+JJCHLHZelIbnzIKE8JKxr8Et/byn3OuL5nL1qeITQQn3+AYVsbj2hbljM7w==",
-            "license": "MIT",
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-utils/-/vscode-azext-utils-3.0.1.tgz",
+            "integrity": "sha512-eO0tueSQqKn8GOUzFdNvNGF9aSjnQwS2xUftBv4BH3m6s18sAtViBgwVH/+k7aAjUBhqlkSwZNJOzf4A18L1/A==",
             "dependencies": {
                 "@microsoft/vscode-azureresources-api": "^2.3.1",
                 "@vscode/extension-telemetry": "^0.9.6",
@@ -11010,9 +11009,9 @@
             }
         },
         "@microsoft/vscode-azext-azureutils": {
-            "version": "3.1.4",
-            "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-azureutils/-/vscode-azext-azureutils-3.1.4.tgz",
-            "integrity": "sha512-hExl+AL4lpBZ++ejSyuvpxLurGcRgIQVAC8UfWLZnPWqdfUrW9sAqpjrZBjOSpQ72Jr/E+3GnB2lVW7U1T5J2w==",
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-azureutils/-/vscode-azext-azureutils-3.2.0.tgz",
+            "integrity": "sha512-GiEMWjtzAo3Lrg1t02rPQa/OEDAj35PguFQEk3N5QoBubezK38oL5QNJDe2IxAvYniZwNU+XfjHxdFZtI2+PUA==",
             "requires": {
                 "@azure/arm-authorization": "^9.0.0",
                 "@azure/arm-authorization-profile-2020-09-01-hybrid": "^2.1.0",
@@ -11025,7 +11024,7 @@
                 "@azure/core-client": "^1.6.0",
                 "@azure/core-rest-pipeline": "^1.9.0",
                 "@azure/logger": "^1.0.4",
-                "@microsoft/vscode-azext-utils": "^2.5.14",
+                "@microsoft/vscode-azext-utils": "^3.0.0",
                 "semver": "^7.3.7",
                 "uuid": "^9.0.0"
             }
@@ -11111,9 +11110,9 @@
             }
         },
         "@microsoft/vscode-azext-utils": {
-            "version": "2.6.3",
-            "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-utils/-/vscode-azext-utils-2.6.3.tgz",
-            "integrity": "sha512-eogbgZH1KQkGWstl9qb1Tq4DQH+JJCHLHZelIbnzIKE8JKxr8Et/byn3OuL5nL1qeITQQn3+AYVsbj2hbljM7w==",
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/@microsoft/vscode-azext-utils/-/vscode-azext-utils-3.0.1.tgz",
+            "integrity": "sha512-eO0tueSQqKn8GOUzFdNvNGF9aSjnQwS2xUftBv4BH3m6s18sAtViBgwVH/+k7aAjUBhqlkSwZNJOzf4A18L1/A==",
             "requires": {
                 "@microsoft/vscode-azureresources-api": "^2.3.1",
                 "@vscode/extension-telemetry": "^0.9.6",
diff --git a/package.json b/package.json
index 88f7c5d5..320a445a 100644
--- a/package.json
+++ b/package.json
@@ -914,8 +914,8 @@
         "@azure/arm-resources-profile-2020-09-01-hybrid": "^2.1.0",
         "@azure/ms-rest-js": "^2.7.0",
         "@microsoft/vscode-azext-azureauth": "^4.0.3",
-        "@microsoft/vscode-azext-azureutils": "^3.1.4",
-        "@microsoft/vscode-azext-utils": "^2.6.3",
+        "@microsoft/vscode-azext-azureutils": "^3.2.0",
+        "@microsoft/vscode-azext-utils": "^3.0.1",
         "buffer": "^6.0.3",
         "form-data": "^4.0.1",
         "jsonc-parser": "^2.2.1",
diff --git a/src/activityLog/ActivityLogsTreeItem.ts b/src/activityLog/ActivityLogsTreeItem.ts
deleted file mode 100644
index cdfb1326..00000000
--- a/src/activityLog/ActivityLogsTreeItem.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- *  Copyright (c) Microsoft Corporation. All rights reserved.
- *  Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-import { AzExtParentTreeItem, AzExtTreeItem, callWithTelemetryAndErrorHandling, IActionContext } from '@microsoft/vscode-azext-utils';
-import { Activity } from '@microsoft/vscode-azext-utils/hostapi';
-import { commands, Disposable } from 'vscode';
-import { localize } from '../utils/localize';
-import { settingUtils } from '../utils/settingUtils';
-import { ActivityStatus, ActivityTreeItem } from './ActivityTreeItem';
-
-export class ActivityLogTreeItem extends AzExtParentTreeItem implements Disposable {
-    public label: string = localize('activityLog', 'Activity Log');
-    public contextValue: string = 'azureActivityLog';
-
-    private activityTreeItems: Record<string, ActivityTreeItem> = {};
-
-    public constructor() {
-        super(undefined);
-    }
-
-    public dispose(): void {
-        Object.values(this.activityTreeItems).forEach((activity: ActivityTreeItem) => {
-            activity.dispose();
-        });
-    }
-
-    public async addActivity(activity: Activity): Promise<void> {
-        await callWithTelemetryAndErrorHandling('registerActivity', async (context: IActionContext) => {
-            this.activityTreeItems[activity.id] = new ActivityTreeItem(this, activity);
-            if ((await settingUtils.getWorkspaceSetting('autoOpenActivityPanel'))) {
-                await commands.executeCommand('azureActivityLog.focus');
-            }
-            await this.refresh(context);
-        });
-    }
-
-    public async clearActivities(context: IActionContext): Promise<void> {
-        Object.entries(this.activityTreeItems).forEach(([id, activity]: [string, ActivityTreeItem]) => {
-            if (activity.status === ActivityStatus.Done) {
-                activity.dispose();
-                delete this.activityTreeItems[id];
-            }
-        });
-        await this.refresh(context);
-    }
-
-    public async loadMoreChildrenImpl(_clearCache: boolean, _context: IActionContext): Promise<AzExtTreeItem[]> {
-        // no status means activity hasn't started yet
-        return Object.values(this.activityTreeItems).filter((activity) => !!activity.status);
-    }
-
-    public compareChildrenImpl(item1: ActivityTreeItem, item2: ActivityTreeItem): number {
-        return item1.startedAtMs - item2.startedAtMs;
-    }
-
-    public hasMoreChildrenImpl(): boolean {
-        return false;
-    }
-}
diff --git a/src/api/ResourceProviderManagers.ts b/src/api/ResourceProviderManagers.ts
index c1f9efba..12cc9d18 100644
--- a/src/api/ResourceProviderManagers.ts
+++ b/src/api/ResourceProviderManagers.ts
@@ -91,3 +91,6 @@ export class WorkspaceResourceProviderManager extends ResourceProviderManager<vo
 
 export class TenantResourceProviderManager extends ResourceProviderManager<void, TenantResource, TenantResourceProvider> {
 }
+
+export class ActivityLogResourceProviderManager extends ResourceProviderManager<void, ResourceBase, ResourceProvider<void, ResourceBase>> {
+}
diff --git a/src/api/compatibility/pickAppResource.ts b/src/api/compatibility/pickAppResource.ts
index 131d2175..eef6c396 100644
--- a/src/api/compatibility/pickAppResource.ts
+++ b/src/api/compatibility/pickAppResource.ts
@@ -5,6 +5,7 @@
 
 import { AzExtTreeItem, ContextValueFilter, ITreeItemPickerContext, PickTreeItemWithCompatibility } from "@microsoft/vscode-azext-utils";
 import { PickAppResourceOptions } from "@microsoft/vscode-azext-utils/hostapi";
+import { TelemetryTrustedValue } from "vscode";
 import { AzExtResourceType, getAzExtResourceType } from "../../../api/src/index";
 import { ext } from "../../extensionVariables";
 
@@ -18,7 +19,7 @@ export function createCompatibilityPickAppResource() {
             childItemFilter: convertExpectedChildContextValueToContextValueFilter(options?.expectedChildContextValue)
         });
 
-        context.telemetry.properties.resourceId = result.id;
+        context.telemetry.properties.resourceId = result.id ? new TelemetryTrustedValue(result.id) : undefined;
 
         try {
             // AzExtTreeItems throw when subscription is undefined. It's unlikely to happen here, but better safe than sorry.
diff --git a/src/commands/activities/clearActivities.ts b/src/commands/activities/clearActivities.ts
index 71a118a0..3a37d2ef 100644
--- a/src/commands/activities/clearActivities.ts
+++ b/src/commands/activities/clearActivities.ts
@@ -7,5 +7,5 @@ import { IActionContext } from "@microsoft/vscode-azext-utils";
 import { ext } from "../../extensionVariables";
 
 export async function clearActivities(context: IActionContext): Promise<void> {
-    await ext.activityLogTreeItem.clearActivities(context);
+    await ext.activityLogTree.clearActivities(context);
 }
diff --git a/src/activityLog/registerActivity.ts b/src/commands/activities/registerActivity.ts
similarity index 82%
rename from src/activityLog/registerActivity.ts
rename to src/commands/activities/registerActivity.ts
index 5d5dc682..7825bbdf 100644
--- a/src/activityLog/registerActivity.ts
+++ b/src/commands/activities/registerActivity.ts
@@ -4,8 +4,8 @@
 *--------------------------------------------------------------------------------------------*/
 
 import { Activity } from "@microsoft/vscode-azext-utils/hostapi";
-import { ext } from "../extensionVariables";
+import { ext } from "../../extensionVariables";
 
 export async function registerActivity(activity: Activity): Promise<void> {
-    await ext.activityLogTreeItem.addActivity(activity);
+    await ext.activityLogTree.addActivity(activity);
 }
diff --git a/src/commands/activities/registerActivityLogTree.ts b/src/commands/activities/registerActivityLogTree.ts
new file mode 100644
index 00000000..9eaf6be9
--- /dev/null
+++ b/src/commands/activities/registerActivityLogTree.ts
@@ -0,0 +1,44 @@
+/*---------------------------------------------------------------------------------------------
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Licensed under the MIT License. See License.md in the project root for license information.
+*--------------------------------------------------------------------------------------------*/
+
+import { AzExtTreeItem } from "@microsoft/vscode-azext-utils";
+import { Event, ExtensionContext, TreeView } from "vscode";
+import { ActivityLogResourceProviderManager } from "../../api/ResourceProviderManagers";
+import { ext } from "../../extensionVariables";
+import { ActivityLogTreeDataProvider } from "../../tree/activityLog/ActivityLogBranchDataProvider";
+import { ActivityLogResourceBranchDataProviderManager } from "../../tree/activityLog/ActivityLogBranchDataProviderManager";
+import { BranchDataItemCache } from "../../tree/BranchDataItemCache";
+import { createTreeView } from "../../tree/createTreeView";
+import { TreeDataItem } from "../../tree/ResourceGroupsItem";
+import { wrapTreeForVSCode } from "../../tree/wrapTreeForVSCode";
+import { localize } from "../../utils/localize";
+
+interface RegisterActivityLogTreeOptions {
+    activityLogResourceBranchDataProviderManager: ActivityLogResourceBranchDataProviderManager,
+    activityLogResourceProviderManager: ActivityLogResourceProviderManager,
+    refreshEvent: Event<void | TreeDataItem | TreeDataItem[] | null | undefined>,
+}
+
+export function registerActivityLogTree(context: ExtensionContext, options: RegisterActivityLogTreeOptions): ActivityLogTreeDataProvider {
+    const { activityLogResourceBranchDataProviderManager, activityLogResourceProviderManager, refreshEvent } = options;
+
+    const branchItemCache = new BranchDataItemCache();
+    const activityLogTreeDataProvider =
+        new ActivityLogTreeDataProvider(activityLogResourceBranchDataProviderManager, refreshEvent, activityLogResourceProviderManager, branchItemCache);
+    context.subscriptions.push(activityLogTreeDataProvider);
+
+    const treeView = createTreeView('azureActivityLog', {
+        canSelectMany: true,
+        showCollapseAll: true,
+        itemCache: branchItemCache,
+        title: localize('activityLog', 'Activity Log'),
+        treeDataProvider: wrapTreeForVSCode(activityLogTreeDataProvider, branchItemCache),
+        findItemById: activityLogTreeDataProvider.findItemById.bind(activityLogTreeDataProvider) as typeof activityLogTreeDataProvider.findItemById,
+    });
+    context.subscriptions.push(treeView);
+    ext.activityLogTreeView = treeView as unknown as TreeView<AzExtTreeItem>;
+
+    return activityLogTreeDataProvider;
+}
diff --git a/src/commands/registerCommands.ts b/src/commands/registerCommands.ts
index 0b4203fd..f486ae2f 100644
--- a/src/commands/registerCommands.ts
+++ b/src/commands/registerCommands.ts
@@ -74,6 +74,10 @@ export function registerCommands(): void {
         ext.actions.refreshTenantTree(node);
     });
 
+    registerCommand('azureActivityLogView.refresh', async (_context, node?: ResourceGroupsItem) => {
+        ext.actions.refreshActivityLogTree(node);
+    });
+
     registerCommand('azureTenantsView.signInToTenant', async (_context, node: TenantTreeItem) => {
         await (await ext.subscriptionProviderFactory()).signIn(node.tenantId, node.account);
         ext.actions.refreshTenantTree(node);
diff --git a/src/commands/revealResource.ts b/src/commands/revealResource.ts
index af179c4d..77809dac 100644
--- a/src/commands/revealResource.ts
+++ b/src/commands/revealResource.ts
@@ -7,14 +7,14 @@ import { ParsedAzureResourceId } from '@microsoft/vscode-azext-azureutils';
 import { AzExtTreeItem, IActionContext, maskUserInfo, parseError } from '@microsoft/vscode-azext-utils';
 import { VSCodeRevealOptions } from '../../api/src/index';
 import { ext } from '../extensionVariables';
-import { ResourceGroupsItem } from '../tree/ResourceGroupsItem';
+import { TreeDataItem } from '../tree/ResourceGroupsItem';
 import { ResourceTreeDataProviderBase } from '../tree/ResourceTreeDataProviderBase';
 
 export async function revealResource(context: IActionContext, resourceId: string, options?: VSCodeRevealOptions): Promise<void> {
     setTelemetryPropertiesForId(context, resourceId);
 
     try {
-        const item: ResourceGroupsItem | undefined = await (ext.v2.api.resources.azureResourceTreeDataProvider as ResourceTreeDataProviderBase).findItemById(resourceId);
+        const item: TreeDataItem | undefined = await (ext.v2.api.resources.azureResourceTreeDataProvider as ResourceTreeDataProviderBase).findItemById(resourceId);
         if (item) {
             await ext.appResourceTreeView.reveal(item as unknown as AzExtTreeItem, options ?? { expand: false, focus: true, select: true });
         }
diff --git a/src/extension.ts b/src/extension.ts
index c6092a49..50b29c6f 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -11,11 +11,9 @@ import { AzureSubscription } from 'api/src';
 import { GetApiOptions, apiUtils } from 'api/src/utils/apiUtils';
 import * as vscode from 'vscode';
 import { AzExtResourceType } from '../api/src/AzExtResourceType';
-import { ActivityLogTreeItem } from './activityLog/ActivityLogsTreeItem';
-import { registerActivity } from './activityLog/registerActivity';
 import { DefaultAzureResourceProvider } from './api/DefaultAzureResourceProvider';
 import { ResourceGroupsExtensionManager } from './api/ResourceGroupsExtensionManager';
-import { AzureResourceProviderManager, TenantResourceProviderManager, WorkspaceResourceProviderManager } from './api/ResourceProviderManagers';
+import { ActivityLogResourceProviderManager, AzureResourceProviderManager, TenantResourceProviderManager, WorkspaceResourceProviderManager } from './api/ResourceProviderManagers';
 import { InternalAzureResourceGroupsExtensionApi } from './api/compatibility/AzureResourceGroupsExtensionApi';
 import { CompatibleAzExtTreeDataProvider } from './api/compatibility/CompatibleAzExtTreeDataProvider';
 import { createCompatibilityPickAppResource } from './api/compatibility/pickAppResource';
@@ -25,6 +23,8 @@ import { createAzureResourcesHostApi } from './api/createAzureResourcesHostApi';
 import { createWrappedAzureResourcesExtensionApi } from './api/createWrappedAzureResourcesExtensionApi';
 import { registerChatStandInParticipantIfNeeded } from './chat/chatStandIn';
 import { createCloudConsole } from './cloudConsole/cloudConsole';
+import { registerActivity } from './commands/activities/registerActivity';
+import { registerActivityLogTree } from './commands/activities/registerActivityLogTree';
 import { registerCommands } from './commands/registerCommands';
 import { TagFileSystem } from './commands/tags/TagFileSystem';
 import { registerTagDiagnostics } from './commands/tags/registerTagDiagnostics';
@@ -35,7 +35,9 @@ import { survey } from './nps';
 import { getSubscriptionProviderFactory } from './services/getSubscriptionProviderFactory';
 import { BranchDataItemCache } from './tree/BranchDataItemCache';
 import { HelpTreeItem } from './tree/HelpTreeItem';
-import { ResourceGroupsItem } from './tree/ResourceGroupsItem';
+import { TreeDataItem } from './tree/ResourceGroupsItem';
+import { ActivityLogResourceBranchDataProviderManager } from './tree/activityLog/ActivityLogBranchDataProviderManager';
+import { ActivityLogDefaultBranchDataProvider } from './tree/activityLog/ActivityLogDefaultBranchDataProvider';
 import { AzureResourceBranchDataProviderManager } from './tree/azure/AzureResourceBranchDataProviderManager';
 import { DefaultAzureResourceBranchDataProvider } from './tree/azure/DefaultAzureResourceBranchDataProvider';
 import { registerAzureTree } from './tree/azure/registerAzureTree';
@@ -61,19 +63,22 @@ export async function activate(context: vscode.ExtensionContext, perfStats: { lo
     registerUIExtensionVariables(ext);
     registerAzureUtilsExtensionVariables(ext);
 
-    const refreshAzureTreeEmitter = new vscode.EventEmitter<void | ResourceGroupsItem | ResourceGroupsItem[] | null | undefined>();
+    const refreshAzureTreeEmitter = new vscode.EventEmitter<void | TreeDataItem | TreeDataItem[] | null | undefined>();
     context.subscriptions.push(refreshAzureTreeEmitter);
-    const refreshFocusTreeEmitter = new vscode.EventEmitter<void | ResourceGroupsItem | ResourceGroupsItem[] | null | undefined>();
+    const refreshFocusTreeEmitter = new vscode.EventEmitter<void | TreeDataItem | TreeDataItem[] | null | undefined>();
     context.subscriptions.push(refreshFocusTreeEmitter);
-    const refreshWorkspaceTreeEmitter = new vscode.EventEmitter<void | ResourceGroupsItem | ResourceGroupsItem[] | null | undefined>();
+    const refreshWorkspaceTreeEmitter = new vscode.EventEmitter<void | TreeDataItem | TreeDataItem[] | null | undefined>();
     context.subscriptions.push(refreshWorkspaceTreeEmitter);
-    const refreshTenantTreeEmitter = new vscode.EventEmitter<void | ResourceGroupsItem | ResourceGroupsItem[] | null | undefined>();
+    const refreshTenantTreeEmitter = new vscode.EventEmitter<void | TreeDataItem | TreeDataItem[] | null | undefined>();
     context.subscriptions.push(refreshTenantTreeEmitter);
+    const refreshActivityLogTreeEmitter = new vscode.EventEmitter<void | TreeDataItem | TreeDataItem[] | null | undefined>();
+    context.subscriptions.push(refreshActivityLogTreeEmitter);
 
     ext.actions.refreshWorkspaceTree = (data) => refreshWorkspaceTreeEmitter.fire(data);
     ext.actions.refreshAzureTree = (data) => refreshAzureTreeEmitter.fire(data);
     ext.actions.refreshFocusTree = (data) => refreshFocusTreeEmitter.fire(data);
     ext.actions.refreshTenantTree = (data) => refreshTenantTreeEmitter.fire(data);
+    ext.actions.refreshActivityLogTree = (data) => refreshActivityLogTreeEmitter.fire(data);
 
     await callWithTelemetryAndErrorHandling('azureResourceGroups.activate', async (activateContext: IActionContext) => {
         activateContext.telemetry.properties.isActivationEvent = 'true';
@@ -92,10 +97,6 @@ export async function activate(context: vscode.ExtensionContext, perfStats: { lo
         ext.helpTree = new AzExtTreeDataProvider(helpTreeItem, 'ms-azuretools.loadMore');
         context.subscriptions.push(vscode.window.createTreeView('ms-azuretools.helpAndFeedback', { treeDataProvider: ext.helpTree }));
 
-        context.subscriptions.push(ext.activityLogTreeItem = new ActivityLogTreeItem());
-        ext.activityLogTree = new AzExtTreeDataProvider(ext.activityLogTreeItem, 'azureActivityLog.loadMore');
-        context.subscriptions.push(vscode.window.createTreeView('azureActivityLog', { treeDataProvider: ext.activityLogTree }));
-
         context.subscriptions.push(vscode.window.registerTerminalProfileProvider('azureResourceGroups.cloudShellBash', {
             provideTerminalProfile: async (token: vscode.CancellationToken) => {
                 return createCloudConsole(await ext.subscriptionProviderFactory(), 'Linux', token).terminalProfile;
@@ -129,6 +130,8 @@ export async function activate(context: vscode.ExtensionContext, perfStats: { lo
         new WorkspaceDefaultBranchDataProvider(),
         type => void extensionManager.activateWorkspaceResourceBranchDataProvider(type));
     const workspaceResourceProviderManager = new WorkspaceResourceProviderManager(() => extensionManager.activateWorkspaceResourceProviders());
+    const activityLogResourceBranchDataProviderManager = new ActivityLogResourceBranchDataProviderManager(new ActivityLogDefaultBranchDataProvider());
+    const activityLogResourceProviderManager = new ActivityLogResourceProviderManager(async () => { return undefined });
 
     const tenantResourceBranchDataProviderManager = new TenantResourceBranchDataProviderManager(
         new TenantDefaultBranchDataProvider());
@@ -161,7 +164,13 @@ export async function activate(context: vscode.ExtensionContext, perfStats: { lo
         tenantResourceBranchDataProviderManager,
         refreshEvent: refreshTenantTreeEmitter.event,
         itemCache: tenantResourcesBranchDataItemCache
-    })
+    });
+
+    ext.activityLogTree = registerActivityLogTree(context, {
+        activityLogResourceProviderManager,
+        activityLogResourceBranchDataProviderManager,
+        refreshEvent: refreshActivityLogTreeEmitter.event
+    });
 
     const v2ApiFactory: AzureExtensionApiFactory<AzureResourcesApiInternal> = {
         apiVersion: '2.0.0',
diff --git a/src/extensionVariables.ts b/src/extensionVariables.ts
index b5cef384..e1ef7ddd 100644
--- a/src/extensionVariables.ts
+++ b/src/extensionVariables.ts
@@ -7,20 +7,21 @@ import { AzureSubscriptionProvider } from "@microsoft/vscode-azext-azureauth";
 import { AzExtTreeDataProvider, IAzExtLogOutputChannel, IExperimentationServiceAdapter } from "@microsoft/vscode-azext-utils";
 import { AzExtResourceType } from "api/src/AzExtResourceType";
 import { DiagnosticCollection, Disposable, ExtensionContext, TreeView } from "vscode";
-import { ActivityLogTreeItem } from "./activityLog/ActivityLogsTreeItem";
 import { TagFileSystem } from "./commands/tags/TagFileSystem";
 import { AzureResourcesApiInternal } from "./hostapi.v2.internal";
 import { ManagedIdentityBranchDataProvider } from "./managedIdentity/ManagedIdentityBranchDataProvider";
 import { AzureResourcesServiceFactory } from "./services/AzureResourcesService";
-import { ResourceGroupsItem } from "./tree/ResourceGroupsItem";
+import { TreeDataItem } from "./tree/ResourceGroupsItem";
 import { TreeItemStateStore } from "./tree/TreeItemState";
+import { ActivityLogTreeDataProvider } from "./tree/activityLog/ActivityLogBranchDataProvider";
 import { FocusViewTreeDataProvider } from "./tree/azure/FocusViewTreeDataProvider";
 
 export namespace extActions {
-    export let refreshWorkspaceTree: (data?: ResourceGroupsItem | ResourceGroupsItem[] | null | undefined | void) => void;
-    export let refreshAzureTree: (data?: ResourceGroupsItem | ResourceGroupsItem[] | null | undefined | void) => void;
-    export let refreshFocusTree: (data?: ResourceGroupsItem | ResourceGroupsItem[] | null | undefined | void) => void;
-    export let refreshTenantTree: (data?: ResourceGroupsItem | ResourceGroupsItem[] | null | undefined | void) => void;
+    export let refreshWorkspaceTree: (data?: TreeDataItem | TreeDataItem[] | null | undefined | void) => void;
+    export let refreshAzureTree: (data?: TreeDataItem | TreeDataItem[] | null | undefined | void) => void;
+    export let refreshFocusTree: (data?: TreeDataItem | TreeDataItem[] | null | undefined | void) => void;
+    export let refreshTenantTree: (data?: TreeDataItem | TreeDataItem[] | null | undefined | void) => void;
+    export let refreshActivityLogTree: (data?: TreeDataItem | TreeDataItem[] | null | undefined | void) => void;
 }
 
 /**
@@ -35,8 +36,8 @@ export namespace ext {
     export let workspaceTree: AzExtTreeDataProvider;
     export let workspaceTreeView: TreeView<unknown>;
     export let tenantTreeView: TreeView<unknown>
-    export let activityLogTree: AzExtTreeDataProvider;
-    export let activityLogTreeItem: ActivityLogTreeItem;
+    export let activityLogTree: ActivityLogTreeDataProvider;
+    export let activityLogTreeView: TreeView<unknown>;
     export let helpTree: AzExtTreeDataProvider;
     export let outputChannel: IAzExtLogOutputChannel;
     export let ignoreBundle: boolean | undefined;
diff --git a/src/managedIdentity/ManagedIdentityBranchDataProvider.ts b/src/managedIdentity/ManagedIdentityBranchDataProvider.ts
index 9cb6af95..3a7c5546 100644
--- a/src/managedIdentity/ManagedIdentityBranchDataProvider.ts
+++ b/src/managedIdentity/ManagedIdentityBranchDataProvider.ts
@@ -3,7 +3,7 @@
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
 
-import { callWithTelemetryAndErrorHandling, type IActionContext } from '@microsoft/vscode-azext-utils';
+import { callWithTelemetryAndErrorHandling, TreeElementBase, type IActionContext } from '@microsoft/vscode-azext-utils';
 import { AzureResource, AzureResourceModel, BranchDataProvider } from '@microsoft/vscode-azureresources-api';
 import * as vscode from 'vscode';
 import { localize } from 'vscode-nls';
@@ -11,7 +11,7 @@ import { ext } from '../extensionVariables';
 import { ResourceGroupsItem } from '../tree/ResourceGroupsItem';
 import { ManagedIdentityItem } from './ManagedIdentityItem';
 export class ManagedIdentityBranchDataProvider extends vscode.Disposable implements BranchDataProvider<AzureResource, AzureResourceModel> {
-    private readonly onDidChangeTreeDataEmitter = new vscode.EventEmitter<ResourceGroupsItem | undefined>();
+    private readonly onDidChangeTreeDataEmitter = new vscode.EventEmitter<TreeElementBase | undefined>();
 
     constructor() {
         super(
@@ -20,11 +20,11 @@ export class ManagedIdentityBranchDataProvider extends vscode.Disposable impleme
             });
     }
 
-    get onDidChangeTreeData(): vscode.Event<ResourceGroupsItem | undefined> {
+    get onDidChangeTreeData(): vscode.Event<TreeElementBase | undefined> {
         return this.onDidChangeTreeDataEmitter.event;
     }
 
-    async getChildren(element: ResourceGroupsItem): Promise<ResourceGroupsItem[] | null | undefined> {
+    async getChildren(element: ResourceGroupsItem): Promise<TreeElementBase[] | null | undefined> {
         return (await element.getChildren?.())?.map((child) => {
             return ext.azureTreeState.wrapItemInStateHandling(child, () => this.refresh(child))
         });
@@ -42,14 +42,14 @@ export class ManagedIdentityBranchDataProvider extends vscode.Disposable impleme
             throw new Error(localize('failedToGetResourceItem', 'Failed to get resource item for "{0}"', element.id));
         }
 
-        return ext.azureTreeState.wrapItemInStateHandling(resourceItem, () => this.refresh(resourceItem));
+        return ext.azureTreeState.wrapItemInStateHandling(resourceItem, () => this.refresh(resourceItem)) as ResourceGroupsItem;
     }
 
     async getTreeItem(element: ResourceGroupsItem): Promise<vscode.TreeItem> {
         return await element.getTreeItem();
     }
 
-    refresh(element?: ResourceGroupsItem): void {
+    refresh(element?: TreeElementBase): void {
         this.onDidChangeTreeDataEmitter.fire(element);
     }
 }
diff --git a/src/tree/ResourceGroupsItem.ts b/src/tree/ResourceGroupsItem.ts
index 0a6e1a47..87a252ce 100644
--- a/src/tree/ResourceGroupsItem.ts
+++ b/src/tree/ResourceGroupsItem.ts
@@ -3,8 +3,10 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
+import { TreeElementBase } from 'node_modules/@microsoft/vscode-azext-utils';
 import * as vscode from 'vscode';
 
+export type TreeDataItem = ResourceGroupsItem | TreeElementBase;
 export interface ResourceGroupsItem {
     readonly id: string;
 
diff --git a/src/tree/ResourceTreeDataProviderBase.ts b/src/tree/ResourceTreeDataProviderBase.ts
index f2ab770f..2945f29f 100644
--- a/src/tree/ResourceTreeDataProviderBase.ts
+++ b/src/tree/ResourceTreeDataProviderBase.ts
@@ -4,27 +4,27 @@
  *--------------------------------------------------------------------------------------------*/
 
 import { AzureSubscriptionProvider } from '@microsoft/vscode-azext-azureauth';
-import { callWithTelemetryAndErrorHandling, parseError } from '@microsoft/vscode-azext-utils';
+import { callWithTelemetryAndErrorHandling, parseError, TreeElementBase } from '@microsoft/vscode-azext-utils';
 import * as vscode from 'vscode';
 import { ResourceBase, ResourceModelBase } from '../../api/src/index';
 import { ext } from '../extensionVariables';
 import { BranchDataItemCache } from './BranchDataItemCache';
 import { BranchDataItemWrapper } from './BranchDataItemWrapper';
 import { InvalidItem } from './InvalidItem';
-import { ResourceGroupsItem } from './ResourceGroupsItem';
+import { ResourceGroupsItem, TreeDataItem } from './ResourceGroupsItem';
 import { TreeItemStateStore } from './TreeItemState';
 
-export abstract class ResourceTreeDataProviderBase extends vscode.Disposable implements vscode.TreeDataProvider<ResourceGroupsItem> {
+export abstract class ResourceTreeDataProviderBase extends vscode.Disposable implements vscode.TreeDataProvider<TreeDataItem> {
     private readonly branchTreeDataChangeSubscription: vscode.Disposable;
     private readonly refreshSubscription: vscode.Disposable;
     private readonly resourceProviderManagerListener: vscode.Disposable;
-    private readonly onDidChangeTreeDataEmitter = new vscode.EventEmitter<void | ResourceGroupsItem | ResourceGroupsItem[] | null | undefined>();
+    private readonly onDidChangeTreeDataEmitter = new vscode.EventEmitter<void | TreeElementBase | TreeElementBase[] | null | undefined>();
 
     constructor(
         protected readonly itemCache: BranchDataItemCache,
         onDidChangeBranchTreeData: vscode.Event<void | ResourceModelBase | ResourceModelBase[] | null | undefined>,
         onDidChangeResource: vscode.Event<ResourceBase | undefined>,
-        onRefresh: vscode.Event<void | ResourceGroupsItem | ResourceGroupsItem[] | null | undefined>,
+        onRefresh: vscode.Event<void | TreeDataItem | TreeDataItem[] | null | undefined>,
         private readonly state?: TreeItemStateStore,
         callOnDispose?: () => void) {
         super(
@@ -73,10 +73,10 @@ export abstract class ResourceTreeDataProviderBase extends vscode.Disposable imp
         }
     }
 
-    onDidChangeTreeData: vscode.Event<void | ResourceGroupsItem | ResourceGroupsItem[] | null | undefined> = this.onDidChangeTreeDataEmitter.event;
+    onDidChangeTreeData: vscode.Event<void | TreeElementBase | TreeElementBase[] | null | undefined> = this.onDidChangeTreeDataEmitter.event;
 
     notifyTreeDataChanged(data: void | ResourceModelBase | ResourceModelBase[] | null | undefined): void {
-        const rgItems: ResourceGroupsItem[] = [];
+        const rgItems: TreeDataItem[] = [];
 
         // eslint-disable-next-line no-extra-boolean-cast
         if (!!data) {
@@ -100,7 +100,7 @@ export abstract class ResourceTreeDataProviderBase extends vscode.Disposable imp
         }
     }
 
-    async getTreeItem(element: ResourceGroupsItem): Promise<vscode.TreeItem> {
+    async getTreeItem(element: TreeDataItem): Promise<vscode.TreeItem> {
         try {
             // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
             return (await callWithTelemetryAndErrorHandling('getTreeItem', async (context) => {
@@ -113,7 +113,7 @@ export abstract class ResourceTreeDataProviderBase extends vscode.Disposable imp
         }
     }
 
-    async getChildren(element?: ResourceGroupsItem | undefined): Promise<ResourceGroupsItem[] | null | undefined> {
+    async getChildren(element?: TreeDataItem | undefined): Promise<TreeDataItem[] | null | undefined> {
         const children = await this.onGetChildren(element);
         return children?.map(child => {
             if (this.state) {
@@ -127,23 +127,23 @@ export abstract class ResourceTreeDataProviderBase extends vscode.Disposable imp
         });
     }
 
-    getParent(element: ResourceGroupsItem): vscode.ProviderResult<ResourceGroupsItem> {
+    getParent(element: ResourceGroupsItem): vscode.ProviderResult<TreeDataItem> {
         return element.getParent?.();
     }
 
-    async findItemById(id: string): Promise<ResourceGroupsItem | undefined> {
-        let element: ResourceGroupsItem | undefined = undefined;
+    async findItemById(id: string): Promise<TreeDataItem | undefined> {
+        let element: TreeDataItem | undefined = undefined;
         outerLoop: while (true) {
-            const children: ResourceGroupsItem[] | null | undefined = await this.getChildren(element);
+            const children: TreeDataItem[] | null | undefined = await this.getChildren(element);
 
             if (!children) {
                 return;
             }
 
             for (const child of children) {
-                if (child.id.toLowerCase() === id.toLowerCase()) {
+                if (child.id?.toLowerCase() === id.toLowerCase()) {
                     return child;
-                } else if (removePrefix(child.id.toLowerCase()) === id.toLowerCase()) {
+                } else if (removePrefix(child.id?.toLowerCase()) === id.toLowerCase()) {
                     return child;
                 } else if (this.isAncestorOf(child, id)) {
                     element = child;
@@ -155,15 +155,15 @@ export abstract class ResourceTreeDataProviderBase extends vscode.Disposable imp
         }
     }
 
-    protected isAncestorOf(element: ResourceGroupsItem, id: string): boolean {
+    protected isAncestorOf(element: TreeDataItem, id: string): boolean {
         // remove accounts / <accountId>/tenant/<tenantId> from the beginning of the id
         const elementId = removePrefix(element.id) + '/';
         return id.toLowerCase().startsWith(elementId.toLowerCase());
     }
 
-    protected abstract onGetChildren(element?: ResourceGroupsItem | undefined): Promise<ResourceGroupsItem[] | null | undefined>;
+    protected abstract onGetChildren(element?: TreeDataItem | undefined): Promise<TreeDataItem[] | null | undefined>;
 }
 
-function removePrefix(id: string): string {
-    return id.replace(/\/accounts\/.+\/tenants\/[^/]+\//i, '/')
+function removePrefix(id?: string): string {
+    return id?.replace(/\/accounts\/.+\/tenants\/[^/]+\//i, '/') || '';
 }
diff --git a/src/tree/TreeDataProviderBase.ts b/src/tree/TreeDataProviderBase.ts
new file mode 100644
index 00000000..214f02f3
--- /dev/null
+++ b/src/tree/TreeDataProviderBase.ts
@@ -0,0 +1,162 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { callWithTelemetryAndErrorHandling, parseError, TreeElementBase } from '@microsoft/vscode-azext-utils';
+import * as vscode from 'vscode';
+import { ResourceBase, ResourceModelBase } from '../../api/src/index';
+import { BranchDataItemCache } from './BranchDataItemCache';
+import { InvalidItem } from './InvalidItem';
+
+export abstract class TreeDataProviderBase extends vscode.Disposable implements vscode.TreeDataProvider<TreeElementBase> {
+    private readonly branchTreeDataChangeSubscription: vscode.Disposable;
+    private readonly refreshSubscription: vscode.Disposable;
+    private readonly resourceProviderManagerListener: vscode.Disposable;
+    private readonly onDidChangeTreeDataEmitter = new vscode.EventEmitter<void | TreeElementBase | TreeElementBase[] | null | undefined>();
+
+    constructor(
+        protected readonly itemCache: BranchDataItemCache,
+        onDidChangeBranchTreeData: vscode.Event<void | ResourceModelBase | ResourceModelBase[] | null | undefined>,
+        onDidChangeResource: vscode.Event<ResourceBase | undefined>,
+        onRefresh: vscode.Event<void | TreeElementBase | TreeElementBase[] | null | undefined>,
+        // private readonly state?: TreeItemStateStore,
+        callOnDispose?: () => void) {
+        super(
+            () => {
+                callOnDispose?.();
+
+                this.branchTreeDataChangeSubscription.dispose();
+                this.refreshSubscription.dispose();
+                this.resourceProviderManagerListener.dispose();
+            });
+
+        this.branchTreeDataChangeSubscription = onDidChangeBranchTreeData(e => this.notifyTreeDataChanged(e));
+
+        this.refreshSubscription = onRefresh((e) => this.onDidChangeTreeDataEmitter.fire(e));
+
+        // TODO: If only individual resources change, just update the tree related to those resources.
+        this.resourceProviderManagerListener = onDidChangeResource(() => this.onDidChangeTreeDataEmitter.fire());
+    }
+
+    // protected statusSubscription: vscode.Disposable | undefined;
+    // private subscriptionProvider?: AzureSubscriptionProvider;
+    // private nextSessionChangeMessageMinimumTime = 0;
+    // private sessionChangeMessageInterval = 1 * 1000; // 1 second
+
+    // protected async getAzureSubscriptionProvider(): Promise<AzureSubscriptionProvider> {
+    //     // override for testing
+    //     if (ext.testing.overrideAzureSubscriptionProvider) {
+    //         return ext.testing.overrideAzureSubscriptionProvider();
+    //     } else {
+    //         if (!this.subscriptionProvider) {
+    //             this.subscriptionProvider = await ext.subscriptionProviderFactory();
+    //         }
+
+    //         this.statusSubscription = vscode.authentication.onDidChangeSessions((evt: vscode.AuthenticationSessionsChangeEvent) => {
+    //             if (evt.provider.id === 'microsoft' || evt.provider.id === 'microsoft-sovereign-cloud') {
+    //                 if (Date.now() > this.nextSessionChangeMessageMinimumTime) {
+    //                     this.nextSessionChangeMessageMinimumTime = Date.now() + this.sessionChangeMessageInterval;
+    //                     // This event gets HEAVILY spammed and needs to be debounced
+    //                     // Suppress additional messages for 1 second after the first one
+    //                     this.notifyTreeDataChanged();
+    //                 }
+    //             }
+    //         });
+
+    //         return this.subscriptionProvider;
+    //     }
+    // }
+
+    public onDidChangeTreeData: vscode.Event<void | TreeElementBase | TreeElementBase[] | null | undefined> = this.onDidChangeTreeDataEmitter.event;
+
+    public notifyTreeDataChanged(data: void | ResourceModelBase | ResourceModelBase[] | null | undefined): void {
+        const rgItems: TreeElementBase[] = [];
+
+        // eslint-disable-next-line no-extra-boolean-cast
+        if (!!data) {
+            // e was defined, either a single item or array
+            // Make an array for consistency
+            const branchItems: ResourceModelBase[] = Array.isArray(data) ? data : [data];
+
+            for (const branchItem of branchItems) {
+                const rgItem = this.itemCache.getItemForBranchItem(branchItem);
+
+                if (rgItem) {
+                    rgItems.push(rgItem);
+                }
+            }
+            this.onDidChangeTreeDataEmitter.fire(rgItems);
+        } else {
+            // e was null/undefined/void
+            // Translate it to fire on all elements for this branch data provider
+            // TODO
+            this.onDidChangeTreeDataEmitter.fire();
+        }
+    }
+
+    async getTreeItem(element: TreeElementBase): Promise<vscode.TreeItem> {
+        try {
+            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+            return (await callWithTelemetryAndErrorHandling('getTreeItem', async (context) => {
+                context.errorHandling.rethrow = true;
+                return await element.getTreeItem();
+            }))!;
+        } catch (e) {
+            const invalidItem = new InvalidItem(parseError(e));
+            return invalidItem.getTreeItem();
+        }
+    }
+
+    abstract getChildren(element?: TreeElementBase | undefined): Promise<TreeElementBase[] | null | undefined>;
+    // const children = await this.onGetChildren(element);
+    // return children?.map(child => {
+    //     if (this.state) {
+    //         // don't wrap items that belong to branch data providers
+    //         if (child instanceof BranchDataItemWrapper) {
+    //             return child;
+    //         }
+    //         return this.state.wrapItemInStateHandling(child, (item) => this.onDidChangeTreeDataEmitter.fire(item));
+    //     }
+    //     return child;
+    // });
+
+    abstract getParent(element: TreeElementBase): vscode.ProviderResult<TreeElementBase>
+    // return element.getParent?.();
+
+    async findItemById(id: string): Promise<TreeElementBase | undefined> {
+        let element: TreeElementBase | undefined = undefined;
+        outerLoop: while (true) {
+            const children: TreeElementBase[] | null | undefined = await this.getChildren(element);
+
+            if (!children) {
+                return;
+            }
+
+            for (const child of children) {
+                if (child.id?.toLowerCase() === id.toLowerCase()) {
+                    return child;
+                } else if (removePrefix(child.id?.toLowerCase()) === id.toLowerCase()) {
+                    return child;
+                } else if (this.isAncestorOf(child, id)) {
+                    element = child;
+                    continue outerLoop;
+                }
+            }
+
+            return undefined;
+        }
+    }
+
+    protected isAncestorOf(element: TreeElementBase, id: string): boolean {
+        // remove accounts / <accountId>/tenant/<tenantId> from the beginning of the id
+        const elementId = removePrefix(element.id) + '/';
+        return id.toLowerCase().startsWith(elementId.toLowerCase());
+    }
+
+    protected abstract onGetChildren(element?: TreeElementBase | undefined): Promise<TreeElementBase[] | null | undefined>;
+}
+
+function removePrefix(id?: string): string {
+    return id ? id.replace(/\/accounts\/.+\/tenants\/[^/]+\//i, '/') : '';
+}
diff --git a/src/tree/TreeItemState.ts b/src/tree/TreeItemState.ts
index 888ca368..00017f08 100644
--- a/src/tree/TreeItemState.ts
+++ b/src/tree/TreeItemState.ts
@@ -3,8 +3,8 @@
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
 
+import { TreeElementBase } from 'node_modules/@microsoft/vscode-azext-utils';
 import * as vscode from 'vscode';
-import { ResourceGroupsItem } from './ResourceGroupsItem';
 
 interface TreeItemState {
     /**
@@ -32,7 +32,7 @@ export class TreeItemStateStore implements vscode.Disposable {
         this.onDidUpdateStateEmitter.fire(id);
     }
 
-    wrapItemInStateHandling(item: ResourceGroupsItem, refresh: (item: ResourceGroupsItem) => void): ResourceGroupsItem {
+    wrapItemInStateHandling(item: TreeElementBase, refresh: (item: TreeElementBase) => void): TreeElementBase {
         const getTreeItem = item.getTreeItem.bind(item) as typeof item.getTreeItem;
         item.getTreeItem = async () => {
             const treeItem = await getTreeItem();
@@ -79,7 +79,7 @@ export class TreeItemStateStore implements vscode.Disposable {
         return treeItem;
     }
 
-    private onDidRequestRefresh(id: string, callback: () => void): void {
+    private onDidRequestRefresh(id: string | undefined, callback: () => void): void {
         this.disposables.push(this.onDidUpdateStateEvent((eventId: string) => {
             if (eventId === id) {
                 callback();
diff --git a/src/activityLog/ActivityTreeItem.ts b/src/tree/activityLog/ActivityItem.ts
similarity index 77%
rename from src/activityLog/ActivityTreeItem.ts
rename to src/tree/activityLog/ActivityItem.ts
index b11b2140..d859e72f 100644
--- a/src/activityLog/ActivityTreeItem.ts
+++ b/src/tree/activityLog/ActivityItem.ts
@@ -3,18 +3,20 @@
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
 
-import { AzExtParentTreeItem, AzExtTreeItem, callWithTelemetryAndErrorHandling, IActionContext, TreeItemIconPath } from "@microsoft/vscode-azext-utils";
+import { callWithTelemetryAndErrorHandling, TreeElementBase, TreeItemIconPath } from "@microsoft/vscode-azext-utils";
 import { Activity, ActivityTreeItemOptions, OnErrorActivityData, OnProgressActivityData, OnStartActivityData, OnSuccessActivityData } from "@microsoft/vscode-azext-utils/hostapi";
-import { Disposable, ThemeColor, ThemeIcon, TreeItemCollapsibleState } from "vscode";
-import { localize } from "../utils/localize";
+import { Disposable, ThemeColor, ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
+import { ext } from "../../extensionVariables";
+import { localize } from "../../utils/localize";
+import { TreeDataItem } from "../ResourceGroupsItem";
 
 export enum ActivityStatus {
     Running = 'running',
     Done = 'done'
 }
 
-export class ActivityTreeItem extends AzExtParentTreeItem implements Disposable {
-
+export class ActivityItem implements TreeElementBase, Disposable {
+    public readonly id: string;
     public startedAtMs: number;
 
     public get contextValue(): string {
@@ -53,14 +55,23 @@ export class ActivityTreeItem extends AzExtParentTreeItem implements Disposable
         label: localize('loading', 'Loading...')
     }
 
-    public initialCollapsibleState: TreeItemCollapsibleState = TreeItemCollapsibleState.None;
+    getTreeItem(): TreeItem | Thenable<TreeItem> {
+        return {
+            label: this.label,
+            description: this.description,
+            iconPath: this.iconPath,
+            contextValue: this.contextValue,
+            collapsibleState: this.initialCollapsibleState
+        }
+    }
+
+    public initialCollapsibleState: TreeItemCollapsibleState = TreeItemCollapsibleState.Expanded;
 
     public status?: ActivityStatus;
     public error?: unknown;
     private latestProgress?: { message?: string };
 
-    public constructor(parent: AzExtParentTreeItem, activity: Activity) {
-        super(parent);
+    public constructor(activity: Activity) {
         this.id = activity.id;
         this.setupListeners(activity);
         this.startedAtMs = Date.now();
@@ -72,53 +83,49 @@ export class ActivityTreeItem extends AzExtParentTreeItem implements Disposable
 
     private readonly disposables: Disposable[] = [];
 
-    public async loadMoreChildrenImpl(_clearCache: boolean, _context: IActionContext): Promise<AzExtTreeItem[]> {
+    public async getChildren(): Promise<TreeDataItem[] | null | undefined> {
         if (this.state.getChildren) {
             return await this.state.getChildren(this);
         }
         return [];
     }
 
-    public hasMoreChildrenImpl(): boolean {
-        return false;
-    }
-
     private onProgress(data: OnProgressActivityData): void {
         void callWithTelemetryAndErrorHandling('activityOnProgress', async (context) => {
             context.telemetry.suppressIfSuccessful = true;
             this.latestProgress = data.message ? { message: data?.message } : this.latestProgress;
             this.state = data;
-            await this.refresh(context);
+            ext.actions.refreshActivityLogTree(this);
         });
     }
 
     private onStart(data: OnStartActivityData): void {
-        void callWithTelemetryAndErrorHandling('activityOnStart', async (context) => {
+        void callWithTelemetryAndErrorHandling('activityOnStart', async (_context) => {
             this.startedAtMs = Date.now();
             this.status = ActivityStatus.Running;
             this.state = data;
-            await this.refresh(context);
+            ext.actions.refreshActivityLogTree(this);
         });
     }
 
     private onSuccess(data: OnSuccessActivityData): void {
-        void callWithTelemetryAndErrorHandling('activityOnSuccess', async (context) => {
+        void callWithTelemetryAndErrorHandling('activityOnSuccess', async (_context) => {
             this.state = data;
             this.status = ActivityStatus.Done;
             if (this.state.getChildren) {
                 this.initialCollapsibleState = TreeItemCollapsibleState.Expanded;
             }
-            await this.refresh(context);
+            ext.actions.refreshActivityLogTree(this);
         })
     }
 
     private onError(data: OnErrorActivityData): void {
-        void callWithTelemetryAndErrorHandling('activityOnError', async (context) => {
+        void callWithTelemetryAndErrorHandling('activityOnError', async (_context) => {
             this.state = data;
             this.status = ActivityStatus.Done;
             this.error = data.error;
             this.initialCollapsibleState = TreeItemCollapsibleState.Expanded;
-            await this.refresh(context);
+            ext.actions.refreshActivityLogTree(this);
         });
     }
 
diff --git a/src/tree/activityLog/ActivityLogBranchDataProvider.ts b/src/tree/activityLog/ActivityLogBranchDataProvider.ts
new file mode 100644
index 00000000..7757e613
--- /dev/null
+++ b/src/tree/activityLog/ActivityLogBranchDataProvider.ts
@@ -0,0 +1,59 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { callWithTelemetryAndErrorHandling, IActionContext, TreeElementBase } from '@microsoft/vscode-azext-utils';
+import { Activity } from '@microsoft/vscode-azext-utils/hostapi';
+import { commands, Event } from 'vscode';
+import { ActivityLogResourceProviderManager } from '../../api/ResourceProviderManagers';
+import { ext } from '../../extensionVariables';
+import { settingUtils } from '../../utils/settingUtils';
+import { BranchDataItemCache } from '../BranchDataItemCache';
+import { ResourceTreeDataProviderBase } from '../ResourceTreeDataProviderBase';
+import { WorkspaceResourceBranchDataProviderManager } from '../workspace/WorkspaceResourceBranchDataProviderManager';
+import { ActivityItem, ActivityStatus } from './ActivityItem';
+
+export class ActivityLogTreeDataProvider extends ResourceTreeDataProviderBase {
+    private activityTreeItems: Record<string, ActivityItem> = {};
+    constructor(
+        branchDataProviderManager: WorkspaceResourceBranchDataProviderManager,
+        onRefresh: Event<void | TreeElementBase | TreeElementBase[] | null | undefined>,
+        resourceProviderManager: ActivityLogResourceProviderManager,
+        branchItemCache: BranchDataItemCache) {
+        super(
+            branchItemCache,
+            branchDataProviderManager.onDidChangeTreeData,
+            resourceProviderManager.onDidChangeResourceChange,
+            onRefresh);
+    }
+
+    async onGetChildren(element?: TreeElementBase | undefined): Promise<TreeElementBase[] | null | undefined> {
+        if (element?.getChildren) {
+            return await element.getChildren();
+        } else {
+            return Object.values(this.activityTreeItems).filter((activity) => !!activity.status);
+        }
+    }
+
+    public async addActivity(activity: Activity): Promise<void> {
+        await callWithTelemetryAndErrorHandling('registerActivity', async (_context: IActionContext) => {
+            this.activityTreeItems[activity.id] = new ActivityItem(activity);
+            if ((await settingUtils.getWorkspaceSetting('autoOpenActivityPanel'))) {
+                await commands.executeCommand('azureActivityLog.focus');
+            }
+
+            ext.actions.refreshActivityLogTree();
+        });
+    }
+
+    public async clearActivities(_context: IActionContext): Promise<void> {
+        Object.entries(this.activityTreeItems).forEach(([id, activity]: [string, ActivityItem]) => {
+            if (activity.status === ActivityStatus.Done) {
+                activity.dispose();
+                delete this.activityTreeItems[id];
+            }
+        });
+        ext.actions.refreshActivityLogTree();
+    }
+}
diff --git a/src/tree/activityLog/ActivityLogBranchDataProviderManager.ts b/src/tree/activityLog/ActivityLogBranchDataProviderManager.ts
new file mode 100644
index 00000000..142e132f
--- /dev/null
+++ b/src/tree/activityLog/ActivityLogBranchDataProviderManager.ts
@@ -0,0 +1,18 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { BranchDataProvider, ResourceBase, ResourceModelBase } from "api/src";
+import { ResourceBranchDataProviderManagerBase } from "../ResourceBranchDataProviderManagerBase";
+
+export class ActivityLogResourceBranchDataProviderManager extends ResourceBranchDataProviderManagerBase<string, BranchDataProvider<ResourceBase, ResourceModelBase>> {
+    constructor(
+        defaultProvider: BranchDataProvider<ResourceBase, ResourceModelBase>
+    ) {
+        super(
+            defaultProvider,
+            () => { return 'activityLog' }
+        );
+    }
+}
diff --git a/src/tree/activityLog/ActivityLogDefaultBranchDataProvider.ts b/src/tree/activityLog/ActivityLogDefaultBranchDataProvider.ts
new file mode 100644
index 00000000..9430af3d
--- /dev/null
+++ b/src/tree/activityLog/ActivityLogDefaultBranchDataProvider.ts
@@ -0,0 +1,34 @@
+/*---------------------------------------------------------------------------------------------
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Licensed under the MIT License. See License.md in the project root for license information.
+*--------------------------------------------------------------------------------------------*/
+import * as vscode from 'vscode';
+import { BranchDataProvider, ResourceBase, ResourceModelBase } from '../../../api/src/index';
+import { ActivityLogResource } from './activityLog';
+
+interface ActivityLogResourceModel extends ResourceModelBase {
+    readonly name: string;
+}
+
+class ActivityLogResourceItem implements ActivityLogResourceModel {
+    constructor(private readonly resource: ActivityLogResource) {
+    }
+
+    get name(): string {
+        return this.resource.name;
+    }
+}
+
+export class ActivityLogDefaultBranchDataProvider implements BranchDataProvider<ResourceBase, ActivityLogResourceModel> {
+    getChildren(_element: ActivityLogResourceModel): vscode.ProviderResult<ActivityLogResourceModel[]> {
+        return [];
+    }
+
+    getResourceItem(element: ActivityLogResource): ActivityLogResourceModel | Thenable<ActivityLogResourceModel> {
+        return new ActivityLogResourceItem(element);
+    }
+
+    getTreeItem(element: ActivityLogResourceModel): vscode.TreeItem | Thenable<vscode.TreeItem> {
+        return new vscode.TreeItem(element.name);
+    }
+}
diff --git a/src/tree/activityLog/ActivityLogResourceBranchDataProviderManager.ts b/src/tree/activityLog/ActivityLogResourceBranchDataProviderManager.ts
new file mode 100644
index 00000000..5a3a3a8e
--- /dev/null
+++ b/src/tree/activityLog/ActivityLogResourceBranchDataProviderManager.ts
@@ -0,0 +1,15 @@
+/*---------------------------------------------------------------------------------------------
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Licensed under the MIT License. See License.md in the project root for license information.
+*--------------------------------------------------------------------------------------------*/
+
+import { BranchDataProvider, ResourceBase, ResourceModelBase } from '../../../api/src/index';
+import { ResourceBranchDataProviderManagerBase } from "../ResourceBranchDataProviderManagerBase";
+
+export class ActivityLogResourceBranchDataProviderManager extends ResourceBranchDataProviderManagerBase<string, BranchDataProvider<ResourceBase, ResourceModelBase>> {
+    constructor(
+        defaultProvider: BranchDataProvider<ResourceBase, ResourceModelBase>
+    ) {
+        super(defaultProvider, () => { return 'activityLog' });
+    }
+}
diff --git a/src/tree/activityLog/activityLog.ts b/src/tree/activityLog/activityLog.ts
new file mode 100644
index 00000000..2fae5948
--- /dev/null
+++ b/src/tree/activityLog/activityLog.ts
@@ -0,0 +1,36 @@
+/*---------------------------------------------------------------------------------------------
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Licensed under the MIT License. See License.md in the project root for license information.
+*--------------------------------------------------------------------------------------------*/
+
+import { BranchDataProvider, ResourceBase, ResourceModelBase, ResourceProvider } from "api/src";
+
+/**
+ * Respresents a specific type of activity log resource.
+ *
+ * @remarks This value should be unique across all types of activity log resources.
+ */
+export type ActivityLogResourceType = string;
+
+/**
+ * An indivdual root resource for an activity log.
+ */
+export interface ActivityLogResource extends ResourceBase {
+    //account?
+
+    /**
+         * The type of this resource.
+         *
+         * @remarks This value is used to map resources to their associated branch data provider.
+         */
+    readonly resourceType: ActivityLogResourceType;
+}
+
+/**
+ * A provider for supplying items for the activity log resource tree
+ */
+export type ActivityLogResourceProvider = ResourceProvider<void, ActivityLogResource>;
+/**
+ * A provider for visualizing items in the activity log resource tree
+ */
+export type ActivityLogResourceBranchDataProvider<TModel extends ResourceModelBase> = BranchDataProvider<ActivityLogResource, TModel>;
diff --git a/src/tree/azure/AzureResourceTreeDataProvider.ts b/src/tree/azure/AzureResourceTreeDataProvider.ts
index e654af76..f718ee79 100644
--- a/src/tree/azure/AzureResourceTreeDataProvider.ts
+++ b/src/tree/azure/AzureResourceTreeDataProvider.ts
@@ -4,7 +4,7 @@
  *--------------------------------------------------------------------------------------------*/
 
 import { AzureSubscription, getUnauthenticatedTenants } from '@microsoft/vscode-azext-azureauth';
-import { IActionContext, callWithTelemetryAndErrorHandling, createSubscriptionContext, nonNullValueAndProp, registerEvent } from '@microsoft/vscode-azext-utils';
+import { IActionContext, TreeElementBase, callWithTelemetryAndErrorHandling, createSubscriptionContext, nonNullValueAndProp, registerEvent } from '@microsoft/vscode-azext-utils';
 import * as vscode from 'vscode';
 import { ResourceModelBase } from '../../../api/src/index';
 import { AzureResourceProviderManager } from '../../api/ResourceProviderManagers';
@@ -28,7 +28,7 @@ export class AzureResourceTreeDataProvider extends AzureResourceTreeDataProvider
         onDidChangeBranchTreeData: vscode.Event<void | ResourceModelBase | ResourceModelBase[] | null | undefined>,
         itemCache: BranchDataItemCache,
         state: TreeItemStateStore,
-        onRefresh: vscode.Event<void | ResourceGroupsItem | ResourceGroupsItem[] | null | undefined>,
+        onRefresh: vscode.Event<void | TreeElementBase | TreeElementBase[] | null | undefined>,
         protected readonly resourceGroupingManager: AzureResourceGroupingManager,
         protected readonly resourceProviderManager: AzureResourceProviderManager) {
         super(
@@ -63,7 +63,7 @@ export class AzureResourceTreeDataProvider extends AzureResourceTreeDataProvider
     }
 
     async onGetChildren(element?: ResourceGroupsItem | undefined): Promise<ResourceGroupsItem[] | null | undefined> {
-        if (element) {
+        if (element?.getChildren) {
             return await element.getChildren();
         } else {
             const subscriptionProvider = await this.getAzureSubscriptionProvider();
diff --git a/src/tree/azure/AzureResourceTreeDataProviderBase.ts b/src/tree/azure/AzureResourceTreeDataProviderBase.ts
index 7a582e08..0dcabd1b 100644
--- a/src/tree/azure/AzureResourceTreeDataProviderBase.ts
+++ b/src/tree/azure/AzureResourceTreeDataProviderBase.ts
@@ -3,6 +3,7 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
+import { TreeElementBase } from 'node_modules/@microsoft/vscode-azext-utils';
 import * as vscode from 'vscode';
 import { ResourceModelBase } from '../../../api/src/index';
 import { AzureResourceProviderManager } from '../../api/ResourceProviderManagers';
@@ -17,7 +18,7 @@ export abstract class AzureResourceTreeDataProviderBase extends ResourceTreeData
     constructor(
         itemCache: BranchDataItemCache,
         onDidChangeBranchTreeData: vscode.Event<void | ResourceModelBase | ResourceModelBase[] | null | undefined>,
-        onRefresh: vscode.Event<void | ResourceGroupsItem | ResourceGroupsItem[] | null | undefined>,
+        onRefresh: vscode.Event<void | TreeElementBase | TreeElementBase[] | null | undefined>,
         state: TreeItemStateStore,
         protected readonly resourceGroupingManager: AzureResourceGroupingManager,
         protected readonly resourceProviderManager: AzureResourceProviderManager,
diff --git a/src/tree/azure/FocusViewTreeDataProvider.ts b/src/tree/azure/FocusViewTreeDataProvider.ts
index 16bf2958..1da1829a 100644
--- a/src/tree/azure/FocusViewTreeDataProvider.ts
+++ b/src/tree/azure/FocusViewTreeDataProvider.ts
@@ -4,6 +4,7 @@
  *--------------------------------------------------------------------------------------------*/
 
 import { AzureSubscription } from '@microsoft/vscode-azext-azureauth';
+import { TreeElementBase } from 'node_modules/@microsoft/vscode-azext-utils';
 import * as vscode from 'vscode';
 import { AzExtResourceType, AzureResource, ResourceModelBase } from '../../../api/src/index';
 import { AzureResourceProviderManager } from '../../api/ResourceProviderManagers';
@@ -32,7 +33,7 @@ export class FocusViewTreeDataProvider extends AzureResourceTreeDataProviderBase
         onDidChangeBranchTreeData: vscode.Event<void | ResourceModelBase | ResourceModelBase[] | null | undefined>,
         itemCache: BranchDataItemCache,
         state: TreeItemStateStore,
-        onRefresh: vscode.Event<void | ResourceGroupsItem | ResourceGroupsItem[] | null | undefined>,
+        onRefresh: vscode.Event<void | TreeElementBase | TreeElementBase[] | null | undefined>,
         protected readonly resourceGroupingManager: AzureResourceGroupingManager,
         protected readonly resourceProviderManager: AzureResourceProviderManager) {
         super(
@@ -45,7 +46,7 @@ export class FocusViewTreeDataProvider extends AzureResourceTreeDataProviderBase
     }
 
     async onGetChildren(element?: ResourceGroupsItem | undefined): Promise<ResourceGroupsItem[] | null | undefined> {
-        if (element) {
+        if (element?.getChildren) {
             return await element.getChildren();
         } else {
             const focusedGroup = ext.focusedGroup;
diff --git a/src/tree/azure/registerAzureTree.ts b/src/tree/azure/registerAzureTree.ts
index 787e28b5..471f1c7c 100644
--- a/src/tree/azure/registerAzureTree.ts
+++ b/src/tree/azure/registerAzureTree.ts
@@ -11,7 +11,7 @@ import { ext } from '../../extensionVariables';
 import { localize } from '../../utils/localize';
 import { listenForRecentlyUsedNodes } from '../../utils/usedAndSelectedResources';
 import { BranchDataItemCache } from '../BranchDataItemCache';
-import { ResourceGroupsItem } from '../ResourceGroupsItem';
+import { TreeDataItem } from '../ResourceGroupsItem';
 import { TreeItemStateStore } from '../TreeItemState';
 import { createTreeView } from '../createTreeView';
 import { wrapTreeForVSCode } from '../wrapTreeForVSCode';
@@ -24,7 +24,7 @@ import { GroupingItemFactory } from './grouping/GroupingItemFactory';
 interface RegisterAzureTreeOptions {
     azureResourceBranchDataProviderManager: AzureResourceBranchDataProviderManager,
     azureResourceProviderManager: AzureResourceProviderManager,
-    refreshEvent: vscode.Event<void | ResourceGroupsItem | ResourceGroupsItem[] | null | undefined>,
+    refreshEvent: vscode.Event<void | TreeDataItem | TreeDataItem[] | null | undefined>,
     itemCache: BranchDataItemCache,
 }
 
diff --git a/src/tree/azure/registerFocusTree.ts b/src/tree/azure/registerFocusTree.ts
index 6acadde3..99e3fa46 100644
--- a/src/tree/azure/registerFocusTree.ts
+++ b/src/tree/azure/registerFocusTree.ts
@@ -10,7 +10,7 @@ import { AzureResourceProviderManager } from '../../api/ResourceProviderManagers
 import { ext } from '../../extensionVariables';
 import { localize } from '../../utils/localize';
 import { BranchDataItemCache } from '../BranchDataItemCache';
-import { ResourceGroupsItem } from '../ResourceGroupsItem';
+import { TreeDataItem } from '../ResourceGroupsItem';
 import { createTreeView } from '../createTreeView';
 import { wrapTreeForVSCode } from '../wrapTreeForVSCode';
 import { AzureResourceBranchDataProviderManager } from './AzureResourceBranchDataProviderManager';
@@ -22,7 +22,7 @@ import { GroupingItemFactory } from './grouping/GroupingItemFactory';
 interface RegisterAzureTreeOptions {
     azureResourceBranchDataProviderManager: AzureResourceBranchDataProviderManager,
     azureResourceProviderManager: AzureResourceProviderManager,
-    refreshEvent: vscode.Event<void | ResourceGroupsItem | ResourceGroupsItem[] | null | undefined>,
+    refreshEvent: vscode.Event<void | TreeDataItem | TreeDataItem[] | null | undefined>,
     itemCache: BranchDataItemCache,
 }
 
diff --git a/src/tree/createTreeView.ts b/src/tree/createTreeView.ts
index 8e27dd15..806561ca 100644
--- a/src/tree/createTreeView.ts
+++ b/src/tree/createTreeView.ts
@@ -6,15 +6,15 @@
 import { isAzExtTreeItem } from "@microsoft/vscode-azext-utils";
 import { TreeDataProvider, TreeView, TreeViewOptions, window } from "vscode";
 import { BranchDataItemCache } from "./BranchDataItemCache";
-import { ResourceGroupsItem } from "./ResourceGroupsItem";
+import { TreeDataItem } from "./ResourceGroupsItem";
 
-export interface InternalTreeView extends TreeView<ResourceGroupsItem> {
-    _reveal: TreeView<ResourceGroupsItem>['reveal'];
+export interface InternalTreeView extends TreeView<TreeDataItem> {
+    _reveal: TreeView<TreeDataItem>['reveal'];
 }
 
-interface InternalTreeViewOptions extends TreeViewOptions<ResourceGroupsItem> {
-    treeDataProvider: TreeDataProvider<ResourceGroupsItem>;
-    findItemById: (id: string) => Promise<ResourceGroupsItem | undefined>;
+interface InternalTreeViewOptions extends TreeViewOptions<TreeDataItem> {
+    treeDataProvider: TreeDataProvider<TreeDataItem>;
+    findItemById: (id: string) => Promise<TreeDataItem | undefined>;
     itemCache: BranchDataItemCache;
     /**
      * See {@link TreeView.description}
@@ -31,7 +31,7 @@ interface InternalTreeViewOptions extends TreeViewOptions<ResourceGroupsItem> {
  * - sets the `description` if present in options
  * - modifies `TreeView.reveal` {@link ResourceTreeDataProviderBase.reveal}
  */
-export function createTreeView(viewId: string, options: InternalTreeViewOptions): TreeView<ResourceGroupsItem> {
+export function createTreeView(viewId: string, options: InternalTreeViewOptions): TreeView<TreeDataItem> {
     const treeView = window.createTreeView(viewId, options);
     treeView.title = options.title;
     treeView.description = options.description;
@@ -44,12 +44,12 @@ export function createTreeView(viewId: string, options: InternalTreeViewOptions)
 /**
  * v1.5 compatibility for TreeView.reveal
  */
-function modifyReveal(treeView: TreeView<ResourceGroupsItem>, findItemById: (id: string) => Promise<ResourceGroupsItem | undefined>, itemCache: BranchDataItemCache): void {
+function modifyReveal(treeView: TreeView<TreeDataItem>, findItemById: (id: string) => Promise<TreeDataItem | undefined>, itemCache: BranchDataItemCache): void {
     (treeView as InternalTreeView)._reveal = treeView.reveal.bind(treeView) as typeof treeView.reveal;
 
     treeView.reveal = async (element, options) => {
-        // For compatibility: convert AzExtTreeItems into ResourceGroupsItems
-        const item: ResourceGroupsItem | undefined = isAzExtTreeItem(element) ? itemCache.getItemForBranchItem(element) ?? await findItemById(element.fullId) : element;
+        // For compatibility: convert AzExtTreeItems into TreeDataItems
+        const item: TreeDataItem | undefined = isAzExtTreeItem(element) ? itemCache.getItemForBranchItem(element) ?? await findItemById(element.fullId) : element;
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
         await (treeView as InternalTreeView)._reveal(item!, options);
     }
diff --git a/src/tree/tenants/TenantResourceTreeDataProvider.ts b/src/tree/tenants/TenantResourceTreeDataProvider.ts
index ed1c79bc..d4df989b 100644
--- a/src/tree/tenants/TenantResourceTreeDataProvider.ts
+++ b/src/tree/tenants/TenantResourceTreeDataProvider.ts
@@ -4,7 +4,7 @@
 *--------------------------------------------------------------------------------------------*/
 
 import { getConfiguredAuthProviderId } from '@microsoft/vscode-azext-azureauth';
-import { IActionContext, callWithTelemetryAndErrorHandling, nonNullProp, nonNullValueAndProp } from '@microsoft/vscode-azext-utils';
+import { IActionContext, TreeElementBase, callWithTelemetryAndErrorHandling, nonNullProp, nonNullValueAndProp } from '@microsoft/vscode-azext-utils';
 import { ResourceModelBase } from 'api/src';
 import * as vscode from 'vscode';
 import { TenantResourceProviderManager } from '../../api/ResourceProviderManagers';
@@ -21,7 +21,7 @@ export class TenantResourceTreeDataProvider extends ResourceTreeDataProviderBase
     constructor(
         protected readonly branchDataProviderManager: TenantResourceBranchDataProviderManager,
         onDidChangeBranchTreeData: vscode.Event<void | ResourceModelBase | ResourceModelBase[] | null | undefined>,
-        onRefresh: vscode.Event<void | ResourceGroupsItem | ResourceGroupsItem[] | null | undefined>,
+        onRefresh: vscode.Event<void | TreeElementBase | TreeElementBase[] | null | undefined>,
         protected readonly resourceProviderManager: TenantResourceProviderManager,
         branchItemCache: BranchDataItemCache,
         callOnDispose?: () => void) {
diff --git a/src/tree/tenants/registerTenantTree.ts b/src/tree/tenants/registerTenantTree.ts
index 25ad4e0d..93c717b7 100644
--- a/src/tree/tenants/registerTenantTree.ts
+++ b/src/tree/tenants/registerTenantTree.ts
@@ -9,7 +9,7 @@ import { TenantResourceProviderManager } from "../../api/ResourceProviderManager
 import { ext } from '../../extensionVariables';
 import { localize } from '../../utils/localize';
 import { BranchDataItemCache } from '../BranchDataItemCache';
-import { ResourceGroupsItem } from '../ResourceGroupsItem';
+import { TreeDataItem } from '../ResourceGroupsItem';
 import { createTreeView } from '../createTreeView';
 import { wrapTreeForVSCode } from '../wrapTreeForVSCode';
 import { TenantResourceBranchDataProviderManager } from "./TenantResourceBranchDataProviderManager";
@@ -19,7 +19,7 @@ import { TenantTreeItem } from './TenantTreeItem';
 interface RegisterTenantTreeOptions {
     tenantResourceBranchDataProviderManager: TenantResourceBranchDataProviderManager,
     tenantResourceProviderManager: TenantResourceProviderManager,
-    refreshEvent: vscode.Event<void | ResourceGroupsItem | ResourceGroupsItem[] | null | undefined>,
+    refreshEvent: vscode.Event<void | TreeDataItem | TreeDataItem[] | null | undefined>,
     itemCache: BranchDataItemCache
 }
 
diff --git a/src/tree/workspace/WorkspaceResourceTreeDataProvider.ts b/src/tree/workspace/WorkspaceResourceTreeDataProvider.ts
index bb599e0d..4756db14 100644
--- a/src/tree/workspace/WorkspaceResourceTreeDataProvider.ts
+++ b/src/tree/workspace/WorkspaceResourceTreeDataProvider.ts
@@ -3,6 +3,7 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
+import { TreeElementBase } from 'node_modules/@microsoft/vscode-azext-utils';
 import * as vscode from 'vscode';
 import { WorkspaceResource } from '../../../api/src/index';
 import { WorkspaceResourceProviderManager } from '../../api/ResourceProviderManagers';
@@ -17,7 +18,7 @@ import { WorkspaceResourceBranchDataProviderManager } from './WorkspaceResourceB
 export class WorkspaceResourceTreeDataProvider extends ResourceTreeDataProviderBase {
     constructor(
         private readonly branchDataProviderManager: WorkspaceResourceBranchDataProviderManager,
-        onRefresh: vscode.Event<void | ResourceGroupsItem | ResourceGroupsItem[] | null | undefined>,
+        onRefresh: vscode.Event<void | TreeElementBase | TreeElementBase[] | null | undefined>,
         private readonly resourceProviderManager: WorkspaceResourceProviderManager,
         branchItemCache: BranchDataItemCache) {
         super(
diff --git a/src/tree/workspace/registerWorkspaceTree.ts b/src/tree/workspace/registerWorkspaceTree.ts
index 545afaa6..1f3ba473 100644
--- a/src/tree/workspace/registerWorkspaceTree.ts
+++ b/src/tree/workspace/registerWorkspaceTree.ts
@@ -3,14 +3,13 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-import { AzExtTreeItem } from '@microsoft/vscode-azext-utils';
+import { AzExtTreeItem, TreeElementBase } from '@microsoft/vscode-azext-utils';
 import * as vscode from 'vscode';
 import { WorkspaceResourceProviderManager } from '../../api/ResourceProviderManagers';
 import { ext } from '../../extensionVariables';
 import { localize } from '../../utils/localize';
 import { BranchDataItemCache } from '../BranchDataItemCache';
 import { createTreeView } from '../createTreeView';
-import { ResourceGroupsItem } from '../ResourceGroupsItem';
 import { wrapTreeForVSCode } from '../wrapTreeForVSCode';
 import { WorkspaceResourceBranchDataProviderManager } from './WorkspaceResourceBranchDataProviderManager';
 import { WorkspaceResourceTreeDataProvider } from './WorkspaceResourceTreeDataProvider';
@@ -18,7 +17,7 @@ import { WorkspaceResourceTreeDataProvider } from './WorkspaceResourceTreeDataPr
 interface RegisterWorkspaceTreeOptions {
     workspaceResourceBranchDataProviderManager: WorkspaceResourceBranchDataProviderManager,
     workspaceResourceProviderManager: WorkspaceResourceProviderManager,
-    refreshEvent: vscode.Event<void | ResourceGroupsItem | ResourceGroupsItem[] | null | undefined>,
+    refreshEvent: vscode.Event<void | TreeElementBase | TreeElementBase[] | null | undefined>,
 }
 
 export function registerWorkspaceTree(context: vscode.ExtensionContext, options: RegisterWorkspaceTreeOptions): WorkspaceResourceTreeDataProvider {
diff --git a/src/tree/wrapTreeForVSCode.ts b/src/tree/wrapTreeForVSCode.ts
index 86415afc..121a4fc9 100644
--- a/src/tree/wrapTreeForVSCode.ts
+++ b/src/tree/wrapTreeForVSCode.ts
@@ -5,7 +5,7 @@
 
 import type { Event, ProviderResult, TreeDataProvider, TreeItem } from "vscode";
 import { BranchDataItemCache } from "./BranchDataItemCache";
-import { ResourceGroupsItem } from "./ResourceGroupsItem";
+import { TreeDataItem } from "./ResourceGroupsItem";
 import { ResourceTreeDataProviderBase } from "./ResourceTreeDataProviderBase";
 
 /**
@@ -18,26 +18,26 @@ export function wrapTreeForVSCode(treeDataProvider: ResourceTreeDataProviderBase
 /**
  * Wraps a tree data provider and calls a callback function when the root of the tree is refreshed.
  */
-class OnRefreshTreeDataProvider implements TreeDataProvider<ResourceGroupsItem> {
+class OnRefreshTreeDataProvider implements TreeDataProvider<TreeDataItem> {
     constructor(
-        private readonly treeDataProvider: TreeDataProvider<ResourceGroupsItem>,
+        private readonly treeDataProvider: TreeDataProvider<TreeDataItem>,
         private readonly onRefresh: () => void,
     ) { }
 
-    getTreeItem(element: ResourceGroupsItem): TreeItem | Thenable<TreeItem> {
+    getTreeItem(element: TreeDataItem): TreeItem | Thenable<TreeItem> {
         return this.treeDataProvider.getTreeItem(element);
     }
 
-    getParent(element: ResourceGroupsItem): ProviderResult<ResourceGroupsItem> {
+    getParent(element: TreeDataItem): ProviderResult<TreeDataItem> {
         return this.treeDataProvider.getParent?.(element);
     }
 
-    getChildren(element?: ResourceGroupsItem): ProviderResult<ResourceGroupsItem[]> {
+    getChildren(element?: TreeDataItem): ProviderResult<TreeDataItem[]> {
         if (!element) {
             this.onRefresh();
         }
         return this.treeDataProvider.getChildren(element);
     }
 
-    onDidChangeTreeData?: Event<void | ResourceGroupsItem | ResourceGroupsItem[] | null | ResourceGroupsItem> = this.treeDataProvider.onDidChangeTreeData;
+    onDidChangeTreeData?: Event<void | TreeDataItem | TreeDataItem[] | null | TreeDataItem> = this.treeDataProvider.onDidChangeTreeData;
 }
diff --git a/src/utils/activityUtils.ts b/src/utils/activityUtils.ts
index aeabb936..6ce5361c 100644
--- a/src/utils/activityUtils.ts
+++ b/src/utils/activityUtils.ts
@@ -1,5 +1,5 @@
 import { ExecuteActivityContext } from "@microsoft/vscode-azext-utils";
-import { registerActivity } from "../activityLog/registerActivity";
+import { registerActivity } from "../commands/activities/registerActivity";
 import { settingUtils } from "./settingUtils";
 
 export async function createActivityContext(): Promise<ExecuteActivityContext> {