/// <summary>
        /// The Loaded event for the Window where we will execute code that should run when the Window
        /// is first put into place.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            // The settings for the app load in the app startup, they will then try to load the last profile that was used.
            App.Conveyor.EchoLog($"Avalon Mud Client Version {Assembly.GetExecutingAssembly()?.GetName()?.Version.ToString() ?? "Unknown"}", LogType.Information);

            try
            {
                int count = Utilities.Utilities.UpdatePlugins();

                if (count == 1)
                {
                    App.Conveyor.EchoLog($"{count} plugin was updated.", LogType.Information);
                }
                else if (count > 1)
                {
                    App.Conveyor.EchoLog($"{count} plugins were updated.", LogType.Information);
                }
            }
            catch (Exception ex)
            {
                App.Conveyor.EchoLog("An error occured copying updated plugins.", LogType.Error);
                App.Conveyor.EchoLog(ex.Message, LogType.Error);
            }

            try
            {
                int count = Utilities.Utilities.CleanupUpdatesFolder();

                if (count > 0)
                {
                    App.Conveyor.EchoLog($"{count} files(s) deleted from the updates folder.", LogType.Information);
                }
            }
            catch (Exception ex)
            {
                App.Conveyor.EchoLog("An error occured removing old updates from the updates folder.", LogType.Error);
                App.Conveyor.EchoLog(ex.Message, LogType.Error);
            }

            try
            {
                if (App.Settings.AvalonSettings.DeveloperMode)
                {
                    App.Conveyor.EchoLog($"Global Settings Folder: {App.Settings.AppDataDirectory}", LogType.Information);
                    App.Conveyor.EchoLog($"Global Settings File:   {App.Settings.AvalonSettingsFile}", LogType.Information);
                    App.Conveyor.EchoLog($"Profiles Folder: {App.Settings.AvalonSettings.SaveDirectory}", LogType.Information);
                }

                // Parse the command line arguments to see if a profile was specified.
                var args = Environment.GetCommandLineArgs();

                // Try to load the last profile loaded, if not found create a new profile.
                if (File.Exists(App.Settings.AvalonSettings.LastLoadedProfilePath))
                {
                    await LoadSettings(App.Settings.AvalonSettings.LastLoadedProfilePath);
                }
                else
                {
                    if (string.IsNullOrWhiteSpace(App.Settings.AvalonSettings.LastLoadedProfilePath))
                    {
                        App.Conveyor.EchoLog($"New Profile being created.", LogType.Information);
                    }
                    else
                    {
                        App.Conveyor.EchoLog($"Last Profile Loaded Not Found: {App.Settings.AvalonSettings.LastLoadedProfilePath}", LogType.Warning);
                    }
                }

                // Set the startup position.
                switch (App.Settings.AvalonSettings.WindowStartupPosition)
                {
                case WindowStartupPosition.OperatingSystemDefault:
                    this.WindowState = WindowState.Normal;
                    break;

                case WindowStartupPosition.Maximized:
                    this.WindowState = WindowState.Maximized;
                    break;

                case WindowStartupPosition.LastUsed:
                    this.Left        = App.Settings.AvalonSettings.LastWindowPosition.Left;
                    this.Top         = App.Settings.AvalonSettings.LastWindowPosition.Top;
                    this.Height      = App.Settings.AvalonSettings.LastWindowPosition.Height;
                    this.Width       = App.Settings.AvalonSettings.LastWindowPosition.Width;
                    this.WindowState = (WindowState)App.Settings.AvalonSettings.LastWindowPosition.WindowState;
                    break;
                }

                // Inject the Conveyor into the Triggers so the Triggers know how to talk to the UI.  Not doing this
                // causes ya know, problems.
                TriggersList.TriggerConveyorSetup();

                // Wire up any events that have to be wired up through code.
                TextInput.Editor.PreviewKeyDown += this.Editor_PreviewKeyDown;
                AddHandler(TabControlEx.NetworkButtonClickEvent, new RoutedEventHandler(NetworkButton_Click));
                AddHandler(TabControlEx.SettingsButtonClickEvent, new RoutedEventHandler(SettingsButton_Click));

                // Pass the necessary reference from this page to the Interpreter.
                Interp = new Interpreter(App.Conveyor);

                // Setup the handler so when it wants to write to the main window it can by raising the echo event.
                Interp.Echo += this.InterpreterEcho;

                // Setup the tick timer.
                TickTimer = new TickTimer(App.Conveyor);

                // TODO - Setting to disable and command to view these tasks.
                // Setup the scheduled and batch tasks.
                ScheduledTasks = new ScheduledTasks(this.Interp);
                BatchTasks     = new BatchTasks(this.Interp);

                // Setup the auto complete commands.  If they're found refresh them, if they're not
                // report it to the terminal window.  It should -always be found-.
                RefreshAutoCompleteEntries();

                // Update static variables from places that might be expensive to populate from (like Environment.Username).  Normally
                // something like that isn't expensive but when run on variable replacement it can be more noticable.
                Utilities.Utilities.UpdateCommonVariables();

                // Load any plugin classes from the plugins folder.  They will be "activated" when a mud who matches
                // the plugin IP is connected to.
                LoadPlugins();

                // Update any UI settings
                UpdateUISettings();

                // Auto connect to the game if the setting is set.
                if (App.Settings.ProfileSettings.AutoConnect)
                {
                    NetworkButton_Click(null, null);
                }

                // Is there an auto execute command or set of commands to run?
                if (!string.IsNullOrWhiteSpace(App.Settings.ProfileSettings.AutoExecuteCommand))
                {
                    Interp.Send(App.Settings.ProfileSettings.AutoExecuteCommand, true, false);
                }

                // Finally, all is done, set the focus to the command box.
                TextInput.Focus();
            }
            catch (Exception ex)
            {
                App.Conveyor.EchoLog("A critical error on startup occured.", LogType.Error);
                App.Conveyor.EchoLog(ex.Message, LogType.Error);
                App.Conveyor.EchoText(ex?.StackTrace?.ToString() ?? "No stack trace available.");
                return;
            }
        }
        /// <summary>
        /// The Loaded event for the Window where we will execute code that should run when the Window
        /// is first put into place.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            // We are going to hide the window while it's loading, we will show it at the end of this
            // to avoid the flickering and repositioning the settings being loaded causes.
            this.Hide();

            if (Utilities.Utilities.IsRunningAsUwp())
            {
                // The settings for the app load in the app startup, they will then try to load the last profile that was used.
                App.Conveyor.EchoInfo($"{{GA{{gvalon {{GM{{gud {{GC{{glient{{x: Version {Assembly.GetExecutingAssembly()?.GetName()?.Version?.ToString() ?? "Unknown"} (UWP)");
                MenuItemUpdateClient.Visibility = Visibility.Collapsed;
            }
            else
            {
                // The settings for the app load in the app startup, they will then try to load the last profile that was used.
                App.Conveyor.EchoInfo($"{{GA{{gvalon {{GM{{gud {{GC{{glient{{x: Version {Assembly.GetExecutingAssembly()?.GetName()?.Version?.ToString() ?? "Unknown"}");
            }

            try
            {
                int count = Utilities.Utilities.UpdatePlugins();

                if (count == 1)
                {
                    App.Conveyor.EchoSuccess($"{count.ToString()} plugin was updated.");
                }
                else if (count > 1)
                {
                    App.Conveyor.EchoSuccess($"{count.ToString()} plugins were updated.");
                }
            }
            catch (Exception ex)
            {
                App.Conveyor.EchoError("An error occurred copying updated plugins.");
                App.Conveyor.EchoError(ex.Message);
            }

            try
            {
                int count = Utilities.Utilities.CleanupUpdatesFolder();

                if (count > 0)
                {
                    App.Conveyor.EchoInfo($"{count.ToString()} files(s) deleted from the updates folder.");
                }
            }
            catch (Exception ex)
            {
                App.Conveyor.EchoError("An error occurred removing old updates from the updates folder.");
                App.Conveyor.EchoError(ex.Message);
            }

            try
            {
                this.DataContext = this.ViewModel;

                // Wire up any events that have to be wired up through code.
                TextInput.Editor.PreviewKeyDown += this.Editor_PreviewKeyDown;

                // Wire up what we're going to do for the search box.
                TitleBar.SearchBox.SearchExecuted += this.SearchBox_SearchExecutedAsync;

                // Pass the necessary reference from this page to the Interpreter.  Add the interpreter
                // references.
                this.Interp = AppServices.GetService <Interpreter>();

                // Setup the handler so when it wants to write to the main window it can by raising the echo event.
                Interp.Echo += this.InterpreterEcho;

                // Setup the tick timer.
                TickTimer = new TickTimer(App.Conveyor);

                // Setup the scheduled and batch tasks.
                this.ScheduledTasks = new ScheduledTasks(this.Interp);
                this.BatchTasks     = new BatchTasks(this.Interp);

                // Load any plugin classes from the plugins folder.  They will be "activated" when a mud who matches
                // the plugin IP is connected to.
                this.LoadPlugins();
            }
            catch (Exception ex)
            {
                App.Conveyor.EchoError("A critical error on startup occurred.");
                App.Conveyor.EchoError(ex.Message);
                App.Conveyor.EchoError(ex?.StackTrace ?? "No stack trace available.");
            }

            // Show the connection manager, if they don't select something, exit the entire program.
            var cm     = new ConnectionManagerWindow();
            var result = cm.ShowDialog();

            if (!result.GetValueOrDefault(false))
            {
                App.InstanceGlobals.SkipSaveOnExit = true;
                Application.Current.Shutdown(0);
            }

            // We're at the end of load, show the window.
            this.Show();
        }