@Nullable
 private static Change[] loadFakeRevisions(final Project project, final Change[] changes) {
   List<Change> matchingChanges = new ArrayList<Change>();
   for (Change change : changes) {
     matchingChanges.addAll(
         ChangeListManager.getInstance(project).getChangesIn(ChangesUtil.getFilePath(change)));
   }
   return matchingChanges.toArray(new Change[matchingChanges.size()]);
 }
  public void actionPerformed(final AnActionEvent e) {
    final Project project = e.getData(CommonDataKeys.PROJECT);
    if (project == null) return;
    if (ChangeListManager.getInstance(project).isFreezedWithNotification(null)) return;
    final Change[] changes = e.getData(VcsDataKeys.CHANGES);
    if (changes == null) return;

    final boolean needsConvertion = checkIfThereAreFakeRevisions(project, changes);
    final List<Change> changesInList = e.getData(VcsDataKeys.CHANGES_IN_LIST_KEY);

    // this trick is essential since we are under some conditions to refresh changes;
    // but we can only rely on callback after refresh
    final Runnable performer =
        new Runnable() {
          public void run() {
            Change[] convertedChanges;
            if (needsConvertion) {
              convertedChanges = loadFakeRevisions(project, changes);
            } else {
              convertedChanges = changes;
            }

            if (convertedChanges == null || convertedChanges.length == 0) {
              return;
            }

            List<Change> changesInListCopy = changesInList;

            int index = 0;
            if (convertedChanges.length == 1) {
              final Change selectedChange = convertedChanges[0];
              ChangeList changeList =
                  ((ChangeListManagerImpl) ChangeListManager.getInstance(project))
                      .getIdentityChangeList(selectedChange);
              if (changeList != null) {
                if (changesInListCopy == null) {
                  changesInListCopy = new ArrayList<Change>(changeList.getChanges());
                  Collections.sort(
                      changesInListCopy,
                      new Comparator<Change>() {
                        public int compare(final Change o1, final Change o2) {
                          return ChangesUtil.getFilePath(o1)
                              .getName()
                              .compareToIgnoreCase(ChangesUtil.getFilePath(o2).getName());
                        }
                      });
                }
                convertedChanges = changesInListCopy.toArray(new Change[changesInListCopy.size()]);
                index =
                    Math.max(0, ContainerUtil.indexOfIdentity(changesInListCopy, selectedChange));
              }
            }

            showDiffForChange(convertedChanges, index, project);
          }
        };

    if (needsConvertion) {
      ChangeListManager.getInstance(project)
          .invokeAfterUpdate(
              performer,
              InvokeAfterUpdateMode.BACKGROUND_CANCELLABLE,
              ourText,
              ModalityState.current());
    } else {
      performer.run();
    }
  }