public async Task<IOpenIdClientRegistration> AddAsync(IOpenIdClientMetadata clientMetadata) {
            using (var db = new ClientConfigurationDbContext(options.ConnectionString, options.Schema)) {
                string clientId = await clientIdGenerator.GenerateClientIdAsync(db);
                
                var registration = new OpenIdClientRegistration(clientId) {
                    ClientIdIssuedAtUtc = DateTime.UtcNow
                };

                var client = new Client() {
                    ClientId = clientId,
                    ClientName = clientMetadata.ClientName,
                    RedirectUris = clientMetadata.RedirectUris.ToList(),
                    Flow = GetFlows(clientMetadata.ResponseTypes),
                    LogoUri = clientMetadata.LogoUri,
                    ClientUri = clientMetadata.ClientUri
                };

                if (IsSecretRequired(client.Flow)) {
                    var secret = await secretGenerator.GenerateSecretAsync(db);
                    
                    client.ClientSecrets = new List<Secret> { secret };

                    registration.ClientSecret = secret.Value;
                }
                
                var e = client.ToEntity();
                
                db.Clients.Add(e);
                               
                await db.SaveChangesAsync();
                
                return registration;
            }
        }
        public Task<ValidationResult> ValidateAsync(IOpenIdClientMetadata metadata) {
            if (metadata.RedirectUris == null || !metadata.RedirectUris.Any() || metadata.RedirectUris.Any(uri => !IsUri(uri))) {
                return Task.FromResult(new ValidationResult(RegistrationErrorType.InvalidRedirectUri));
            }
            //TODO: MOAR Validation - http://openid.net/specs/openid-connect-registration-1_0.html#ClientMetadata

            // Check RedirectUris based on application type


            // Response types are valid
            // Grant Types are valid
                                   

            return Task.FromResult(new ValidationResult());
        }
        public async Task<IOpenIdClientRegistrationResult> RegisterClientAsync(IOpenIdClientMetadata metadata) {

            //TODO: update supplied metadata (where allowed) based on rules
            if (metadata.ResponseTypes == null || metadata.ResponseTypes.Any()) {
                metadata.ResponseTypes = new string[] { Constants.ResponseTypes.Code };
            }

            var validationResult = await validator.ValidateAsync(metadata);

            if(!validationResult.Success) {
                return new OpenIdClientRegistrationResult(validationResult.ErrorType, validationResult.Description);
            }
            
            var registration = await store.AddAsync(metadata);

            return new OpenIdClientRegistrationResult(metadata, registration);
        }
 public OpenIdClientRegistrationResult(IOpenIdClientMetadata metadata, IOpenIdClientRegistration registration) {
     this.ClientMetadata = metadata;
     this.ClientRegistration = registration;
     this.Success = true;
 }