private @Nullable List<Node> getValidChildren(@NotNull Node node) {
    NodeDescriptor<?> descriptor = node.getDescriptor();
    if (descriptor == null) return null;

    Object parent = descriptor.getElement();
    if (!isValid(structure, parent)) return null;

    Object[] elements = structure.getChildElements(parent);
    if (elements.length == 0) return null;

    List<Node> list = new ArrayList<>(elements.length);
    var freshChildren = freshChildrenSet.get().get();
    for (Object element : elements) {
      ProgressManager.checkCanceled();
      if (isValid(structure, element)) {
        Node newChild = new Node(structure, element, descriptor);
        if (freshChildren != null) {
          freshChildren.add(newChild);
        }
        list.add(newChild); // an exception may be thrown while getting children
      }
    }
    Comparator<? super Node> comparator = this.comparator;
    if (comparator != null) {
      try {
        list.sort(comparator); // an exception may be thrown while sorting children
      }
      catch (IllegalArgumentException exception) {
        StringBuilder sb = new StringBuilder("unexpected sorting failed in ");
        sb.append(this);
        for (Node next : list) sb.append('\n').append(next);
        LOG.error(sb.toString(), exception);
      }
    }
    HashMap<Object, Node> map = new HashMap<>();
    node.getChildren().forEach(child -> {
      ProgressManager.checkCanceled();
      Object element = child.getElement();
      if (element != null) map.put(element, child);
    });
    for (int i = 0; i < list.size(); i++) {
      ProgressManager.checkCanceled();
      Node newNode = list.get(i);
      Node oldNode = map.get(newNode.getElement());
      if (oldNode != null && oldNode.canReuse(newNode, null)) {
        list.set(i, oldNode); // reuse old node with possible children
      }
    }
    return list;
  }
private @Nullable List<Node> getValidChildren(@NotNull Node node)