protected override OLECMDF QueryCommandStatus(ref Guid commandGroup, uint commandId, OleCommandText oleCommandText)
        {
            if (commandGroup == typeof(GitDiffMarginCommand).GUID)
            {
                switch ((GitDiffMarginCommand)commandId)
                {
                case GitDiffMarginCommand.ShowPopup:
                {
                    EditorDiffMarginViewModel viewModel;
                    if (!TryGetMarginViewModel(out viewModel))
                    {
                        return(0);
                    }

                    var diffViewModel = GetCurrentDiffViewModel(viewModel);

                    if (diffViewModel != null)
                    {
                        return(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED);
                    }
                    else
                    {
                        return(OLECMDF.OLECMDF_SUPPORTED);
                    }
                }

                case GitDiffMarginCommand.PreviousChange:
                case GitDiffMarginCommand.NextChange:
                {
                    EditorDiffMarginViewModel viewModel;
                    if (!TryGetMarginViewModel(out viewModel))
                    {
                        return(0);
                    }

                    // First look for a diff already showing a popup
                    EditorDiffViewModel diffViewModel = viewModel.DiffViewModels.OfType <EditorDiffViewModel>().FirstOrDefault(i => i.ShowPopup);
                    if (diffViewModel != null)
                    {
                        RelayCommand <DiffViewModel> command = (GitDiffMarginCommand)commandId == GitDiffMarginCommand.NextChange ? viewModel.NextChangeCommand : viewModel.PreviousChangeCommand;
                        if (command.CanExecute(diffViewModel))
                        {
                            return(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED);
                        }
                        else
                        {
                            return(OLECMDF.OLECMDF_SUPPORTED);
                        }
                    }

                    diffViewModel = GetDiffViewModelToMoveTo(commandId, viewModel);

                    if (diffViewModel != null)
                    {
                        return(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED);
                    }
                    else
                    {
                        return(OLECMDF.OLECMDF_SUPPORTED);
                    }
                }

                case GitDiffMarginCommand.RollbackChange:
                case GitDiffMarginCommand.CopyOldText:
                {
                    EditorDiffMarginViewModel viewModel;
                    if (!TryGetMarginViewModel(out viewModel))
                    {
                        return(0);
                    }

                    EditorDiffViewModel diffViewModel = viewModel.DiffViewModels.OfType <EditorDiffViewModel>().FirstOrDefault(i => i.ShowPopup);
                    if (diffViewModel != null)
                    {
                        ICommand command = (GitDiffMarginCommand)commandId == GitDiffMarginCommand.RollbackChange ? diffViewModel.RollbackCommand : diffViewModel.CopyOldTextCommand;
                        if (command.CanExecute(diffViewModel))
                        {
                            return(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED);
                        }
                    }

                    // This command only works when a popup is open
                    return(OLECMDF.OLECMDF_SUPPORTED);
                }

                case GitDiffMarginCommand.ShowDiff:
                {
                    EditorDiffMarginViewModel viewModel;
                    if (!TryGetMarginViewModel(out viewModel))
                    {
                        return(0);
                    }

                    if (viewModel.DiffViewModels.Any())
                    {
                        return(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED);
                    }
                    else
                    {
                        return(OLECMDF.OLECMDF_SUPPORTED);
                    }
                }

                case GitDiffMarginCommand.GitDiffToolbar:
                case GitDiffMarginCommand.GitDiffToolbarGroup:
                    // these aren't actually commands, but IDs of the command bars and groups
                    break;

                default:
                    break;
                }
            }

            return(0);
        }
        protected override bool HandlePreExec(ref Guid commandGroup, uint commandId, OLECMDEXECOPT executionOptions, IntPtr pvaIn, IntPtr pvaOut)
        {
            if (commandGroup == typeof(GitDiffMarginCommand).GUID)
            {
                EditorDiffMarginViewModel viewModel     = null;
                EditorDiffViewModel       diffViewModel = null;
                if (TryGetMarginViewModel(out viewModel))
                {
                    diffViewModel = viewModel.DiffViewModels.OfType <EditorDiffViewModel>().FirstOrDefault(i => i.ShowPopup);
                }

                switch ((GitDiffMarginCommand)commandId)
                {
                case GitDiffMarginCommand.ShowPopup:
                {
                    diffViewModel = GetCurrentDiffViewModel(viewModel);

                    if (diffViewModel != null)
                    {
                        diffViewModel.ShowPopup = true;
                        return(true);
                    }

                    return(false);
                }

                case GitDiffMarginCommand.PreviousChange:
                case GitDiffMarginCommand.NextChange:
                {
                    if (viewModel == null)
                    {
                        return(false);
                    }

                    RelayCommand <DiffViewModel> command = (GitDiffMarginCommand)commandId == GitDiffMarginCommand.NextChange ? viewModel.NextChangeCommand : viewModel.PreviousChangeCommand;

                    // First look for a diff already showing a popup
                    if (diffViewModel != null)
                    {
                        command.Execute(diffViewModel);
                        return(true);
                    }

                    diffViewModel = GetDiffViewModelToMoveTo(commandId, viewModel);

                    if (diffViewModel == null)
                    {
                        return(false);
                    }

                    viewModel.MoveToChange(diffViewModel, 0);
                    return(true);
                }

                case GitDiffMarginCommand.RollbackChange:
                case GitDiffMarginCommand.CopyOldText:
                {
                    if (diffViewModel == null)
                    {
                        return(false);
                    }

                    ICommand command = (GitDiffMarginCommand)commandId == GitDiffMarginCommand.RollbackChange ? diffViewModel.RollbackCommand : diffViewModel.CopyOldTextCommand;
                    command.Execute(diffViewModel);
                    return(true);
                }

                case GitDiffMarginCommand.ShowDiff:
                {
                    if (diffViewModel == null)
                    {
                        return(false);
                    }

                    ICommand command = diffViewModel.ShowDifferenceCommand;
                    command.Execute(diffViewModel);
                    return(true);
                }

                case GitDiffMarginCommand.GitDiffToolbar:
                case GitDiffMarginCommand.GitDiffToolbarGroup:
                    // these aren't actually commands, but IDs of the command bars and groups
                    break;

                default:
                    break;
                }
            }

            return(false);
        }