public void addSelectionPaths(TreePath[] paths) {
    // unselect all descendants of paths[]
    for (int i = 0; i < paths.length; i++) {
      TreePath path = paths[i];
      TreePath[] selectionPaths = getSelectionPaths();
      if (selectionPaths == null) break;
      ArrayList toBeRemoved = new ArrayList();
      for (int j = 0; j < selectionPaths.length; j++) {
        if (isDescendant(selectionPaths[j], path)) toBeRemoved.add(selectionPaths[j]);
      }
      super.removeSelectionPaths((TreePath[]) toBeRemoved.toArray(new TreePath[0]));
    }

    // if all siblings are selected then unselect them and select parent recursively
    // otherwize just select that path.
    for (int i = 0; i < paths.length; i++) {
      TreePath path = paths[i];
      TreePath temp = null;
      while (areSiblingsSelected(path)) {
        temp = path;
        if (path.getParentPath() == null) break;
        path = path.getParentPath();
      }
      if (temp != null) {
        if (temp.getParentPath() != null) addSelectionPath(temp.getParentPath());
        else {
          if (!isSelectionEmpty()) removeSelectionPaths(getSelectionPaths());
          super.addSelectionPaths(new TreePath[] {temp});
        }
      } else super.addSelectionPaths(new TreePath[] {path});
    }
  }
  // if any ancestor node of given path is selected then unselect it
  //  and selection all its descendants except given path and descendants.
  // otherwise just unselect the given path
  private void toggleRemoveSelection(TreePath path) {
    Stack stack = new Stack();
    TreePath parent = path.getParentPath();
    while (parent != null && !isPathSelected(parent)) {
      stack.push(parent);
      parent = parent.getParentPath();
    }
    if (parent != null) stack.push(parent);
    else {
      super.removeSelectionPaths(new TreePath[] {path});
      return;
    }

    while (!stack.isEmpty()) {
      TreePath temp = (TreePath) stack.pop();
      TreePath peekPath = stack.isEmpty() ? path : (TreePath) stack.peek();
      Object node = temp.getLastPathComponent();
      Object peekNode = peekPath.getLastPathComponent();
      int childCount = model.getChildCount(node);
      for (int i = 0; i < childCount; i++) {
        Object childNode = model.getChild(node, i);
        if (childNode != peekNode)
          super.addSelectionPaths(new TreePath[] {temp.pathByAddingChild(childNode)});
      }
    }
    super.removeSelectionPaths(new TreePath[] {parent});
  }
 @Override
 public void addSelectionPaths(TreePath[] paths) {
   LinkedList<TreePath> filteredPaths = new LinkedList<TreePath>();
   for (TreePath path : paths) {
     if (path.getLastPathComponent() instanceof HierarchicalData) filteredPaths.add(path);
   }
   super.addSelectionPaths(filteredPaths.toArray(new TreePath[0]));
 }