extensions/microsoft-authentication/src/AADHelper.ts/AzureActiveDirectoryService/doRefreshToken
class AzureActiveDirectoryService:	private async doRefreshToken(refreshToken: string, scopeData: IScopeData, sessionId?: string): Promise<IToken> {
		Logger.info(`Refreshing token for scopes: ${scopeData.scopeStr}`);
		const postData = querystring.stringify({
			refresh_token: refreshToken,
			client_id: scopeData.clientId,
			grant_type: 'refresh_token',
			scope: scopeData.scopesToSend
		});

		const proxyEndpoints: { [providerId: string]: string } | undefined = await vscode.commands.executeCommand('workbench.getCodeExchangeProxyEndpoints');
		const endpointUrl = proxyEndpoints?.microsoft || loginEndpointUrl;
		const endpoint = `${endpointUrl}${scopeData.tenant}/oauth2/v2.0/token`;

		try {
			const json = await this.fetchTokenResponse(endpoint, postData, scopeData);
			const token = this.convertToTokenSync(json, scopeData, sessionId);
			if (token.expiresIn) {
				this.setSessionTimeout(token.sessionId, token.refreshToken, scopeData, token.expiresIn * AzureActiveDirectoryService.REFRESH_TIMEOUT_MODIFIER);
			}
			await this.setToken(token, scopeData);
			Logger.info(`Token refresh success for scopes: ${token.scope}`);
			return token;
		} catch (e) {
			if (e.message === REFRESH_NETWORK_FAILURE) {
				// We were unable to refresh because of a network failure (i.e. the user lost internet access).
				// so set up a timeout to try again later. We only do this if we have a session id to reference later.
				if (sessionId) {
					this.setSessionTimeout(sessionId, refreshToken, scopeData, AzureActiveDirectoryService.POLLING_CONSTANT);
				}
				throw e;
			}
			Logger.error(`Refreshing token failed (for scopes: ${scopeData.scopeStr}): ${e.message}`);
			throw e;
		}
	}