/// <summary>
        /// Creates a new instance of <see cref="Limitless"/> with
        /// the loaded <see cref="LimitlessSettings"/> and <see cref="ILogger"/>.
        /// </summary>
        /// <param name="settings">The <see cref="LimitlessSettings"/> to be used</param>
        /// <param name="log">The <see cref="ILogger"/> to use</param>
        public Limitless(LimitlessSettings settings, ILogger log)
        {
            Skill skill = new Skill();

            skill.UUID             = "sample-coffee";
            skill.Name             = "Coffee Brewer";
            skill.Author           = "Project Limitless";
            skill.ShortDescription = "A skill to make coffee";
            skill.Class            = "actions/coffee";
            skill.Intent           = new Intent();
            skill.Intent.Actions.Add("brew");
            skill.Intent.Actions.Add("make");
            skill.Intent.Targets.Add("coffee");
            skill.Intent.Targets.Add("cuppa");
            skill.InstalledLocations.Add("kitchen");
            skill.InstalledLocations.Add("downstairs");
            skill.Binding = SkillExecutorBinding.Network;
            skill.Parameters.Add(new SkillParameter("sugar", SkillParameterClass.Quantity, true));
            skill.Parameters.Add(new SkillParameter("day", SkillParameterClass.DateRange, true));
            NetworkExecutor executor = new NetworkExecutor();

            executor.Url = "https://www.postoffice.co.za";
            executor.ValidateCertificate = false;
            skill.Executor           = executor;
            skill.Help.Phrase        = "make coffee";
            skill.Help.ExamplePhrase = "Make me a cup of coffee";

            //Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(skill));

            //Console.ReadLine();


            _settings = settings;
            _log      = log;
            // TODO: the analysis module hook needs to be implemented in a better way
            _analysis = new AnalysisModule(_log);

            CoreContainer.Instance.ModuleManager = new ModuleManager(_settings.FullConfiguration, _log);

            // TODO: Maybe make IOManager just an instance variable?
            CoreContainer.Instance.IOManager = new IOManager(_log);
            CoreContainer.Instance.RouteManager.AddRoutes(CoreContainer.Instance.IOManager.GetRequiredRoutes());

#if DEBUG
            _log.Debug($"Added {CoreContainer.Instance.IOManager.GetRequiredRoutes().Count} required API routes for 'IOManager'");
#endif

            Configure();
        }
        /// <summary>
        /// Loads the configurations from ConfigurationPath and ModuleConfigurationPath
        /// and merges them into one.
        /// </summary>
        /// <returns>The merged configuration</returns>
        public LimitlessSettings Load()
        {
            var settings = new LimitlessSettings();

            string coreConfigString = "";
            string coreFilePath     = Path.Combine(ConfigurationPath, "Core.toml");

            if (File.Exists(coreFilePath) == false)
            {
                throw new FileNotFoundException($"The Core.toml configuration file could not be found at '{coreFilePath}'.");
            }
            coreConfigString = File.ReadAllText(coreFilePath);

            string userConfigString = "";
            string userFilePath     = Path.Combine(ConfigurationPath, "User.toml");

            if (File.Exists(userFilePath) == false)
            {
                throw new FileNotFoundException($"The User.toml configuration file could not be found at '{userFilePath}'.");
            }
            userConfigString = File.ReadAllText(userFilePath);

            string moduleConfigsString = "";

            string[] moduleConfigFiles = Directory.GetFiles(ModuleConfigurationPath, "*.toml");
            if (moduleConfigFiles.Length == 0)
            {
                throw new NotSupportedException($"No module configurations could be found at '{ModuleConfigurationPath}'.");
            }
            foreach (string configPath in moduleConfigFiles)
            {
                // Add newlines between configs to parse successfully
                moduleConfigsString += "\r\n" + File.ReadAllText(configPath);
            }

            string combinedConfigsString = coreConfigString + moduleConfigsString;

            var combinedToml = Toml.ReadString(combinedConfigsString);
            var userToml     = Toml.ReadString(userConfigString);

            var completeToml = Merge(combinedToml, userToml);

            settings.Core = LimitlessSettings.Convert <CoreSettings>("Core", completeToml);
            settings.FullConfiguration = completeToml;

            return(settings);
        }
 /// <summary>
 /// Private constructor for Singleton pattern.
 /// </summary>
 private CoreContainer()
 {
     RouteManager = new RouteManager();
     Settings     = new LimitlessSettings();
 }