// Internal so we can mock.  Need to call this a lot and
        public TenantInformation FindTenantInAccount(Account account, string tenantId,
                                                     VSAccountProvider provider)
        {
            var tenantsInScope = provider.GetTenantsInScope(account);

            return(tenantsInScope.FirstOrDefault(tenant => tenant.TenantId == tenantId));
        }
        // Logic shows UI and interacts with all mocked methods.  Mocking this as well.
        public async Task <ICredentials> PromptUserForAccount(
            string tenentId,
            VSAccountProvider provider,
            bool nonInteractive,
            CancellationToken cancellationToken)
        {
            ICredentials ret = null;

            if (nonInteractive)
            {
                //  If we are not supposed to interact with the user then we can't prompt for account so we
                // need to fail.
                throw new InvalidOperationException(Strings.AccountProvider_TriedToShowUIOnNonInteractive);
            }
            Account account = null;

            NuGetUIThreadHelper.JoinableTaskFactory.Run(async() =>
            {
                await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
                var parent = IntPtr.Zero;
                if (_dte != null)
                {
                    parent = new IntPtr(_dte.MainWindow.HWnd);
                }

                account = await provider.CreateAccountWithUIAsync(parent, cancellationToken);
            });

            var tenant = FindTenantInAccount(account, tenentId, provider);

            if (tenant != null)
            {
                ret = await GetTokenFromAccount(
                    new AccountAndTenant(account, tenant),
                    provider,
                    false,
                    cancellationToken);
            }

            return(ret);
        }
        // Logic goes between UI and web.  made internal to be mocked for unit tests
        public async Task <ICredentials> GetTokenFromAccount(
            AccountAndTenant account,
            VSAccountProvider provider,
            bool nonInteractive,
            CancellationToken cancellationToken)
        {
            // get the ADAL creds for the user account
            var uniqueId = account.TenantToUse.UniqueIds.First();
            var tenantId = account.TenantToUse.TenantId;

            // we are passed the flag as non-interactive.  we realy want to know if we should prompt so
            // need to reverse the flag
            var shouldPrompt            = !nonInteractive;
            AuthenticationResult result = null;

            NuGetUIThreadHelper.JoinableTaskFactory.Run(async() =>
            {
                await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                var parent = IntPtr.Zero;
                if (_dte != null)
                {
                    parent = new IntPtr(_dte.MainWindow.HWnd);
                }

                try
                {
                    result = await provider.AcquireAdalTokenAsync(
                        resource: VsoEndpointResource,
                        tenantId: tenantId,
                        identitifer: new UserIdentifier(uniqueId, UserIdentifierType.UniqueId),
                        parentWindowHandle: parent,
                        accountKeyForReAuthentication: account.UserAccount,
                        prompt: shouldPrompt,
                        cancellationToken: cancellationToken);
                }
                catch (AdalSilentTokenAcquisitionException)
                {
                    result = null;
                }
            });

            if (result == null)
            {
                return(null);
            }

            var aadcred = new VssAadCredential(new VssAadToken(result));

            // create the session token
            var connection      = new VssConnection(AccountManager.VsoEndpoint, aadcred);
            var delegatedClient = connection.GetClient <DelegatedAuthorizationHttpClient>();

            // Create a scoped session token to the endpoint
            var sessionToken = await delegatedClient.CreateSessionToken(
                cancellationToken : cancellationToken,
                scope : SessionTokenScope);

            var cred = new NetworkCredential
            {
                UserName = account.UserAccount.DisplayInfo.UserName,
                Password = sessionToken.Token
            };

            return(cred);
        }