private static async Task RegisterPeriodicTasksAsync()
        {
            BotStatusUpdateTimer = new Timer(BotActivityCallback, Shards[0].Client, TimeSpan.FromSeconds(10), TimeSpan.FromMinutes(10));
            DatabaseSyncTimer    = new Timer(DatabaseSyncCallback, Shards[0].Client, TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(BotConfiguration.DatabaseSyncInterval));
            FeedCheckTimer       = new Timer(FeedCheckCallback, Shards[0].Client, TimeSpan.FromSeconds(BotConfiguration.FeedCheckStartDelay), TimeSpan.FromSeconds(BotConfiguration.FeedCheckInterval));
            MiscActionsTimer     = new Timer(MiscellaneousActionsCallback, Shards[0].Client, TimeSpan.FromSeconds(5), TimeSpan.FromHours(12));

            using (DatabaseContext db = GlobalDatabaseContextBuilder.CreateContext()) {
                await RegisterSavedTasksAsync(db.SavedTasks.ToDictionary <DatabaseSavedTask, int, SavedTaskInfo>(
                                                  t => t.Id,
                                                  t => {
                    switch (t.Type)
                    {
                    case SavedTaskType.Unban:
                        return(new UnbanTaskInfo(t.GuildId, t.UserId, t.ExecutionTime));

                    case SavedTaskType.Unmute:
                        return(new UnmuteTaskInfo(t.GuildId, t.UserId, t.RoleId, t.ExecutionTime));

                    default:
                        return(null);
                    }
                })
                                              );
                await RegisterRemindersAsync(db.Reminders.ToDictionary(
                                                 t => t.Id,
                                                 t => new SendMessageTaskInfo(t.ChannelId, t.UserId, t.Message, t.ExecutionTime, t.IsRepeating, t.RepeatInterval)
                                                 ));
            }


            async Task RegisterSavedTasksAsync(IReadOnlyDictionary <int, SavedTaskInfo> tasks)
            {
                int scheduled = 0, missed = 0;

                foreach ((int tid, SavedTaskInfo task) in tasks)
                {
                    if (await RegisterTaskAsync(tid, task))
                    {
                        scheduled++;
                    }
                    else
                    {
                        missed++;
                    }
                }
                SharedData.LogProvider.ElevatedLog(LogLevel.Info, $"Saved tasks: {scheduled} scheduled; {missed} missed.");
            }

            async Task RegisterRemindersAsync(IReadOnlyDictionary <int, SendMessageTaskInfo> reminders)
            {
                int scheduled = 0, missed = 0;

                foreach ((int tid, SendMessageTaskInfo task) in reminders)
                {
                    if (await RegisterTaskAsync(tid, task))
                    {
                        scheduled++;
                    }
                    else
                    {
                        missed++;
                    }
                }
                SharedData.LogProvider.ElevatedLog(LogLevel.Info, $"Reminders: {scheduled} scheduled; {missed} missed.");
            }

            async Task <bool> RegisterTaskAsync(int id, SavedTaskInfo tinfo)
            {
                var texec = new SavedTaskExecutor(id, Shards[0].Client, tinfo, SharedData, GlobalDatabaseContextBuilder);

                if (texec.TaskInfo.IsExecutionTimeReached)
                {
                    await texec.HandleMissedExecutionAsync();

                    return(false);
                }
                else
                {
                    texec.Schedule();
                    return(true);
                }
            }
        }
        private static async Task RegisterPeriodicTasksAsync()
        {
            BotStatusUpdateTimer = new Timer(BotActivityCallback, Shards[0].Client, TimeSpan.FromSeconds(10), TimeSpan.FromMinutes(10));
            DatabaseSyncTimer    = new Timer(DatabaseSyncCallback, Shards[0].Client, TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(BotConfiguration.DatabaseSyncInterval));
            FeedCheckTimer       = new Timer(FeedCheckCallback, Shards[0].Client, TimeSpan.FromSeconds(BotConfiguration.FeedCheckStartDelay), TimeSpan.FromSeconds(BotConfiguration.FeedCheckInterval));
            MiscActionsTimer     = new Timer(MiscellaneousActionsCallback, Shards[0].Client, TimeSpan.FromSeconds(5), TimeSpan.FromHours(12));

            await RegisterSavedTasks(await DatabaseService.GetAllSavedTasksAsync());
            await RegisterReminders(await DatabaseService.GetAllRemindersAsync());


            async Task RegisterSavedTasks(IReadOnlyDictionary <int, SavedTaskInfo> tasks)
            {
                int registeredTasks = 0, missedTasks = 0;

                foreach ((int tid, SavedTaskInfo task) in tasks)
                {
                    if (await RegisterTask(tid, task))
                    {
                        registeredTasks++;
                    }
                    else
                    {
                        missedTasks++;
                    }
                }
                SharedData.LogProvider.ElevatedLog(LogLevel.Info, $"Saved tasks: {registeredTasks} registered; {missedTasks} missed.");
            }

            async Task RegisterReminders(IReadOnlyDictionary <int, SendMessageTaskInfo> reminders)
            {
                int registeredTasks = 0, missedTasks = 0;

                foreach ((int tid, SendMessageTaskInfo task) in reminders)
                {
                    if (await RegisterTask(tid, task))
                    {
                        registeredTasks++;
                    }
                    else
                    {
                        missedTasks++;
                    }
                }
                SharedData.LogProvider.ElevatedLog(LogLevel.Info, $"Reminders: {registeredTasks} registered; {missedTasks} missed.");
            }

            async Task <bool> RegisterTask(int id, SavedTaskInfo tinfo)
            {
                var texec = new SavedTaskExecutor(id, Shards[0].Client, tinfo, SharedData, DatabaseService);

                if (texec.TaskInfo.IsExecutionTimeReached)
                {
                    await texec.HandleMissedExecutionAsync();

                    return(false);
                }
                else
                {
                    texec.Schedule();
                    return(true);
                }
            }
        }