/// <summary>
        /// Adds default services to the service collection
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        private static IServiceCollection TryAddDefaultServices(this IServiceCollection services)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));
            services.AddLogging();
            services.AddDataProtection();

            var descriptor = new ServiceDescriptor(typeof(IAuthenticatorDataRepository), typeof(UserProfileAuthenticatorDataRepository), ServiceLifetime.Scoped);
            services.TryAdd(descriptor);

            descriptor = new ServiceDescriptor(typeof(IEnrollmentClient), typeof(EnrollmentClient), ServiceLifetime.Scoped);
            services.TryAdd(descriptor);

            descriptor = new ServiceDescriptor(typeof(IAuthenticator), typeof(Authenticator), ServiceLifetime.Scoped);
            services.TryAdd(descriptor);

            return services;
        }
        /// <summary>
        /// Adds Itasu hostings services to the specified <see cref="IServiceCollection" />.
        /// </summary>
        /// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param>
        /// <returns>A reference to this instance after the operation has completed.</returns>
        public static IServiceCollection AddItasuHosting(this IServiceCollection services)
        {
            services.AddLogging();
            services.AddOptions();
            services.AddLocalization();
            services.AddEntityFrameworkServices();

            services.AddItasuHostingCore();
            services.AddItasuExtensionManagement(options =>
            {
                options.AddModulesLocation("extensions");
                options.AddThemesLocation("themes");
            });

            services.AddItasuMvc();

            return services;
        }
        public static void AddSleeper(this IServiceCollection services, Action<ServiceBrokerApplicationBuilder> setupAction)
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }

            if (setupAction == null)
            {
                throw new ArgumentNullException(nameof(setupAction));
            }

            services.AddLogging();

            var builder = new ServiceBrokerApplicationBuilder(services);

            setupAction(builder);

            services.AddSingleton(builder.Build());
        }
        /// <summary>
        /// Adds default services to the service collection
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        private static void TryAddDefaultServices(this IServiceCollection services)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));
            services.AddLogging();
            services.AddOptions();

            var descriptor = new ServiceDescriptor(typeof(IRegionSelector), DefaultRegionSelector.DefaultInstance);
            services.TryAdd(descriptor);

            descriptor = new ServiceDescriptor(typeof(IBattleNetClient), typeof(BattleNetClient), ServiceLifetime.Scoped);
            services.TryAdd(descriptor);

            descriptor = new ServiceDescriptor(typeof(HttpClient), typeof(HttpClient), ServiceLifetime.Scoped);
            services.TryAdd(descriptor);
        }
        /// <summary>
        /// Configures custom services to add to the ASP.NET MVC 6 Injection of Control (IoC) container.
        /// </summary>
        /// <param name="services">The services collection or IoC container.</param>
        public static void ConfigureCoreServices(this IServiceCollection services)
        {
            #region Antiforgery
            services.ConfigureAntiforgery(
                    antiforgeryOptions =>
                    {
                        // Rename the Anti-Forgery cookie from "__RequestVerificationToken" to "f". This adds a little 
                        // security through obscurity and also saves sending a few characters over the wire. 
                        antiforgeryOptions.CookieName = "f";

                        // Rename the form input name from "__RequestVerificationToken" to "f" for the same reason above 
                        // e.g. <input name="__RequestVerificationToken" type="hidden" value="..." />
                        antiforgeryOptions.FormFieldName = "f";

                        // If you have enabled SSL/TLS. Uncomment this line to ensure that the Anti-Forgery cookie requires 
                        // SSL /TLS to be sent across the wire. 
                        // $Start-HttpsEverywhere$
                        // antiforgeryOptions.RequireSsl = true;
                        // $End-HttpsEverywhere$
                    });
            services.AddAntiforgery();
            #endregion

            #region Configuration

            var applicationEnvironment = services.BuildServiceProvider().GetRequiredService<IApplicationEnvironment>();
            var hostingEnvironment = services.BuildServiceProvider().GetRequiredService<IHostingEnvironment>();
            //var configurationPath = Path.Combine(applicationEnvironment.ApplicationBasePath, "config.json");

            // Set up configuration sources.
            var configBuilder = new ConfigurationBuilder()
                .SetBasePath(applicationEnvironment.ApplicationBasePath)
                .AddJsonFile("appsettings.json")
                .AddJsonFile($"appsettings.{hostingEnvironment.EnvironmentName}.json", optional: true)
                //All environment variables in the process's context flow in as configuration values.
                .AddEnvironmentVariables();

            Configuration = configBuilder.Build();

            services.AddSingleton(_ => Configuration as IConfiguration);

           
            #endregion  

            #region Logging


            services.AddLogging();
            

            #endregion

           

            #region Caching
            // Adds a default in-memory implementation of IDistributedCache, which is very fast but 
            // the cache will not be shared between instances of the application. 
            // Also adds IMemoryCache.
            services.AddCaching();

            // Uncomment the following line to use the Redis implementation of      
            // IDistributedCache. This will override any previously registered IDistributedCache 
            // service. Redis is a very fast cache provider and the recommended distributed cache 
            // provider.
            // services.AddTransient<IDistributedCache, RedisCache>();

            // Uncomment the following line to use the Microsoft SQL Server implementation of 
            // IDistributedCache. Note that this would require setting up the session state database.
            // Redis is the preferred cache implementation but you can use SQL Server if you don't 
            // have an alternative.
            // services.AddSqlServerCache(o =>
            // {
            //     o.ConnectionString = 
            //       "Server=.;Database=ASPNET5SessionState;Trusted_Connection=True;";
            //     o.SchemaName = "dbo";
            //     o.TableName = "Sessions";
            // });
            #endregion

            #region Session
            services.AddSession(o =>
            {
                //o.IdleTimeout = TimeSpan.FromMinutes(Double.Parse(Configuration[TimeoutConfigKey]));
                o.IdleTimeout = TimeSpan.FromMinutes(15);
            });
            #endregion

            #region Localization
            services.AddLocalization();
            #endregion

        }