public override void OnExecute(CommandEventArgs e)
        {
            List<GitItem> toRevert = new List<GitItem>();
            HybridCollection<string> contained = new HybridCollection<string>(StringComparer.OrdinalIgnoreCase);
            HybridCollection<string> checkedItems = null;

            foreach (GitItem i in e.Selection.GetSelectedGitItems(false))
            {
                if (contained.Contains(i.FullPath))
                    continue;

                contained.Add(i.FullPath);

                if (i.IsModified || (i.IsVersioned && i.IsDocumentDirty) || i.IsConflicted)
                    toRevert.Add(i);
            }

            Predicate<GitItem> initialCheckedFilter = null;
            if (toRevert.Count > 0)
            {
                checkedItems = new HybridCollection<string>(contained, StringComparer.OrdinalIgnoreCase);

                initialCheckedFilter = delegate(GitItem item)
                    {
                        return checkedItems.Contains(item.FullPath);
                    };
            }

            foreach (GitItem i in e.Selection.GetSelectedGitItems(true))
            {
                if (contained.Contains(i.FullPath))
                    continue;

                contained.Add(i.FullPath);

                if (i.IsModified || (i.IsVersioned && i.IsDocumentDirty))
                    toRevert.Add(i);
            }

            if (e.PromptUser || (!e.DontPrompt && !Shift))
            {
                using (PendingChangeSelector pcs = new PendingChangeSelector())
                {
                    pcs.Text = CommandStrings.RevertDialogTitle;

                    pcs.PreserveWindowPlacement = true;

                    pcs.LoadItems(toRevert, null, initialCheckedFilter);

                    if (pcs.ShowDialog(e.Context) != DialogResult.OK)
                        return;

                    toRevert.Clear();
                    toRevert.AddRange(pcs.GetSelectedItems());
                }
            }

            IVisualGitOpenDocumentTracker documentTracker = e.GetService<IVisualGitOpenDocumentTracker>();

            ICollection<string> revertPaths = GitItem.GetPaths(toRevert);
            documentTracker.SaveDocuments(revertPaths);

            // perform the actual revert
            using (DocumentLock dl = documentTracker.LockDocuments(revertPaths, DocumentLockType.NoReload))
            using (dl.MonitorChangesForReload())
            {
                e.GetService<IProgressRunner>().RunModal(CommandStrings.Reverting,
                delegate(object sender, ProgressWorkerArgs a)
                {
                    GitRevertItemArgs ra = new GitRevertItemArgs();
                    ra.Depth = GitDepth.Empty;

                    List<string> toRevertPaths = new List<string>();

                    foreach (GitItem item in toRevert)
                    {
                        toRevertPaths.Add(item.FullPath);
                    }

                    foreach (GitItem item in toRevert)
                    {
                        try
                        {
                            a.Client.RevertItem(toRevertPaths, ra);
                        }
                        catch (GitNoRepositoryException)
                        {
                            // Ignore path no repository exceptions.
                        }
                    }
                });
            }
        }
        public override void OnExecute(CommandEventArgs e)
        {
            IPendingChangesManager pcm = e.GetService<IPendingChangesManager>();
            Dictionary<string, PendingChange> changes = new Dictionary<string, PendingChange>(StringComparer.OrdinalIgnoreCase);

            foreach (PendingChange pc in pcm.GetAll())
            {
                if (!changes.ContainsKey(pc.FullPath))
                    changes.Add(pc.FullPath, pc);
            }

            Dictionary<string, GitItem> selectedChanges = new Dictionary<string, GitItem>(StringComparer.OrdinalIgnoreCase);
            foreach (GitItem item in e.Selection.GetSelectedGitItems(true))
            {
                if (changes.ContainsKey(item.FullPath) &&
                    !selectedChanges.ContainsKey(item.FullPath))
                {
                    selectedChanges.Add(item.FullPath, item);
                }
            }

            Collection<GitItem> resources = new Collection<GitItem>();
            List<GitItem> selectedItems = new List<GitItem>(selectedChanges.Values);

            // TODO: Give the whole list to a refreshable dialog!
            foreach (GitItem item in selectedItems)
            {
                PendingChange pc = changes[item.FullPath];

                if (pc.IsChangeForPatching())
                    continue;

                resources.Add(item);
            }
            if (resources.Count == 0)
                return;

            using (PendingChangeSelector pcs = new PendingChangeSelector())
            {
                pcs.Context = e.Context;
                pcs.Text = CommandStrings.CreatePatchTitle;

                pcs.PreserveWindowPlacement = true;

                pcs.LoadItems(e.Selection.GetSelectedGitItems(true));

                DialogResult dr = pcs.ShowDialog(e.Context);

                if (dr != DialogResult.OK)
                    return;

                string fileName = GetFileName(e.Context.DialogOwner);
                if (string.IsNullOrEmpty(fileName))
                {
                    return;
                }

                PendingChangeCreatePatchArgs pca = new PendingChangeCreatePatchArgs();
                pca.FileName = fileName;
                IVisualGitSolutionSettings ss = e.GetService<IVisualGitSolutionSettings>();
                pca.RelativeToPath = ss.ProjectRoot;
                pca.AddUnversionedFiles = true;

                List<PendingChange> patchChanges = new List<PendingChange>(pcs.GetSelection());
                e.GetService<IPendingChangeHandler>().CreatePatch(patchChanges, pca);
            }
        }