public static void DeleteCredentials(Program program, OperationArguments operationArguments)
        {
            if (ReferenceEquals(operationArguments, null))
            {
                throw new ArgumentNullException("operationArguments");
            }

            var task = Task.Run(async() => { return(await program.CreateAuthentication(operationArguments)); });

            BaseAuthentication authentication = task.Result;

            switch (operationArguments.Authority)
            {
            default:
            case AuthorityType.Basic:
                Git.Trace.WriteLine($"deleting basic credentials for '{operationArguments.TargetUri}'.");
                authentication.DeleteCredentials(operationArguments.TargetUri);
                break;

            case AuthorityType.AzureDirectory:
            case AuthorityType.MicrosoftAccount:
                Git.Trace.WriteLine($"deleting VSTS credentials for '{operationArguments.TargetUri}'.");
                BaseVstsAuthentication vstsAuth = authentication as BaseVstsAuthentication;
                vstsAuth.DeleteCredentials(operationArguments.TargetUri);
                break;

            case AuthorityType.GitHub:
                Git.Trace.WriteLine($"deleting GitHub credentials for '{operationArguments.TargetUri}'.");
                Github.Authentication ghAuth = authentication as Github.Authentication;
                ghAuth.DeleteCredentials(operationArguments.TargetUri);
                break;

            case AuthorityType.Bitbucket:
                Git.Trace.WriteLine($"deleting Bitbucket credentials for '{operationArguments.TargetUri}'.");
                var bbAuth = authentication as Bitbucket.Authentication;
                bbAuth.DeleteCredentials(operationArguments.TargetUri, operationArguments.CredUsername);
                break;
            }
        }
        public static Credential QueryCredentials(Program program, OperationArguments operationArguments)
        {
            if (ReferenceEquals(operationArguments, null))
            {
                throw new ArgumentNullException(nameof(operationArguments));
            }
            if (ReferenceEquals(operationArguments.TargetUri, null))
            {
                throw new ArgumentException("TargetUri property returned null", nameof(operationArguments));
            }

            var task = Task.Run(async() => { return(await program.CreateAuthentication(operationArguments)); });
            BaseAuthentication authentication = task.Result;
            Credential         credentials    = null;

            switch (operationArguments.Authority)
            {
            default:
            case AuthorityType.Basic:
            {
                BasicAuthentication basicAuth = authentication as BasicAuthentication;

                Task.Run(async() =>
                    {
                        // attempt to get cached creds or acquire creds if interactivity is allowed
                        if ((operationArguments.Interactivity != Interactivity.Always &&
                             (credentials = authentication.GetCredentials(operationArguments.TargetUri)) != null) ||
                            (operationArguments.Interactivity != Interactivity.Never &&
                             (credentials = await basicAuth.AcquireCredentials(operationArguments.TargetUri)) != null))
                        {
                            Git.Trace.WriteLine("credentials found.");
                            // no need to save the credentials explicitly, as Git will call back with
                            // a store command if the credentials are valid.
                        }
                        else
                        {
                            Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found.");
                            program.LogEvent($"Failed to retrieve credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit);
                        }
                    }).Wait();
            }
            break;

            case AuthorityType.AzureDirectory:
            {
                VstsAadAuthentication aadAuth = authentication as VstsAadAuthentication;

                Task.Run(async() =>
                    {
                        // attempt to get cached creds -> non-interactive logon -> interactive
                        // logon note that AAD "credentials" are always scoped access tokens
                        if (((operationArguments.Interactivity != Interactivity.Always &&
                              ((credentials = aadAuth.GetCredentials(operationArguments.TargetUri)) != null) &&
                              (!operationArguments.ValidateCredentials ||
                               await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) ||
                            (operationArguments.Interactivity != Interactivity.Always &&
                             ((credentials = await aadAuth.NoninteractiveLogon(operationArguments.TargetUri, true)) != null) &&
                             (!operationArguments.ValidateCredentials ||
                              await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) ||
                            (operationArguments.Interactivity != Interactivity.Never &&
                             ((credentials = await aadAuth.InteractiveLogon(operationArguments.TargetUri, true)) != null) &&
                             (!operationArguments.ValidateCredentials ||
                              await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials))))
                        {
                            Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found.");
                            program.LogEvent($"Azure Directory credentials  for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit);
                        }
                        else
                        {
                            Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found.");
                            program.LogEvent($"Failed to retrieve Azure Directory credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit);
                        }
                    }).Wait();
            }
            break;

            case AuthorityType.MicrosoftAccount:
            {
                VstsMsaAuthentication msaAuth = authentication as VstsMsaAuthentication;

                Task.Run(async() =>
                    {
                        // attempt to get cached creds -> interactive logon note that MSA
                        // "credentials" are always scoped access tokens
                        if (((operationArguments.Interactivity != Interactivity.Always &&
                              ((credentials = msaAuth.GetCredentials(operationArguments.TargetUri)) != null) &&
                              (!operationArguments.ValidateCredentials ||
                               await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) ||
                            (operationArguments.Interactivity != Interactivity.Never &&
                             ((credentials = await msaAuth.InteractiveLogon(operationArguments.TargetUri, true)) != null) &&
                             (!operationArguments.ValidateCredentials ||
                              await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials))))
                        {
                            Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found.");
                            program.LogEvent($"Microsoft Live credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit);
                        }
                        else
                        {
                            Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found.");
                            program.LogEvent($"Failed to retrieve Microsoft Live credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit);
                        }
                    }).Wait();
            }
            break;

            case AuthorityType.GitHub:
            {
                Github.Authentication ghAuth = authentication as Github.Authentication;

                Task.Run(async() =>
                    {
                        if ((operationArguments.Interactivity != Interactivity.Always &&
                             ((credentials = ghAuth.GetCredentials(operationArguments.TargetUri)) != null) &&
                             (!operationArguments.ValidateCredentials ||
                              await ghAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) ||
                            (operationArguments.Interactivity != Interactivity.Never &&
                             ((credentials = await ghAuth.InteractiveLogon(operationArguments.TargetUri)) != null) &&
                             (!operationArguments.ValidateCredentials ||
                              await ghAuth.ValidateCredentials(operationArguments.TargetUri, credentials))))
                        {
                            Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found.");
                            program.LogEvent($"GitHub credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit);
                        }
                        else
                        {
                            Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found.");
                            program.LogEvent($"Failed to retrieve GitHub credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit);
                        }
                    }).Wait();
            }
            break;

            case AuthorityType.Bitbucket:
            {
                var bbcAuth = authentication as Bitbucket.Authentication;

                Task.Run(async() =>
                    {
                        if (((operationArguments.Interactivity != Interactivity.Always) &&
                             ((credentials = bbcAuth.GetCredentials(operationArguments.TargetUri, operationArguments.CredUsername)) != null) &&
                             (!operationArguments.ValidateCredentials ||
                              ((credentials = await bbcAuth.ValidateCredentials(operationArguments.TargetUri, operationArguments.CredUsername, credentials)) != null))) ||
                            ((operationArguments.Interactivity != Interactivity.Never) &&
                             ((credentials = await bbcAuth.InteractiveLogon(operationArguments.TargetUri, operationArguments.CredUsername)) != null) &&
                             (!operationArguments.ValidateCredentials ||
                              ((credentials = await bbcAuth.ValidateCredentials(operationArguments.TargetUri, operationArguments.CredUsername, credentials)) != null))))
                        {
                            Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found.");
                            // Bitbucket relies on a username + secret, so make sure there is a
                            // username to return
                            if (operationArguments.CredUsername != null)
                            {
                                credentials = new Credential(operationArguments.CredUsername, credentials.Password);
                            }
                            program.LogEvent($"Bitbucket credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit);
                        }
                        else
                        {
                            program.LogEvent($"Failed to retrieve Bitbucket credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit);
                        }
                    }).Wait();
            }
            break;

            case AuthorityType.Ntlm:
            {
                Git.Trace.WriteLine($"'{operationArguments.TargetUri}' is NTLM.");
                credentials = BasicAuthentication.NtlmCredentials;
            }
            break;
            }

            if (credentials != null)
            {
                operationArguments.SetCredentials(credentials);
            }

            return(credentials);
        }