public static IdentityServerServiceFactory Create(
                    string issuerUri, string siteName, string publicHostAddress = "")
        {
            var settings = new LocalTestCoreSettings(issuerUri, siteName, publicHostAddress);
            
            var codeStore = new InMemoryAuthorizationCodeStore();
            var tokenStore = new InMemoryTokenHandleStore();
            var consent = new InMemoryConsentService();
            var scopes = new InMemoryScopeService(LocalTestScopes.Get());
            var clients = new InMemoryClientService(LocalTestClients.Get());
            var logger = new TraceLogger();

            var users = new InMemoryUser[]
            {
                new InMemoryUser{Subject = "alice", Username = "******", Password = "******", 
                    Claims = new Claim[]
                    {
                        new Claim(Constants.ClaimTypes.GivenName, "Alice"),
                        new Claim(Constants.ClaimTypes.FamilyName, "Smith"),
                        new Claim(Constants.ClaimTypes.Email, "*****@*****.**"),
                    }
                },
                new InMemoryUser{Subject = "bob", Username = "******", Password = "******", 
                    Claims = new Claim[]
                    {
                        new Claim(Constants.ClaimTypes.GivenName, "Bob"),
                        new Claim(Constants.ClaimTypes.FamilyName, "Smith"),
                        new Claim(Constants.ClaimTypes.Email, "*****@*****.**"),
                    }
                },
            };
            var userSvc = new InMemoryUserService(users);

            var fact = new IdentityServerServiceFactory
            {
                Logger = () => logger,
                UserService = () => userSvc,
                AuthorizationCodeStore = () => codeStore,
                TokenHandleStore = () => tokenStore,
                CoreSettings = () => settings,
                ConsentService = () => consent,
                ScopeService = () => scopes,
                ClientService = () => clients
            };

            return fact;
        }
        public static IContainer Configure(IdentityServerOptions options, InternalConfiguration internalConfig)
        {
            if (options == null) throw new ArgumentNullException("options");
            if (options.Factory == null) throw new InvalidOperationException("null factory");
            if (internalConfig == null) throw new ArgumentNullException("internalConfig");

            IdentityServerServiceFactory fact = options.Factory;
            fact.Validate();

            var builder = new ContainerBuilder();

            builder.RegisterInstance(internalConfig).AsSelf();

            // mandatory from factory
            builder.Register(fact.UserService);
            builder.Register(fact.ScopeService);
            builder.Register(fact.ClientService);
            builder.Register(fact.CoreSettings);
            
            // optional from factory
            if (fact.AuthorizationCodeStore != null)
            {
                builder.Register(fact.AuthorizationCodeStore);
            }
            else
            {
                var inmemCodeStore = new InMemoryAuthorizationCodeStore();
                builder.RegisterInstance(inmemCodeStore).As<IAuthorizationCodeStore>();
            }

            if (fact.TokenHandleStore != null)
            {
                builder.Register(fact.TokenHandleStore);
            }
            else
            {
                var inmemTokenHandleStore = new InMemoryTokenHandleStore();
                builder.RegisterInstance(inmemTokenHandleStore).As<ITokenHandleStore>();
            }

            if (fact.RefreshTokenStore != null)
            {
                builder.Register(fact.RefreshTokenStore);
            }
            else
            {
                var inmemRefreshTokenStore = new InMemoryRefreshTokenStore();
                builder.RegisterInstance(inmemRefreshTokenStore).As<IRefreshTokenStore>();
            }

            if (fact.ConsentService != null)
            {
                builder.Register(fact.ConsentService);
            }
            else
            {
                var inmemConsentService = new InMemoryConsentService();
                builder.RegisterInstance(inmemConsentService).As<IConsentService>();
            }

            if (fact.ClaimsProvider != null)
            {
                builder.Register(fact.ClaimsProvider);
            }
            else
            {
                builder.RegisterType<DefaultClaimsProvider>().As<IClaimsProvider>();
            }

            if (fact.TokenService != null)
            {
                builder.Register(fact.TokenService);
            }
            else
            {
                builder.RegisterType<DefaultTokenService>().As<ITokenService>();
            }

            if (fact.RefreshTokenService != null)
            {
                builder.Register(fact.RefreshTokenService);
            }
            else
            {
                builder.RegisterType<DefaultRefreshTokenService>().As<IRefreshTokenService>();
            }

            if (fact.TokenSigningService != null)
            {
                builder.Register(fact.TokenSigningService);
            }
            else
            {
                builder.RegisterType<DefaultTokenSigningService>().As<ITokenSigningService>();
            }

            if (fact.CustomRequestValidator != null)
            {
                builder.Register(fact.CustomRequestValidator);
            }
            else
            {
                builder.RegisterType<DefaultCustomRequestValidator>().As<ICustomRequestValidator>();
            }

            if (fact.AssertionGrantValidator != null)
            {
                builder.Register(fact.AssertionGrantValidator);
            }
            else
            {
                builder.RegisterType<DefaultAssertionGrantValidator>().As<IAssertionGrantValidator>();
            }

            if (fact.ExternalClaimsFilter != null)
            {
                builder.Register(fact.ExternalClaimsFilter);
            }
            else
            {
                builder.RegisterType<DefaultExternalClaimsFilter>().As<IExternalClaimsFilter>();
            }

            if (fact.CustomTokenValidator != null)
            {
                builder.Register(fact.CustomTokenValidator);
            }
            else
            {
                builder.RegisterType<DefaultCustomTokenValidator>().As<ICustomTokenValidator>();
            }

            // validators
            builder.RegisterType<TokenRequestValidator>();
            builder.RegisterType<AuthorizeRequestValidator>();
            builder.RegisterType<ClientValidator>();
            builder.RegisterType<TokenValidator>();

            // processors
            builder.RegisterType<TokenResponseGenerator>();
            builder.RegisterType<AuthorizeResponseGenerator>();
            builder.RegisterType<AuthorizeInteractionResponseGenerator>();
            builder.RegisterType<UserInfoResponseGenerator>();

            // general services
            builder.RegisterType<CookieMiddlewareTrackingCookieService>().As<ITrackingCookieService>();

            // for authentication
            var authenticationOptions = options.AuthenticationOptions ?? new AuthenticationOptions();
            builder.RegisterInstance(authenticationOptions).AsSelf();

            // load core controller
            builder.RegisterApiControllers(typeof(AuthorizeEndpointController).Assembly);

            // add any additional dependencies from hosting application
            foreach(var registration in fact.Registrations)
            {
                builder.Register(registration);
            }

            return builder.Build();
        }