src/vs/workbench/contrib/feedback/browser/feedback.ts/FeedbackWidget/renderContents
class FeedbackWidget:	private renderContents(container: HTMLElement): IDisposable {
		const disposables = new DisposableStore();

		container.classList.add('monaco-menu-container');

		// Form
		this.feedbackForm = append<HTMLFormElement>(container, $('form.feedback-form'));
		this.feedbackForm.setAttribute('action', 'javascript:void(0);');

		// Title
		append(this.feedbackForm, $('h2.title')).textContent = localize("label.sendASmile", "Tweet us your feedback.");

		// Close Button (top right)
		const closeBtn = append(this.feedbackForm, $(`div.cancel${Codicon.close.cssSelector}`));
		closeBtn.tabIndex = 0;
		closeBtn.setAttribute('role', 'button');
		closeBtn.title = localize('close', "Close");

		disposables.add(addDisposableListener(container, EventType.KEY_DOWN, keyboardEvent => {
			const standardKeyboardEvent = new StandardKeyboardEvent(keyboardEvent);
			if (standardKeyboardEvent.keyCode === KeyCode.Escape) {
				this.hide();
			}
		}));

		disposables.add(addDisposableListener(closeBtn, EventType.MOUSE_OVER, () => {
			const theme = this.themeService.getColorTheme();
			let darkenFactor: number | undefined;
			switch (theme.type) {
				case 'light':
					darkenFactor = 0.1;
					break;
				case 'dark':
					darkenFactor = 0.2;
					break;
			}

			if (darkenFactor) {
				const backgroundBaseColor = theme.getColor(editorWidgetBackground);
				if (backgroundBaseColor) {
					const backgroundColor = backgroundBaseColor.darken(darkenFactor);
					if (backgroundColor) {
						closeBtn.style.backgroundColor = backgroundColor.toString();
					}
				}
			}
		}));

		disposables.add(addDisposableListener(closeBtn, EventType.MOUSE_OUT, () => {
			closeBtn.style.backgroundColor = '';
		}));

		this.invoke(closeBtn, disposables, () => this.hide());

		// Content
		const content = append(this.feedbackForm, $('div.content'));

		// Sentiment Buttons
		const sentimentContainer = append(content, $('div'));

		if (!this.isPure) {
			append(sentimentContainer, $('span')).textContent = localize("patchedVersion1", "Your installation is corrupt.");
			sentimentContainer.appendChild(document.createElement('br'));
			append(sentimentContainer, $('span')).textContent = localize("patchedVersion2", "Please specify this if you submit a bug.");
			sentimentContainer.appendChild(document.createElement('br'));
		}

		append(sentimentContainer, $('span')).textContent = localize("sentiment", "How was your experience?");

		const feedbackSentiment = append(sentimentContainer, $('div.feedback-sentiment'));

		// Sentiment: Smiley
		this.smileyInput = append(feedbackSentiment, $('div.sentiment'));
		this.smileyInput.classList.add('smile');
		this.smileyInput.setAttribute('aria-checked', 'false');
		this.smileyInput.setAttribute('aria-label', localize('smileCaption', "Happy Feedback Sentiment"));
		this.smileyInput.setAttribute('role', 'checkbox');
		this.smileyInput.title = localize('smileCaption', "Happy Feedback Sentiment");
		this.smileyInput.tabIndex = 0;

		this.invoke(this.smileyInput, disposables, () => this.setSentiment(true));

		// Sentiment: Frowny
		this.frownyInput = append(feedbackSentiment, $('div.sentiment'));
		this.frownyInput.classList.add('frown');
		this.frownyInput.setAttribute('aria-checked', 'false');
		this.frownyInput.setAttribute('aria-label', localize('frownCaption', "Sad Feedback Sentiment"));
		this.frownyInput.setAttribute('role', 'checkbox');
		this.frownyInput.title = localize('frownCaption', "Sad Feedback Sentiment");
		this.frownyInput.tabIndex = 0;

		this.invoke(this.frownyInput, disposables, () => this.setSentiment(false));

		if (this.sentiment === 1) {
			this.smileyInput.classList.add('checked');
			this.smileyInput.setAttribute('aria-checked', 'true');
		} else {
			this.frownyInput.classList.add('checked');
			this.frownyInput.setAttribute('aria-checked', 'true');
		}

		// Contact Us Box
		const contactUsContainer = append(content, $('div.contactus'));

		append(contactUsContainer, $('span')).textContent = localize("other ways to contact us", "Other ways to contact us");

		const channelsContainer = append(contactUsContainer, $('div.channels'));

		// Contact: Submit a Bug
		const submitBugLinkContainer = append(channelsContainer, $('div'));

		const submitBugLink = append(submitBugLinkContainer, $('a'));
		submitBugLink.setAttribute('target', '_blank');
		submitBugLink.setAttribute('href', '#');
		submitBugLink.textContent = localize("submit a bug", "Submit a bug");
		submitBugLink.tabIndex = 0;

