/// <summary>
 /// Configure the application and then register all the routes.
 /// This is because after the configuration, the dynamic html pages will be processed in the routes.
 /// </summary>
 protected void Application_Start()
 {
     var app = new AppConfigurator();
     Configure(app);
 }
        /// <summary>
        /// This configures the application by initializing all the various services.
        /// 1. Set environment. There is dev and dev2 which correspond to the config files in \config directory.
        /// 2. Config files
        /// 3. Email notifications                
        /// 4. Repository configuration
        /// 5. Account Membership.
        /// 6. Entity/Repository initialization            
        /// 7. Authentication
        /// 8. Logging to In-Memory Database. Can be replaced w/ real db.            
        /// 9. Configure dashboard w/ the models.                            
        /// </summary>
        public void Configure(AppConfigurator app)
        {
            // IMPORTANT  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            // Once in a while you get a 404 - resource not found error. here is why
            // http://insomniacgeek.com/how-to-fix-resource-not-found-error-with-your-asp-net-mvc-project/

            // Initialize all the various services for the application including:
            string configDir = Server.MapPath(@"~/Config/Env");
            string _ENVIRONMENT_ = System.Configuration.ConfigurationManager.AppSettings["environment"];
            bool useRealData = Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["useRealData"]);
            bool clearData = Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["clearData"]);
            bool loadSchema = Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["loadSchema"]);
            bool loadData = Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["loadData"]);
            bool updateSchema = Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["updateSchema"]);

            CMS.Register<BootStrapper>(new BootStrapper());
            Application["start_time"] = DateTime.Now;
            Application["model.settings"] = app.GetModelSettingsAsDictionary();

            // Non-Fluent API to bootup core bootup tasks for any app, web/non-web.
            CMS.Bootup.OnStart("Environment",       "core", BootTask.Importance.High,   false, (ctx) => Envs.Set(_ENVIRONMENT_, "prod,qa,dev2:dev,dev", "prod.config,qa.config,dev2.config,dev.config", true, true));
            CMS.Bootup.OnStart("Configuration",     "core", BootTask.Importance.High,   false, (ctx) => Config.Init(Configs.LoadFiles(configDir, Env.RefPath)));
            CMS.Bootup.OnStart("Database Config",   "core", BootTask.Importance.High,   false, (ctx) => RepositoryFactory.Add(Config.Get<string>("Database", "connectstr")));
            CMS.Bootup.OnStart("Forms Auth",        "core", BootTask.Importance.High,   false, (ctx) => FormsAuthentication.Initialize());
            CMS.Bootup.OnStart("Repositories",      "core", BootTask.Importance.High,   false, (ctx) => app.ConfigureRepositories(useRealData, ctx.Bag));
            CMS.Bootup.OnStart("Logs",              "core", BootTask.Importance.High,   false, (ctx) => Logger.Default.Replace(new LogDatabase("commons.mvc", "db", ctx.Bag["logRepo"] as IRepository<LogEventEntity>, LogLevel.Debug)));
            CMS.Bootup.OnStart("Database Clear",    "core", BootTask.Importance.High,   clearData, false, (ctx) => app.DeleteData());
            CMS.Bootup.OnStart("Database Schema",   "core", BootTask.Importance.High,   loadSchema, false, (ctx) => app.CreateSchema());
            CMS.Bootup.OnStart("Database Update",   "core", BootTask.Importance.High,   updateSchema, false, (ctx) => app.UpdateSchema());                
            CMS.Bootup.OnStart("Queues",            "core", BootTask.Importance.High,   false, (ctx) => app.ConfigureQueueProcessing());
            CMS.Bootup.OnStart("Schedule",          "core", BootTask.Importance.High,   false, (ctx) => app.ConfigureSchedules());
            CMS.Bootup.OnStart("Notifications",     "core", BootTask.Importance.High,   false, (ctx) => app.ConfigureNotifications());
            CMS.Bootup.OnStart("Auth1",             "core", BootTask.Importance.Low,    false, (ctx) => Auth.Init(new AuthWin("Admin", new UserPrincipal(1, "admin", "Admin", "custom", true))));

            // Example of Fluent API.
            CMS.Bootup.OnStart(BootTask.Named("Services"    ).InGroup("app" ).PriorityHigh.MustSucceed().ActionIs((ctx) => app.ConfigureServices()));
            CMS.Bootup.OnStart(BootTask.Named("Themes"      ).InGroup("app" ).PriorityHigh.MustSucceed().ActionIs((ctx) => app.ConfigureThemes()));
            CMS.Bootup.OnStart(BootTask.Named("ImportExport").InGroup("app" ).PriorityHigh.MustSucceed().ActionIs((ctx) => app.ConfigureImportExport()));
            CMS.Bootup.OnStart(BootTask.Named("Extensions"  ).InGroup("core").PriorityHigh.MustSucceed().ActionIs((ctx) => app.ConfigureExtensions()));
            CMS.Bootup.OnStart(BootTask.Named("Locations"   ).InGroup("app" ).PriorityHigh.MustSucceed().ActionIs((ctx) => app.ConfigureLocations()));
            CMS.Bootup.OnStart(BootTask.Named("App Config"  ).InGroup("app" ).PriorityHigh.MustSucceed().ActionIs((ctx) => app.ConfigureConfigs()));
            CMS.Bootup.OnStart(BootTask.Named("Dashboard"   ).InGroup("app" ).PriorityHigh.MustSucceed().ActionIs((ctx) => app.ConfigureDashBoard())); 
            CMS.Bootup.OnStart(BootTask.Named("Modules"     ).InGroup("app").PriorityHigh.MustSucceed().ActionIs((ctx) => app.ConfigureModules()));
            CMS.Bootup.OnStart(BootTask.Named("Data Load"   ).If(loadData).InGroup("app" ).PriorityNormal.CanFail(  ).ActionIs((ctx) => app.LoadData()));
            CMS.Bootup.OnStart(BootTask.Named("Settings"    ).InGroup("app" ).PriorityHigh.MustSucceed().ActionIs((ctx) => app.ConfigureSettings(ctx.Bag)));
            CMS.Bootup.OnStart(BootTask.Named("Web Search"  ).InGroup("app" ).PriorityHigh.MustSucceed().ActionIs((ctx) => app.ConfigureSearch()));
            CMS.Bootup.OnStart(BootTask.Named("Web Maps"    ).InGroup("app" ).PriorityHigh.MustSucceed().ActionIs((ctx) => app.ConfigureMaps()));
            CMS.Bootup.OnStart(BootTask.Named("MVC_Areas"   ).InGroup("mvc" ).PriorityHigh.MustSucceed().ActionIs((ctx) => AreaRegistration.RegisterAllAreas()));
            CMS.Bootup.OnStart(BootTask.Named("MVC_Routes"  ).InGroup("mvc" ).PriorityHigh.MustSucceed().ActionIs((ctx) => app.ConfigureRoutes()));
            CMS.Bootup.OnStart(BootTask.Named("Handlers"    ).InGroup("core").PriorityHigh.MustSucceed().ActionIs((ctx) => app.ConfigureHandlers()));
            CMS.Bootup.OnStart(BootTask.Named("Auth"        ).InGroup("core").PriorityHigh.MustSucceed().ActionIs((ctx) => Auth.Init(new AuthWeb("Admin"))));
            
            CMS.Bootup.StartUp(new AppContext());
            Article.Init(new RepositoryInMemory<Article>(), false);
            if(Article.Count() == 0 )
                for (int count = 1; count < 80; count++)
                    Article.Repository.Create(new Article() { Title = "article " + count, Author = "kishore_" + count, IsExternal = false, PublishDate = DateTime.Now, NumberOfComments = count });

            Logger.Info("Starting CMS");
        }