/// <summary>
        /// Integrates the given module with the core by replacing other modules,
        /// configuring routes and setting up wrappers.
        /// </summary>
        /// <param name="moduleName">The name of the loaded module as specified in the config</param>
        /// <param name="module">The loaded module</param>
        /// <exception cref="NotSupportedException">When duplicate content paths are found</exception>
        private void Integrate(string moduleName, IModule module)
        {
            _log.Info($"Integrating module '{moduleName}'");

            if (module is ILogger)
            {
                _log = (ILogger)module;
                _log.Info($"Loaded module '{moduleName}' implements ILogger, replaced Bootstrap logger");

                // TODO: Find a better way to reload modules in other modules
                /// See Issue #3
                /// https://github.com/ProjectLimitless/ProjectLimitless/issues/3
                _analysis.SetLog(_log);
                CoreContainer.Instance.IOManager.SetLog(_log);
            }

            if (module is IUIModule)
            {
                // Multiple UI modules are allowed, we can add all their paths
                var    ui          = module as IUIModule;
                string contentPath = ui.GetContentPath();
                if (CoreContainer.Instance.RouteManager.AddContentRoute(contentPath))
                {
                    _log.Debug($"Added content path '{contentPath}' for module '{moduleName}'");
                }
                else
                {
                    _log.Critical($"Previously loaded IUIModule already uses the content path '{contentPath}' specified in '{moduleName}'");
                    throw new NotSupportedException($"Previously loaded IUIModule already uses the content path '{contentPath}' specified in '{moduleName}'");
                }
            }

            if (module is IIdentityProvider)
            {
                var identityProvider = module as IIdentityProvider;

                CoreContainer.Instance.RouteManager.AddRoutes(identityProvider.GetRequiredAPIRoutes(_analysis.Record));
                CoreContainer.Instance.IdentityProvider = identityProvider;
#if DEBUG
                _log.Debug($"Added {identityProvider.GetRequiredAPIRoutes(_analysis.Record).Count} required API routes for 'IdentityProvider'");
#endif
            }

            // Add this provider to the input pipeline
            if (module is IIOProcessor)
            {
                var inputProvider = module as IIOProcessor;
                try
                {
                    CoreContainer.Instance.IOManager.RegisterProvider(inputProvider);
                }
                catch (NotSupportedException ex)
                {
                    _log.Error($"Unable to load input provider '{inputProvider.GetType().Name}': {ex.Message}");
                }
            }

            if (module is IInteractionEngine)
            {
                var interactionEngine = module as IInteractionEngine;
                // TODO: Better replacement. See Issue #3
                // https://github.com/ProjectLimitless/ProjectLimitless/issues/3
                CoreContainer.Instance.IOManager.SetEngine(interactionEngine);
                CoreContainer.Instance.RouteManager.AddRoutes(interactionEngine.GetRequiredAPIRoutes(_analysis.Record));

#if DEBUG
                _log.Debug($"Added {interactionEngine.GetRequiredAPIRoutes(_analysis.Record).Count} required API routes for 'InteractionEngine'");
#endif
            }


            // TODO: Add decorating to interfaces with required paths
            // TODO: Testing hook
            var moduleRoutes = module.GetAPIRoutes(_analysis.Record);
            if (CoreContainer.Instance.RouteManager.AddRoutes(moduleRoutes))
            {
                _log.Info($"Added {moduleRoutes.Count} new API routes for module '{moduleName}'");
            }
            else
            {
                _log.Warning($"Unable to add all API routes for module '{moduleName}'. Possible duplicate route and method.");
            }
        }