		disposables.add(addDisposableListener(submitBugLink, 'click', e => {
			EventHelper.stop(e);
			const actionId = 'workbench.action.openIssueReporter';
			this.commandService.executeCommand(actionId);
			this.hide();
			this.telemetryService.publicLog2<WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification>('workbenchActionExecuted', { id: actionId, from: 'feedback' });
		}));

		// Contact: Request a Feature
		if (!!this.requestFeatureLink) {
			const requestFeatureLinkContainer = append(channelsContainer, $('div'));

			const requestFeatureLink = append(requestFeatureLinkContainer, $('a'));
			requestFeatureLink.setAttribute('target', '_blank');
			requestFeatureLink.setAttribute('href', this.requestFeatureLink);
			requestFeatureLink.textContent = localize("request a missing feature", "Request a missing feature");
			requestFeatureLink.tabIndex = 0;

			disposables.add(addDisposableListener(requestFeatureLink, 'click', e => this.hide()));
		}

		// Remaining Characters
		const remainingCharacterCountContainer = append(this.feedbackForm, $('h3'));
		remainingCharacterCountContainer.textContent = localize("tell us why", "Tell us why?");

		this.remainingCharacterCount = append(remainingCharacterCountContainer, $('span.char-counter'));
		this.remainingCharacterCount.textContent = this.getCharCountText(0);

		// Feedback Input Form
		this.feedbackDescriptionInput = append<HTMLTextAreaElement>(this.feedbackForm, $('textarea.feedback-description'));
		this.feedbackDescriptionInput.rows = 3;
		this.feedbackDescriptionInput.maxLength = this.maxFeedbackCharacters;
		this.feedbackDescriptionInput.textContent = this.feedback;
		this.feedbackDescriptionInput.required = true;
		this.feedbackDescriptionInput.setAttribute('aria-label', localize("feedbackTextInput", "Tell us your feedback"));
		this.feedbackDescriptionInput.focus();

		disposables.add(addDisposableListener(this.feedbackDescriptionInput, 'keyup', () => this.updateCharCountText()));

		// Feedback Input Form Buttons Container
		const buttonsContainer = append(this.feedbackForm, $('div.form-buttons'));

		// Checkbox: Hide Feedback Smiley
		const hideButtonContainer = append(buttonsContainer, $('div.hide-button-container'));

		this.hideButton = append(hideButtonContainer, $('input.hide-button')) as HTMLInputElement;
		this.hideButton.type = 'checkbox';
		this.hideButton.checked = true;
		this.hideButton.id = 'hide-button';

		const hideButtonLabel = append(hideButtonContainer, $('label'));
		hideButtonLabel.setAttribute('for', 'hide-button');
		hideButtonLabel.textContent = localize('showFeedback', "Show Feedback Icon in Status Bar");

		// Button: Send Feedback
		this.sendButton = new Button(buttonsContainer);
		this.sendButton.enabled = false;
		this.sendButton.label = localize('tweet', "Tweet");
		prepend(this.sendButton.element, $(`span${Codicon.twitter.cssSelector}`));
		this.sendButton.element.classList.add('send');
		this.sendButton.element.title = localize('tweetFeedback', "Tweet Feedback");
		disposables.add(attachButtonStyler(this.sendButton, this.themeService));

		this.sendButton.onDidClick(() => this.onSubmit());

		disposables.add(attachStylerCallback(this.themeService, { widgetShadow, editorWidgetBackground, editorWidgetForeground, inputBackground, inputForeground, inputBorder, editorBackground, contrastBorder }, colors => {
			if (this.feedbackForm) {
				this.feedbackForm.style.backgroundColor = colors.editorWidgetBackground ? colors.editorWidgetBackground.toString() : '';
				this.feedbackForm.style.color = colors.editorWidgetForeground ? colors.editorWidgetForeground.toString() : '';
				this.feedbackForm.style.boxShadow = colors.widgetShadow ? `0 0 8px 2px ${colors.widgetShadow}` : '';
			}
			if (this.feedbackDescriptionInput) {
				this.feedbackDescriptionInput.style.backgroundColor = colors.inputBackground ? colors.inputBackground.toString() : '';
				this.feedbackDescriptionInput.style.color = colors.inputForeground ? colors.inputForeground.toString() : '';
				this.feedbackDescriptionInput.style.border = `1px solid ${colors.inputBorder || 'transparent'}`;
			}

			contactUsContainer.style.backgroundColor = colors.editorBackground ? colors.editorBackground.toString() : '';
			contactUsContainer.style.border = `1px solid ${colors.contrastBorder || 'transparent'}`;
		}));

		return {
			dispose: () => {
				this.feedbackForm = undefined;
				this.feedbackDescriptionInput = undefined;
				this.smileyInput = undefined;
				this.frownyInput = undefined;

				disposables.dispose();
			}
		};
	}