@Override
  @RequiresBackgroundThread
  public @NotNull Action visit(@NotNull TreePath path) {
    if (LOG.isTraceEnabled()) LOG.debug("process ", path);
    T element = getElement();
    if (element == null) return Action.SKIP_SIBLINGS;
    Object component = path.getLastPathComponent();
    if (component instanceof AbstractTreeNode) {
      return visit(path, (AbstractTreeNode)component, element);
    }
    if (component instanceof DefaultMutableTreeNode node) {
      Object object = node.getUserObject();
      if (object instanceof AbstractTreeNode) {
        return visit(path, (AbstractTreeNode)object, element);
      }
      else if (object instanceof String) {
        LOG.debug("ignore children: ", object);
      }
      else {
        LOG.warn(object == null ? "no object" : "unexpected object " + object.getClass());
      }
    }
    else if (component instanceof String) {
      LOG.debug("ignore children: ", component);
    }
    else {
      LOG.warn(component == null ? "no component" : "unexpected component " + component.getClass());
    }
    return Action.SKIP_CHILDREN;
  }
@Override
  @RequiresBackgroundThread
  public @NotNull Action visit(@NotNull TreePath path)