public void toggleSelection(final DefaultMutableTreeNode node) {
    final StateWorker stateWorker = new StateWorker(node, myNodeConvertor);
    final VirtualFile vf = stateWorker.getVf();
    if (vf == null) return;

    final TreeNodeState state = getStateImpl(stateWorker);
    if (TreeNodeState.HAVE_SELECTED_ABOVE.equals(state)) return;
    if (TreeNodeState.CLEAR.equals(state) && (! myState.canAddSelection())) return;

    final Set<VirtualFile> old = myState.getSelected();

    final TreeNodeState futureState =
      myState.putAndPass(vf, TreeNodeState.SELECTED.equals(state) ? TreeNodeState.CLEAR : TreeNodeState.SELECTED);

    // for those possibly duplicate nodes (i.e. when we have root for module and root for VCS root, each file is shown twice in a tree ->
    // clear all suspicious cached)
    if (! TreeNodeState.SELECTED.equals(futureState)) {
      myState.clearAllCachedMatching(virtualFile -> VfsUtilCore.isAncestor(virtualFile, vf, false));
    }
    stateWorker.iterateParents(myState, (virtualFile, state1) -> {
      if (TreeNodeState.SELECTED.equals(futureState)) {
        myState.putAndPass(virtualFile, TreeNodeState.HAVE_SELECTED_BELOW);
      } else {
        myState.remove(virtualFile);
      }
      return true;
    });
    // todo vf, vf - what is correct?
    myState.clearAllCachedMatching(vf1 -> VfsUtilCore.isAncestor(stateWorker.getVf(), vf1, false));
    for (VirtualFile selected : myState.getSelected()) {
      if (VfsUtilCore.isAncestor(stateWorker.getVf(), selected, true)) {
        myState.remove(selected);
      }
    }
    final Set<VirtualFile> selectedAfter = myState.getSelected();
    if (mySelectionChangeListener != null && ! old.equals(selectedAfter)) {
      final Collection<VirtualFile> removed = subtract(old, selectedAfter);
      final Collection<VirtualFile> newlyAdded = subtract(selectedAfter, old);
      for (VirtualFile file : newlyAdded) {
        if (mySelectionChangeListener != null) {
          mySelectionChangeListener.plus(file);
        }
      }
      for (VirtualFile file : removed) {
        if (mySelectionChangeListener != null) {
          mySelectionChangeListener.minus(file);
        }
      }
    }
  }
public void toggleSelection(final DefaultMutableTreeNode node)