/// <summary>
        ///     Adds the specified <see cref="IManager"/> to the Manager list and subscribes to its
        ///     <see cref="Manager.StateChanged"/> event.
        /// </summary>
        /// <typeparam name="T">The Type of the specified Manager.</typeparam>
        /// <param name="manager">The Manager to register.</param>
        /// <returns>The registered Manager.</returns>
        /// <exception cref="ManagerRegistrationException">Thrown when an error is encountered during registration.</exception>
        private T RegisterManager <T>(IManager manager)
            where T : IManager
        {
            logger.EnterMethod(xLogger.TypeParams(typeof(T)), xLogger.Params(manager));
            logger.Trace("Registering Manager '" + manager.GetType().Name + "'...");

            // ensure the specified Manager hasn't already been registered. There can only be one of each Type in the Manager list.
            if (IsManagerRegistered <T>())
            {
                throw new ManagerRegistrationException("The Manager '" + manager.GetType().Name + "' is already registered.");
            }

            try
            {
                // retrieve the dependencies for the Manager
                List <Type> dependencies = GetManagerDependencies <T>();

                logger.Trace("Registering Manager with " + dependencies.Count() + " dependencies...");

                // add the specified Manager to the list and attach an event handler to its StateChanged event
                ManagerInstances.Add(manager);
                ManagerDependencies.Add(typeof(T), dependencies);
                manager.StateChanged += ManagerStateChanged;
            }
            catch (Exception ex)
            {
                logger.Exception(ex);
                throw new ManagerRegistrationException("Failed to register Manager '" + manager.GetType().Name + "'.  See the inner exception for details.", ex);
            }

            logger.Trace("Successfully registered Manager '" + manager.GetType().Name + "'.");

            logger.ExitMethod();
            return((T)manager);
        }
        /// <summary>
        /// Factory method for returning the apropriate manager instance for the specified type
        /// </summary>
        /// <param name="typeName"></param>
        /// <returns></returns>
        public IPersonalArtefactManager GetManager(string typeName)
        {
            IPersonalArtefactManager instance = null;

            switch (typeName)
            {
            case PersonalArtefactType.UserQuery:
                if (!ManagerInstances.ContainsKey(typeName))
                {
                    var viewManager = new PersonalViewManager(_pluginContext);
                    viewManager.PersonalViewsListUpdated += (object sender, EventArgs evt) =>
                    {
                        ArtefactListUpdated?.Invoke(this, new ArtefactListUpdatedEventArgs(viewManager.Views));
                    };
                    ManagerInstances.Add(typeName, viewManager);
                }
                instance = ManagerInstances[typeName];
                break;

            case "userform":
                if (!ManagerInstances.ContainsKey(typeName))
                {
                    var dashboardManager = new PersonalDashboardManager(_pluginContext);
                    dashboardManager.PersonalDashboardsListUpdated += (object sender, EventArgs evt) =>
                    {
                        ArtefactListUpdated?.Invoke(this, new ArtefactListUpdatedEventArgs(dashboardManager.Dashboards));
                    };
                    ManagerInstances.Add(typeName, dashboardManager);
                }
                instance = ManagerInstances[typeName];
                break;

            case "userqueryvisualization":
                if (!ManagerInstances.ContainsKey(typeName))
                {
                    var diagramManager = new PersonalDiagramManager(_pluginContext);
                    diagramManager.PersonalDiagramsListUpdated += (object sender, EventArgs evt) =>
                    {
                        ArtefactListUpdated?.Invoke(this, new ArtefactListUpdatedEventArgs(diagramManager.Diagrams));
                    };
                    ManagerInstances.Add(typeName, diagramManager);
                }
                instance = ManagerInstances[typeName];
                break;

            default:
                throw new UnknownArtefactTypeError(typeName, $"Unknown artefact type \"{typeName}\"");
                break;
            }

            return(instance);
        }
        /// <summary>
        ///     Stops each of the <see cref="IManager"/> instances in the specified Manager instance list.
        /// </summary>
        /// <remarks>Does not Stop the ApplicationManager instance.</remarks>
        /// <param name="stopType">The type of stoppage.</param>
        private void StopManagers(StopType stopType = StopType.Stop)
        {
            Guid guid = logger.EnterMethod();

            logger.Debug("Stopping Managers...");

            for (int i = ManagerInstances.Count() - 1; i >= 0; i--)
            {
                logger.SubHeading(LogLevel.Debug, ManagerInstances[i].GetType().Name);
                if (ManagerInstances[i] != this)
                {
                    StopManager(ManagerInstances[i], StopType.Shutdown);
                }
            }

            logger.ExitMethod(guid);
        }
 /// <summary>
 ///     Searches the list of registered <see cref="IManager"/> instances for the specified instance and returns a value
 ///     indicating whether it was found.
 /// </summary>
 /// <typeparam name="T">The Manager Type to check.</typeparam>
 /// <returns>A value indicating whether the specified Manager has been registered.</returns>
 private bool IsManagerRegistered <T>()
     where T : IManager
 {
     return(ManagerInstances.OfType <T>().Count() > 0);
 }
 /// <summary>
 ///     Returns the Manager from the list of Managers matching the specified Type.
 /// </summary>
 /// <typeparam name="T">The Type of the Manager to return.</typeparam>
 /// <returns>The requested Manager.</returns>
 public T GetManager <T>()
     where T : IManager
 {
     return(ManagerInstances.OfType <T>().FirstOrDefault());
 }