protected VirtualFile getLeadSelectedObject(final ChangesBrowserNode node) {
   final Object o = node.getUserObject();
   if (o instanceof VirtualFile) {
     return (VirtualFile) o;
   }
   return null;
 }
 @Override
 public void calcData(DataKey key, DataSink sink) {
   if (key == VcsDataKeys.CHANGES) {
     sink.put(VcsDataKeys.CHANGES, getSelectedChanges());
   } else if (key == VcsDataKeys.CHANGE_LEAD_SELECTION) {
     sink.put(VcsDataKeys.CHANGE_LEAD_SELECTION, getLeadSelection());
   } else if (key == VcsDataKeys.CHANGE_LISTS) {
     sink.put(VcsDataKeys.CHANGE_LISTS, getSelectedChangeLists());
   } else if (key == PlatformDataKeys.VIRTUAL_FILE_ARRAY) {
     sink.put(PlatformDataKeys.VIRTUAL_FILE_ARRAY, getSelectedFiles());
   } else if (key == PlatformDataKeys.NAVIGATABLE) {
     final VirtualFile[] files = getSelectedFiles();
     if (files.length == 1 && !files[0].isDirectory()) {
       sink.put(PlatformDataKeys.NAVIGATABLE, new OpenFileDescriptor(myProject, files[0], 0));
     }
   } else if (key == PlatformDataKeys.NAVIGATABLE_ARRAY) {
     sink.put(
         PlatformDataKeys.NAVIGATABLE_ARRAY,
         ChangesUtil.getNavigatableArray(myProject, getSelectedFiles()));
   } else if (key == PlatformDataKeys.DELETE_ELEMENT_PROVIDER) {
     final TreePath[] paths = getSelectionPaths();
     if (paths != null) {
       for (TreePath path : paths) {
         ChangesBrowserNode node = (ChangesBrowserNode) path.getLastPathComponent();
         if (!(node.getUserObject() instanceof ChangeList)) {
           sink.put(PlatformDataKeys.DELETE_ELEMENT_PROVIDER, new VirtualFileDeleteProvider());
           break;
         }
       }
     }
   } else if (key == PlatformDataKeys.COPY_PROVIDER) {
     sink.put(PlatformDataKeys.COPY_PROVIDER, myCopyProvider);
   } else if (key == UNVERSIONED_FILES_DATA_KEY) {
     sink.put(UNVERSIONED_FILES_DATA_KEY, getSelectedUnversionedFiles());
   } else if (key == VcsDataKeys.MODIFIED_WITHOUT_EDITING_DATA_KEY) {
     sink.put(VcsDataKeys.MODIFIED_WITHOUT_EDITING_DATA_KEY, getSelectedModifiedWithoutEditing());
   } else if (key == LOCALLY_DELETED_CHANGES) {
     sink.put(LOCALLY_DELETED_CHANGES, getSelectedLocallyDeletedChanges());
   } else if (key == MISSING_FILES_DATA_KEY) {
     sink.put(MISSING_FILES_DATA_KEY, getSelectedMissingFiles());
   } else if (VcsDataKeys.HAVE_LOCALLY_DELETED == key) {
     sink.put(VcsDataKeys.HAVE_LOCALLY_DELETED, haveLocallyDeleted());
   } else if (VcsDataKeys.HAVE_MODIFIED_WITHOUT_EDITING == key) {
     sink.put(VcsDataKeys.HAVE_MODIFIED_WITHOUT_EDITING, haveLocallyModified());
   } else if (VcsDataKeys.HAVE_SELECTED_CHANGES == key) {
     sink.put(VcsDataKeys.HAVE_SELECTED_CHANGES, haveSelectedChanges());
   } else if (key == HELP_ID_DATA_KEY) {
     sink.put(HELP_ID_DATA_KEY, ourHelpId);
   } else if (key == VcsDataKeys.CHANGES_IN_LIST_KEY) {
     final TreePath selectionPath = getSelectionPath();
     if (selectionPath != null && selectionPath.getPathCount() > 1) {
       ChangesBrowserNode<?> firstNode = (ChangesBrowserNode) selectionPath.getPathComponent(1);
       if (firstNode instanceof ChangesBrowserChangeListNode) {
         final List<Change> list = firstNode.getAllChangesUnder();
         sink.put(VcsDataKeys.CHANGES_IN_LIST_KEY, list);
       }
     }
   }
 }
 @Nullable
 protected Change getLeadSelectedObject(@NotNull final ChangesBrowserNode node) {
   final Object o = node.getUserObject();
   if (o instanceof Change) {
     return (Change) o;
   }
   return null;
 }
 protected boolean haveSelectedFileType(final Object tag) {
   final TreePath[] paths = getSelectionPaths();
   if (paths != null) {
     for (TreePath path : paths) {
       if (path.getPathCount() > 1) {
         ChangesBrowserNode firstNode = (ChangesBrowserNode) path.getPathComponent(1);
         if ((tag == null || firstNode.getUserObject() == tag) && path.getPathCount() > 2) {
           return true;
         }
       }
     }
   }
   return false;
 }
 private List<FilePath> getSelectedFilePaths(final Object tag) {
   Set<FilePath> files = new HashSet<FilePath>();
   final TreePath[] paths = getSelectionPaths();
   if (paths != null) {
     for (TreePath path : paths) {
       if (path.getPathCount() > 1) {
         ChangesBrowserNode firstNode = (ChangesBrowserNode) path.getPathComponent(1);
         if (tag == null || firstNode.getUserObject() == tag) {
           ChangesBrowserNode<?> node = (ChangesBrowserNode) path.getLastPathComponent();
           files.addAll(node.getAllFilePathsUnder());
         }
       }
     }
   }
   return new ArrayList<FilePath>(files);
 }
  @NotNull
  private ChangeList[] getSelectedChangeLists() {
    Set<ChangeList> lists = new HashSet<ChangeList>();

    final TreePath[] paths = getSelectionPaths();
    if (paths == null) return new ChangeList[0];

    for (TreePath path : paths) {
      ChangesBrowserNode node = (ChangesBrowserNode) path.getLastPathComponent();
      final Object userObject = node.getUserObject();
      if (userObject instanceof ChangeList) {
        lists.add((ChangeList) userObject);
      }
    }

    return lists.toArray(new ChangeList[lists.size()]);
  }
 private List<LocallyDeletedChange> getSelectedLocallyDeletedChanges() {
   Set<LocallyDeletedChange> files = new HashSet<LocallyDeletedChange>();
   final TreePath[] paths = getSelectionPaths();
   if (paths != null) {
     for (TreePath path : paths) {
       if (path.getPathCount() > 1) {
         ChangesBrowserNode firstNode = (ChangesBrowserNode) path.getPathComponent(1);
         if (firstNode.getUserObject() == TreeModelBuilder.LOCALLY_DELETED_NODE) {
           ChangesBrowserNode<?> node = (ChangesBrowserNode) path.getLastPathComponent();
           final List<LocallyDeletedChange> objectsUnder =
               node.getAllObjectsUnder(LocallyDeletedChange.class);
           files.addAll(objectsUnder);
         }
       }
     }
   }
   return new ArrayList<LocallyDeletedChange>(files);
 }