extensions/ipynb/src/notebookAttachmentCleaner.ts/AttachmentCleaner/constructor
class AttachmentCleaner:	constructor() {
		this._disposables = [];
		const debounceTrigger = new DebounceTrigger<AttachmentCleanRequest>({
			callback: (change: AttachmentCleanRequest) => {
				this.cleanNotebookAttachments(change);
			},
			delay: 500
		});

		this._imageDiagnosticCollection = vscode.languages.createDiagnosticCollection('Notebook Image Attachment');
		this._disposables.push(this._imageDiagnosticCollection);

		this._disposables.push(vscode.commands.registerCommand(ATTACHMENT_CLEANUP_COMMANDID, async (document: vscode.Uri, range: vscode.Range) => {
			const workspaceEdit = new vscode.WorkspaceEdit();
			workspaceEdit.delete(document, range);
			await vscode.workspace.applyEdit(workspaceEdit);
		}));

		this._disposables.push(vscode.languages.registerCodeActionsProvider(JUPYTER_NOTEBOOK_MARKDOWN_SELECTOR, this, {
			providedCodeActionKinds: [
				vscode.CodeActionKind.QuickFix
			],
		}));

		this._disposables.push(vscode.workspace.onDidChangeNotebookDocument(e => {
			e.cellChanges.forEach(change => {
				if (!change.document) {
					return;
				}

				if (change.cell.kind !== vscode.NotebookCellKind.Markup) {
					return;
				}

				debounceTrigger.trigger({
					notebook: e.notebook,
					cell: change.cell,
					document: change.document
				});
			});
		}));

		this._disposables.push(vscode.workspace.onDidCloseNotebookDocument(e => {
			this._attachmentCache.delete(e.uri.toString());
		}));

		this._disposables.push(vscode.workspace.onWillRenameFiles(e => {
			const re = /\.ipynb$/;
			for (const file of e.files) {
				if (!re.exec(file.oldUri.toString())) {
					continue;
				}

				// transfer cache to new uri
				if (this._attachmentCache.has(file.oldUri.toString())) {
					this._attachmentCache.set(file.newUri.toString(), this._attachmentCache.get(file.oldUri.toString())!);
					this._attachmentCache.delete(file.oldUri.toString());
				}
			}
		}));

		this._disposables.push(vscode.workspace.onDidOpenTextDocument(e => {
			this.analyzeMissingAttachments(e);
		}));

		this._disposables.push(vscode.workspace.onDidCloseTextDocument(e => {
			this.analyzeMissingAttachments(e);
		}));

		vscode.workspace.textDocuments.forEach(document => {
			this.analyzeMissingAttachments(document);
		});
	}