public async Task <TResult> RedeemTokenAsync <TResult>(IDictionary <string, string> tokens,
                                                               Func <string, Guid?, Guid?, IDictionary <string, string>, TResult> onSuccess,
                                                               Func <Guid?, IDictionary <string, string>, TResult> onUnauthenticated,
                                                               Func <string, TResult> onInvalidCredentials,
                                                               Func <string, TResult> onCouldNotConnect,
                                                               Func <string, TResult> onUnspecifiedConfiguration,
                                                               Func <string, TResult> onFailure)
        {
            return(await EastFive.Web.Configuration.Settings.GetBase64Bytes(AppSettings.SAMLCertificate,
                                                                            async (certBuffer) =>
            {
                var certificate = new X509Certificate2(certBuffer);
                var m = ((RSACryptoServiceProvider)certificate.PrivateKey);
                AsymmetricAlgorithm trustedSigner = m;     // AsymmetricAlgorithm.Create(certificate.GetKeyAlgorithm()
                var trustedSigners = default(AsymmetricAlgorithm) == trustedSigner ? null : trustedSigner.AsEnumerable();

                try
                {
                    var nameId = tokens[SAMLProvider.SamlNameIDKey];

                    return EastFive.Web.Configuration.Settings.GetString(AppSettings.SAMLLoginIdAttributeName,
                                                                         (attributeName) =>
                    {
                        //var attributes = assertion.Attributes
                        //    .Where(attribute => attribute.Name.CompareTo(attributeName) == 0)
                        //    .ToArray();
                        //if (attributes.Length == 0)
                        //    return invalidCredentials($"SAML assertion does not contain an attribute with name [{attributeName}] which is necessary to operate with this system");
                        //Guid authId;
                        //if (!Guid.TryParse(attributes[0].AttributeValue.First(), out authId))
                        //    return invalidCredentials("User's auth identifier is not a guid.");

                        var hash = SHA512.Create().ComputeHash(System.Text.Encoding.UTF8.GetBytes(nameId));
                        var loginId = new Guid(hash.Take(16).ToArray());

                        return onSuccess(nameId, default(Guid?), loginId, new Dictionary <string, string>());        // TODO: Build this from params above
                    },
                                                                         (why) => onUnspecifiedConfiguration(why));
                } catch (Exception ex)
                {
                    return await onInvalidCredentials("SAML Assertion parse and validate failed").ToTask();
                }
            },
                                                                            (why) => onUnspecifiedConfiguration(why).ToTask()));
        }