src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts/NotebookEditorManager/constructor
class NotebookEditorManager:	constructor(
		@IEditorService private readonly _editorService: IEditorService,
		@INotebookEditorModelResolverService private readonly _notebookEditorModelService: INotebookEditorModelResolverService,
		@INotebookService notebookService: INotebookService,
		@IEditorGroupsService editorGroups: IEditorGroupsService,
	) {

		// OPEN notebook editor for models that have turned dirty without being visible in an editor
		type E = IResolvedNotebookEditorModel;
		this._disposables.add(Event.debounce<E, E[]>(
			this._notebookEditorModelService.onDidChangeDirty,
			(last, current) => !last ? [current] : [...last, current],
			100
		)(this._openMissingDirtyNotebookEditors, this));

		// CLOSE notebook editor for models that have no more serializer
		this._disposables.add(notebookService.onWillRemoveViewType(e => {
			for (const group of editorGroups.groups) {
				const staleInputs = group.editors.filter(input => input instanceof NotebookEditorInput && input.viewType === e);
				group.closeEditors(staleInputs);
			}
		}));

		// CLOSE editors when we are about to open conflicting notebooks
		this._disposables.add(_notebookEditorModelService.onWillFailWithConflict(e => {
			for (const group of editorGroups.groups) {
				const conflictInputs = group.editors.filter(input => input instanceof NotebookEditorInput && input.viewType !== e.viewType && isEqual(input.resource, e.resource));
				const p = group.closeEditors(conflictInputs);
				e.waitUntil(p);
			}
		}));
	}