public static int Main(string[] args)
        {
            var logger = LogManager.GetLogger("DatabaseInitializer");

            try
            {
                Console.WriteLine("Creating/updating database for version {0}", CurrentVersion);
                Console.WriteLine("Started at: {0}", DateTime.Now);

                Console.WriteLine("Initializing...");
                var param = GetParamsFromArgs(args);

                Console.WriteLine("Working...");

                var creatorDb           = new DatabaseCreator();
                var sqlConnectionString = param.MasterConnectionString;

                var mirroringRole = creatorDb.MirroringRole(sqlConnectionString, param.CompanyName);
                // if Mirroring role value is 2, we need to switch between Mirror and Principal
                if (mirroringRole == 2)
                {
                    Console.WriteLine("Connected to the mirror database");
                    Console.WriteLine("Connection string before switch : " + sqlConnectionString);

                    var elements = sqlConnectionString.Split(';');

                    for (int idx = 0; idx < elements.Length; idx++)
                    {
                        if (elements[idx].ToLower().Contains("data source"))
                        {
                            elements[idx] = elements[idx].Replace("Data Source", "Failover Partner");
                        }
                        else if (elements[idx].ToLower().Contains("failover partner"))
                        {
                            elements[idx] = elements[idx].Replace("Failover Partner", "Data Source");
                        }
                    }

                    Console.WriteLine("Switched addresses between 'Data Source' and 'Failover Partner'");

                    sqlConnectionString = string.Join(";", elements);
                    Console.WriteLine("Switched connection string : " + sqlConnectionString);
                }

                IsUpdate = creatorDb.DatabaseExists(sqlConnectionString, param.CompanyName);
                IDictionary <string, string> appSettings;

                //for dev company, delete old database to prevent keeping too many databases
                if (param.CompanyName == LocalDevProjectName && IsUpdate)
                {
#if DEBUG
                    Console.WriteLine("Drop Existing Database? Y or N");
                    var shouldDrop = args.Length > 1 ? args[1] : Console.ReadLine();
                    if ("Y".Equals(shouldDrop, StringComparison.OrdinalIgnoreCase))
                    {
                        if (param.ReuseTemporaryDb)
                        {
                            creatorDb.DropSchema(param.MkWebConnectionString, param.CompanyName);
                        }
                        else
                        {
                            creatorDb.DropDatabase(sqlConnectionString, param.CompanyName);
                        }
                        IsUpdate = false;
                    }
#endif
                }

                if (IsUpdate)
                {
                    creatorDb.DropMessageLogTable(sqlConnectionString, param.CompanyName);

                    creatorDb.DeleteDeviceRegisteredEvents(sqlConnectionString, param.CompanyName);

                    UpdateSchema(param);

                    if (param.ReuseTemporaryDb)
                    {
                        // the idea behind reuse of temp db is that account doesn't have permission to rename db
                        // so we instead we need to re-migrate from the temp db to the actual name
                        UpdateSchema(param);
                    }
                }
                else
                {
                    // if DBs are re-used then it should already be created
                    if (!param.ReuseTemporaryDb)
                    {
                        creatorDb.CreateDatabase(sqlConnectionString, param.CompanyName, param.SqlServerDirectory);
                    }
                    creatorDb.CreateSchemas(new ConnectionStringSettings("MkWeb", param.MkWebConnectionString));

                    UpdateSchema(param);

                    creatorDb.CreateIndexes(sqlConnectionString, param.CompanyName);

                    Console.WriteLine("Add user for IIS...");
                    if (param.MkWebConnectionString.ToLower().Contains("integrated security=true"))
                    {
                        creatorDb.AddUserAndRighst(sqlConnectionString, param.MkWebConnectionString,
                                                   "IIS APPPOOL\\" + param.AppPoolName, param.CompanyName);
                    }

                    SetupMirroring(param);
                }

                var connectionString = new ConnectionStringSettings("MkWeb", param.MkWebConnectionString);

                UnityContainer container = new UnityContainer();
                Module         module    = new Module();
                module.Init(container, connectionString, param.MkWebConnectionString);

                var serverSettings = container.Resolve <IServerSettings>();
                var commandBus     = container.Resolve <ICommandBus>();

                Console.WriteLine("Checking Company Created...");
                CheckCompanyCreated(container, commandBus);

                if (!IsUpdate)
                {
                    appSettings = GetCompanySettings(param.CompanyName);

                    //Save settings so that next calls to referenceDataService has the IBS Url
                    AddOrUpdateAppSettings(commandBus, appSettings);

                    FetchingIbsDefaults(container, commandBus);

                    CreateDefaultAccounts(container, commandBus);
                }
                else
                {
                    EnsureSupportRoleIsSupported(connectionString, commandBus);
                    appSettings = serverSettings.GetSettings();
                }

                // If we are deploying to staging, regardless if we are updating or creating a new DB, create the apple test account.
                if (param.IsStaging)
                {
                    CreateAppleTestAccountIfNeeded(container, commandBus);
                }

                Console.WriteLine("Checking Rules...");
                CheckandMigrateDefaultRules(connectionString, commandBus, appSettings);
                Console.WriteLine("Checking Default Account Settings ...");
                EnsureDefaultAccountsHasCorrectSettings(connectionString, commandBus);

                SetDefaultAdminSettings(serverSettings, appSettings);

                Console.WriteLine("Checking Default Tariff ...");
                CreateDefaultTariff(connectionString.ConnectionString, serverSettings, commandBus);

                Console.WriteLine("Checking Ratings ...");
                var ratingTypes = new RatingTypeDao(() => new BookingDbContext(connectionString.ConnectionString)).GetAll();
                if (!ratingTypes.Any())
                {
                    AddDefaultRatings(commandBus);
                }
                else
                {
                    UpdateRatings(commandBus, ratingTypes);
                }

                Console.WriteLine("Checking Vehicles Types ...");
                var vehicleTypeDao     = new VehicleTypeDao(() => new BookingDbContext(connectionString.ConnectionString));
                var vehicleTypeDetails = vehicleTypeDao.GetAll();
                if (!vehicleTypeDetails.Any())
                {
                    appSettings["VehicleTypeSelectionEnabled"] = "false";
                    AddOrUpdateAppSettings(commandBus, appSettings);
                    CreateDefaultVehicleTypes(container, commandBus);
                }
                else
                {
                    CheckAndAddCapacity(vehicleTypeDetails, container, commandBus);
                }

                Console.WriteLine("Migration of Notification Settings ...");
                var configDao = new ConfigurationDao(() => new ConfigurationDbContext(connectionString.ConnectionString));
                if (configDao.GetNotificationSettings() == null)
                {
                    commandBus.Send(new AddOrUpdateNotificationSettings
                    {
                        CompanyId            = AppConstants.CompanyId,
                        NotificationSettings = new NotificationSettings
                        {
                            Enabled = true,
                            BookingConfirmationEmail = true,
                            ConfirmPairingPush       = true,
                            DriverAssignedPush       = true,
                            NearbyTaxiPush           = true,
                            UnpairingReminderPush    = true,
                            PaymentConfirmationPush  = true,
                            ReceiptEmail             = true,
                            PromotionUnlockedEmail   = true,
                            VehicleAtPickupPush      = true,
                            PromotionUnlockedPush    = true,
                            DriverBailedPush         = true,
                            NoShowPush = true,
                            OrderCancellationConfirmationPush = true
                        }
                    });
                }

                Console.WriteLine("Migration of Payment Settings ...");

                MigratePaymentSettings(serverSettings, commandBus, appSettings);

                EnsurePrivacyPolicyExists(connectionString, commandBus, serverSettings);

#if DEBUG
                var iisManager = new ServerManager();
                var appPool    = iisManager.ApplicationPools.FirstOrDefault(x => x.Name == param.AppPoolName);

                if (appPool != null &&
                    appPool.State == ObjectState.Stopped)
                {
                    appPool.Start();
                    Console.WriteLine("App Pool started.");
                }
#endif

                Console.WriteLine("Database Creation/Migration for version {0} finished", CurrentVersion);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message + "-" + e);
                logger.Fatal(e.ToString());
                logger.Fatal(e.Message, e);
                return(1);
            }
            return(0);
            // ReSharper restore LocalizableElement
        }