/// <summary>
        /// Bind a window to some commands to be executed by the viewmodel.
        /// </summary>
        /// <param name="win"></param>
        public void InitCommandBinding(Window win)
        {
            InitEditCommandBinding(win);

            win.CommandBindings.Add(new CommandBinding(AppCommand.Exit,
                                                       (s, e) =>
            {
                AppExit_CommandExecuted();
                e.Handled = true;
            }));

            win.CommandBindings.Add(new CommandBinding(AppCommand.About,
                                                       (s, e) =>
            {
                AppAbout_CommandExecuted();
                e.Handled = true;
            }));

            win.CommandBindings.Add(new CommandBinding(AppCommand.ProgramSettings,
                                                       (s, e) =>
            {
                AppProgramSettings_CommandExecuted();
                e.Handled = true;
            }));

            win.CommandBindings.Add(new CommandBinding(AppCommand.ShowToolWindow,
                                                       (s, e) =>
            {
                if (e == null)
                {
                    return;
                }

                var toolwindowviewmodel = e.Parameter as IToolWindow;

                if (toolwindowviewmodel == null)
                {
                    return;
                }


                if (toolwindowviewmodel is IRegisterableToolWindow)
                {
                    IRegisterableToolWindow registerTW = toolwindowviewmodel as IRegisterableToolWindow;

                    registerTW.SetToolWindowVisibility(this, !toolwindowviewmodel.IsVisible);
                }
                else
                {
                    toolwindowviewmodel.SetToolWindowVisibility(!toolwindowviewmodel.IsVisible);
                }

                e.Handled = true;
            }));

            // Standard File New command binding via ApplicationCommands enumeration
            win.CommandBindings.Add(new CommandBinding(ApplicationCommands.New,
                                                       (s, e) =>
            {
                TypeOfDocument t = TypeOfDocument.EdiTextEditor;

                if (e != null)
                {
                    e.Handled = true;

                    if (e.Parameter != null)
                    {
                        if (e.Parameter is TypeOfDocument)
                        {
                            t = (TypeOfDocument)e.Parameter;
                        }
                    }
                }

                this.OnNew(t);
            }
                                                       ));

            // Standard File Open command binding via ApplicationCommands enumeration
            win.CommandBindings.Add(new CommandBinding(ApplicationCommands.Open,
                                                       (s, e) =>
            {
                string t = string.Empty;

                if (e?.Parameter is string)
                {
                    t = (string)e.Parameter;
                }

                OnOpen(t);
                if (e != null)
                {
                    e.Handled = true;
                }
            }
                                                       ));

            // Close Document command
            // Closes the FileViewModel document supplied in e.parameter
            // or the Active document
            win.CommandBindings.Add(new CommandBinding(AppCommand.CloseFile,
                                                       (s, e) =>
            {
                try
                {
                    FileBaseViewModel f = null;

                    if (e != null)
                    {
                        e.Handled = true;
                        f         = e.Parameter as FileBaseViewModel;
                    }

                    if (f != null)
                    {
                        Close(f);
                    }
                    else
                    {
                        if (ActiveDocument != null)
                        {
                            Close(ActiveDocument);
                        }
                    }
                }
                catch (Exception exp)
                {
                    Logger.Error(exp.Message, exp);
                    _MsgBox.Show(exp, Util.Local.Strings.STR_MSG_IssueTrackerTitle, MsgBoxButtons.OK, MsgBoxImage.Error, MsgBoxResult.NoDefaultButton,
                                 _AppCore.IssueTrackerLink,
                                 _AppCore.IssueTrackerLink,
                                 Util.Local.Strings.STR_MSG_IssueTrackerText, null, true);
                }
            },
                                                       (s, e) =>
            {
                try
                {
                    if (e != null)
                    {
                        e.Handled    = true;
                        e.CanExecute = false;

                        EdiViewModel f = null;

                        if (e != null)
                        {
                            e.Handled = true;
                            f         = e.Parameter as EdiViewModel;
                        }

                        if (f != null)
                        {
                            e.CanExecute = f.CanClose();
                        }
                        else
                        {
                            if (this.ActiveDocument != null)
                            {
                                e.CanExecute = this.ActiveDocument.CanClose();
                            }
                        }
                    }
                }
                catch (Exception exp)
                {
                    Logger.Error(exp.Message, exp);
                    _MsgBox.Show(exp, Util.Local.Strings.STR_MSG_IssueTrackerTitle, MsgBoxButtons.OK, MsgBoxImage.Error, MsgBoxResult.NoDefaultButton,
                                 _AppCore.IssueTrackerLink,
                                 _AppCore.IssueTrackerLink,
                                 Util.Local.Strings.STR_MSG_IssueTrackerText, null, true);
                }
            }));

            // Change the WPF/TextEditor highlighting theme currently used in the application
            win.CommandBindings.Add(new CommandBinding(AppCommand.ViewTheme,
                                                       (s, e) => this.ChangeThemeCmd_Executed(s, e, win.Dispatcher)));

            win.CommandBindings.Add(new CommandBinding(AppCommand.BrowseUrl,
                                                       (s, e) =>
            {
                Process.Start(new ProcessStartInfo("https://github.com/Dirkster99/Edi"));
            }));

            win.CommandBindings.Add(new CommandBinding(AppCommand.ShowStartPage,
                                                       (s, e) =>
            {
                ShowStartPage();
            }));

            win.CommandBindings.Add(new CommandBinding(AppCommand.ToggleOptimizeWorkspace,
                                                       (s, e) =>
            {
                Logger.InfoFormat("TRACE AppCommand.ToggleOptimizeWorkspace parameter is {0}.", e?.ToString() ?? "(null)");

                try
                {
                    var newViewSetting       = !IsWorkspaceAreaOptimized;
                    IsWorkspaceAreaOptimized = newViewSetting;
                }
                catch (Exception exp)
                {
                    Logger.Error(exp.Message, exp);
                    _MsgBox.Show(exp, Util.Local.Strings.STR_MSG_IssueTrackerTitle, MsgBoxButtons.OK, MsgBoxImage.Error, MsgBoxResult.NoDefaultButton,
                                 _AppCore.IssueTrackerLink, _AppCore.IssueTrackerLink,
                                 Util.Local.Strings.STR_MSG_IssueTrackerText, null, true);
                }
            }));

            win.CommandBindings.Add(new CommandBinding(AppCommand.LoadFile,
                                                       (s, e) =>
            {
                try
                {
                    Logger.InfoFormat("TRACE AppCommand.LoadFile parameter is {0}.", (e == null ? "(null)" : e.ToString()));

                    if (e == null)
                    {
                        return;
                    }

                    string filename = e.Parameter as string;

                    if (filename == null)
                    {
                        return;
                    }

                    Logger.InfoFormat("TRACE AppCommand.LoadFile with: '{0}'", filename);

                    this.Open(filename);
                }
                catch (Exception exp)
                {
                    Logger.Error(exp.Message, exp);
                    _MsgBox.Show(exp, Util.Local.Strings.STR_MSG_IssueTrackerTitle, MsgBoxButtons.OK, MsgBoxImage.Error, MsgBoxResult.NoDefaultButton,
                                 _AppCore.IssueTrackerLink, _AppCore.IssueTrackerLink,
                                 Util.Local.Strings.STR_MSG_IssueTrackerText, null, true);
                }
            }));

            win.CommandBindings.Add(new CommandBinding(ApplicationCommands.Save,
                                                       (s, e) =>
            {
                try
                {
                    if (e != null)
                    {
                        e.Handled = true;
                    }

                    if (ActiveDocument != null)
                    {
                        OnSave(ActiveDocument);
                    }
                }
                catch (Exception exp)
                {
                    Logger.Error(exp.Message, exp);
                    _MsgBox.Show(exp, Util.Local.Strings.STR_MSG_UnknownError_Caption,
                                 MsgBoxButtons.OK, MsgBoxImage.Error, MsgBoxResult.NoDefaultButton,
                                 _AppCore.IssueTrackerLink, _AppCore.IssueTrackerLink,
                                 Util.Local.Strings.STR_MSG_IssueTrackerText, null, true);
                }
            },
                                                       (s, e) =>
            {
                if (e == null)
                {
                    return;
                }
                e.Handled = true;

                if (ActiveDocument != null)
                {
                    e.CanExecute = ActiveDocument.CanSave();
                }
            }));

            win.CommandBindings.Add(new CommandBinding(ApplicationCommands.SaveAs,
                                                       (s, e) =>
            {
                try
                {
                    if (e != null)
                    {
                        e.Handled = true;
                    }

                    if (ActiveDocument == null)
                    {
                        return;
                    }

                    if (!OnSave(ActiveDocument, true))
                    {
                        return;
                    }

                    _MruVM.UpdateEntry(ActiveDocument.FilePath);
                    _SettingsManager.SessionData.LastActiveFile = ActiveDocument.FilePath;
                }
                catch (Exception exp)
                {
                    Logger.Error(exp.Message, exp);
                    _MsgBox.Show(exp, Util.Local.Strings.STR_MSG_IssueTrackerTitle, MsgBoxButtons.OK, MsgBoxImage.Error, MsgBoxResult.NoDefaultButton,
                                 _AppCore.IssueTrackerLink,
                                 _AppCore.IssueTrackerLink,
                                 Util.Local.Strings.STR_MSG_IssueTrackerText, null, true);
                }
            },
                                                       (s, e) =>
            {
                try
                {
                    if (e != null)
                    {
                        e.Handled    = true;
                        e.CanExecute = false;

                        if (ActiveDocument != null)
                        {
                            e.CanExecute = ActiveDocument.CanSaveAs();
                        }
                    }
                }
                catch (Exception exp)
                {
                    Logger.Error(exp.Message, exp);
                    _MsgBox.Show(exp, Util.Local.Strings.STR_MSG_IssueTrackerTitle, MsgBoxButtons.OK, MsgBoxImage.Error, MsgBoxResult.NoDefaultButton,
                                 _AppCore.IssueTrackerLink,
                                 _AppCore.IssueTrackerLink,
                                 Util.Local.Strings.STR_MSG_IssueTrackerText, null, true);
                }
            }
                                                       ));

            // Execute a command to save all edited files and current program settings
            win.CommandBindings.Add(new CommandBinding(AppCommand.SaveAll,
                                                       (s, e) =>
            {
                try
                {
                    // Save all edited documents
                    if (_Files != null)                                   // Close all open files and make sure there are no unsaved edits
                    {                                                     // If there are any: Ask user if edits should be saved
                        IFileBaseViewModel activeDoc = ActiveDocument;

                        try
                        {
                            foreach (var f in Files)
                            {
                                if (f == null)
                                {
                                    continue;
                                }
                                if (!f.IsDirty || !f.CanSaveData)
                                {
                                    continue;
                                }
                                ActiveDocument = f;
                                OnSave(f);
                            }
                        }
                        catch (Exception exp)
                        {
                            _MsgBox.Show(exp.ToString(), Util.Local.Strings.STR_MSG_UnknownError_Caption, MsgBoxButtons.OK);
                        }
                        finally
                        {
                            if (activeDoc != null)
                            {
                                ActiveDocument = activeDoc;
                            }
                        }
                    }

                    // Save program settings
                    SaveConfigOnAppClosed();
                }
                catch (Exception exp)
                {
                    Logger.Error(exp.Message, exp);
                    _MsgBox.Show(exp, Util.Local.Strings.STR_MSG_IssueTrackerTitle, MsgBoxButtons.OK, MsgBoxImage.Error, MsgBoxResult.NoDefaultButton,
                                 _AppCore.IssueTrackerLink,
                                 _AppCore.IssueTrackerLink,
                                 Util.Local.Strings.STR_MSG_IssueTrackerText, null, true);
                }
            }));

            // Execute a command to export UML editor content as image
            win.CommandBindings.Add(new CommandBinding(AppCommand.ExportUmlToImage,
                                                       (s, e) =>
            {
                try
                {
                    if (vm_DocumentViewModel?.dm_DocumentDataModel.State == DataModel.ModelState.Ready)
                    {
                        vm_DocumentViewModel.ExecuteExport(s, e, ActiveDocument.FileName + ".png");
                    }
                }
                catch (Exception exp)
                {
                    Logger.Error(exp.Message, exp);
                    _MsgBox.Show(exp, Util.Local.Strings.STR_MSG_IssueTrackerTitle, MsgBoxButtons.OK, MsgBoxImage.Error, MsgBoxResult.NoDefaultButton,
                                 _AppCore.IssueTrackerLink,
                                 _AppCore.IssueTrackerLink,
                                 Util.Local.Strings.STR_MSG_IssueTrackerText, null, true);
                }
            },
                                                       (s, e) => // Execute this command only if an UML document is currently active
            {
                if (vm_DocumentViewModel != null)
                {
                    e.CanExecute = (vm_DocumentViewModel.dm_DocumentDataModel.State == DataModel.ModelState.Ready);
                }
                else
                {
                    e.CanExecute = false;
                }
            }
                                                       ));

            // Execute a command to export Text editor content as highlighted image content
            win.CommandBindings.Add(new CommandBinding(AppCommand.ExportTextToHtml,
                                                       (s, e) =>
            {
                try
                {
                    ActiveEdiDocument?.ExportToHtml(ActiveDocument.FileName + ".html",
                                                    _SettingsManager.SettingData.TextToHTML_ShowLineNumbers,
                                                    _SettingsManager.SettingData.TextToHTML_AlternateLineBackground);
                }
                catch (Exception exp)
                {
                    Logger.Error(exp.Message, exp);
                    _MsgBox.Show(exp, Util.Local.Strings.STR_MSG_IssueTrackerTitle, MsgBoxButtons.OK, MsgBoxImage.Error, MsgBoxResult.NoDefaultButton,
                                 _AppCore.IssueTrackerLink,
                                 _AppCore.IssueTrackerLink,
                                 Util.Local.Strings.STR_MSG_IssueTrackerText, null, true);
                }
            },
                                                       (s, e) => // Execute this command only if a Text document is currently active
            {
                e.CanExecute = ActiveEdiDocument != null;
            }
                                                       ));


            // Removes ALL MRU entries (even pinned entries) from the current list of entries.
            win.CommandBindings.Add(new CommandBinding(AppCommand.ClearAllMruItemsCommand,
                                                       (s, e) =>
            {
                GetToolWindowVm <RecentFilesTWViewModel>().MruList.Clear();
            }));

            // <summary>
            /// Gets a command that removes all items that are older
            /// than a given <see cref="GroupType"/>.
            // Eg.: Remove all MRU entries older than yesterday.
            // </summary>
            win.CommandBindings.Add(new CommandBinding(AppCommand.RemoveItemsOlderThanThisCommand,
                                                       (s, e) =>
            {
                if (e.Parameter is GroupType == false)
                {
                    return;
                }

                var param = (GroupType)e.Parameter;

                GetToolWindowVm <RecentFilesTWViewModel>().MruList.RemoveEntryOlderThanThis(param);
            },
                                                       (s, e) =>
            {
                if (e.Parameter is GroupType == false)
                {
                    e.CanExecute = false;
                    return;
                }

                e.CanExecute = true;
            }));

            win.CommandBindings.Add(new CommandBinding(AppCommand.MovePinnedMruItemUpCommand,
                                                       (s, e) =>
            {
                if (e.Parameter is IMRUEntryViewModel == false)
                {
                    return;
                }

                var param = (IMRUEntryViewModel)e.Parameter;

                GetToolWindowVm <RecentFilesTWViewModel>().MruList.MovePinnedEntry(MoveMRUItem.Up, param);
            },
                                                       (s, e) =>
            {
                if (e.Parameter is IMRUEntryViewModel == false)
                {
                    e.CanExecute = false;
                    return;
                }

                if (((IMRUEntryViewModel)e.Parameter).IsPinned == 0)                  //Make sure it is pinned
                {
                    e.CanExecute = false;
                    return;
                }

                e.CanExecute = true;
            }));

            win.CommandBindings.Add(new CommandBinding(AppCommand.MovePinnedMruItemDownCommand,
                                                       (s, e) =>
            {
                if (e.Parameter is IMRUEntryViewModel == false)
                {
                    return;
                }

                var param = (IMRUEntryViewModel)e.Parameter;

                GetToolWindowVm <RecentFilesTWViewModel>().MruList.MovePinnedEntry(MoveMRUItem.Down, param);
            },
                                                       (s, e) =>
            {
                if (e.Parameter is IMRUEntryViewModel == false)
                {
                    e.CanExecute = false;
                    return;
                }

                if (((IMRUEntryViewModel)e.Parameter).IsPinned == 0)                  //Make sure it is pinned
                {
                    e.CanExecute = false;
                    return;
                }

                e.CanExecute = true;
            }));

            win.CommandBindings.Add(new CommandBinding(AppCommand.PinItemCommand,
                                                       (s, e) =>
            {
                GetToolWindowVm <RecentFilesTWViewModel>().MruList.PinUnpinEntry(true, e.Parameter as IMRUEntryViewModel);
            },
                                                       (s, e) =>
            {
                if (e.Parameter is IMRUEntryViewModel == false)
                {
                    e.CanExecute = false;
                    return;
                }

                if (((IMRUEntryViewModel)e.Parameter).IsPinned == 0)                  //Make sure it is pinned
                {
                    e.CanExecute = true;
                    return;
                }

                e.CanExecute = false;
            }));

            win.CommandBindings.Add(new CommandBinding(AppCommand.UnPinItemCommand,
                                                       (s, e) =>
            {
                if (e.Parameter is IMRUEntryViewModel == false)
                {
                    return;
                }

                GetToolWindowVm <RecentFilesTWViewModel>().MruList.PinUnpinEntry(false, (IMRUEntryViewModel)e.Parameter);
            },
                                                       (s, e) =>
            {
                if (e.Parameter is IMRUEntryViewModel == false)
                {
                    e.CanExecute = false;
                    return;
                }

                if (((IMRUEntryViewModel)e.Parameter).IsPinned == 0)                  //Make sure it is pinned
                {
                    e.CanExecute = false;
                    return;
                }

                e.CanExecute = true;
            }));

            win.CommandBindings.Add(new CommandBinding(AppCommand.PinUnpin,
                                                       (s, e) =>
            {
                PinCommand_Executed(e.Parameter, e);
            }));

            win.CommandBindings.Add(new CommandBinding(AppCommand.RemoveMruEntry,
                                                       (s, e) =>
            {
                RemoveMRUEntry_Executed(e.Parameter, e);
            }));

            win.CommandBindings.Add(new CommandBinding(AppCommand.AddMruEntry,
                                                       (s, e) =>
            {
                AddMRUEntry_Executed(e.Parameter, e);
            }));
        }