public static async Task <TResult> ProcessAsync <TResult>(Authorization authorization, Func <Authorization, Task> saveAsync, Method authentication, string externalAccountKey, IDictionary <string, string> extraParams, Guid requestId, Uri baseUri, AzureApplication application, IProvideLogin loginProvider, Func <Uri, TResult> onRedirect, Func <string, TResult> onGeneralFailure, TelemetryClient telemetry) { authorization.authorized = true; authorization.LocationAuthentication = null; var result = await await AccountMapping.FindByMethodAndKeyAsync(authentication.authenticationId, externalAccountKey, authorization, // Found async internalAccountId => { authorization.parameters = extraParams; authorization.accountIdMaybe = internalAccountId; await saveAsync(authorization); return(await CreateLoginResponseAsync(requestId, internalAccountId, extraParams, authentication, authorization, baseUri, application, loginProvider, onRedirect, onGeneralFailure, telemetry)); }, // Not found async() => { return(await await UnmappedCredentialAsync(externalAccountKey, extraParams, authentication, authorization, loginProvider, application, baseUri, // Create mapping async(internalAccountId) => { authorization.parameters = extraParams; authorization.accountIdMaybe = internalAccountId; await saveAsync(authorization); return await await AccountMapping.CreateByMethodAndKeyAsync(authorization, externalAccountKey, internalAccountId, () => { return CreateLoginResponseAsync(requestId, internalAccountId, extraParams, authentication, authorization, baseUri, application, loginProvider, onRedirect, onGeneralFailure, telemetry); }, (why) => onGeneralFailure(why).AsTask()); }, // Allow self serve async() => { authorization.parameters = extraParams; await saveAsync(authorization); return await CreateLoginResponseAsync(requestId, default(Guid?), extraParams, authentication, authorization, baseUri, application, loginProvider, onRedirect, onGeneralFailure, telemetry); }, // Intercept process async(interceptionUrl) => { authorization.parameters = extraParams; await saveAsync(authorization); return onRedirect(interceptionUrl); }, // Failure async(why) => { // Save params so they can be used later authorization.parameters = extraParams; await saveAsync(authorization); return onGeneralFailure(why); }, telemetry)); }); return(result); }