src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts/NotebookCellOutline/constructor
class NotebookCellOutline:	constructor(
		private readonly _editor: INotebookEditorPane,
		private readonly _target: OutlineTarget,
		@IInstantiationService instantiationService: IInstantiationService,
		@IThemeService themeService: IThemeService,
		@IEditorService private readonly _editorService: IEditorService,
		@IMarkerService private readonly _markerService: IMarkerService,
		@IConfigurationService private readonly _configurationService: IConfigurationService,
		@INotebookExecutionStateService private readonly _notebookExecutionStateService: INotebookExecutionStateService,
	) {
		const selectionListener = new MutableDisposable();
		this._dispoables.add(selectionListener);
		const installSelectionListener = () => {
			const notebookEditor = _editor.getControl();
			if (!notebookEditor?.hasModel()) {
				selectionListener.clear();
			} else {
				selectionListener.value = combinedDisposable(
					Event.debounce<void, void>(
						notebookEditor.onDidChangeSelection,
						(last, _current) => last,
						200
					)(this._recomputeActive, this),
					Event.debounce<INotebookViewCellsUpdateEvent, INotebookViewCellsUpdateEvent>(
						notebookEditor.onDidChangeViewCells,
						(last, _current) => last ?? _current,
						200
					)(this._recomputeState, this)
				);
			}
		};

		this._dispoables.add(_editor.onDidChangeModel(() => {
			this._recomputeState();
			installSelectionListener();
		}));

		this._dispoables.add(_configurationService.onDidChangeConfiguration(e => {
			if (e.affectsConfiguration('notebook.outline.showCodeCells')) {
				this._recomputeState();
			}
		}));

		this._dispoables.add(themeService.onDidFileIconThemeChange(() => {
			this._onDidChange.fire({});
		}));

		this._dispoables.add(_notebookExecutionStateService.onDidChangeCellExecution(e => {
			if (!!this._editor.textModel && e.affectsNotebook(this._editor.textModel?.uri)) {
				this._recomputeState();
			}
		}));

		this._recomputeState();
		installSelectionListener();

		const options: IWorkbenchDataTreeOptions<OutlineEntry, FuzzyScore> = {
			collapseByDefault: _target === OutlineTarget.Breadcrumbs || (_target === OutlineTarget.OutlinePane && _configurationService.getValue(OutlineConfigKeys.collapseItems) === OutlineConfigCollapseItemsValues.Collapsed),
			expandOnlyOnTwistieClick: true,
			multipleSelectionSupport: false,
			accessibilityProvider: new NotebookOutlineAccessibility(),
			identityProvider: { getId: element => element.cell.id },
			keyboardNavigationLabelProvider: new NotebookNavigationLabelProvider()
		};

		const treeDataSource: IDataSource<this, OutlineEntry> = { getChildren: parent => parent instanceof NotebookCellOutline ? this._entries : parent.children };
		const delegate = new NotebookOutlineVirtualDelegate();
		const renderers = [instantiationService.createInstance(NotebookOutlineRenderer)];
		const comparator = new NotebookComparator();

		this.config = {
			breadcrumbsDataSource: {
				getBreadcrumbElements: () => {
					const result: OutlineEntry[] = [];
					let candidate = this._activeEntry;
					while (candidate) {
						result.unshift(candidate);
						candidate = candidate.parent;
					}
					return result;
				}
			},
			quickPickDataSource: instantiationService.createInstance(NotebookQuickPickProvider, () => this._entries),
			treeDataSource,
			delegate,
			renderers,
			comparator,
			options
		};
	}