docs: protected TreeNode dfs(Object cell, Object parent, Set<Object> visited) {
      if (visited == null) {
        visited = new HashSet<Object>();
      }
  
      TreeNode node = null;
  
      mxIGraphModel model = graph.getModel();
      if (cell != null && !visited.contains(cell) && (!isVertexIgnored(cell) || isBoundaryEvent(cell))) {
        visited.add(cell);
        node = createNode(cell);
  
        TreeNode prev = null;
        Object[] out = graph.getEdges(cell, parent, invert, !invert, false);
  
        for (int i = 0; i < out.length; i++) {
          Object edge = out[i];
  
          if (!isEdgeIgnored(edge)) {
            // Resets the points on the traversed edge
            if (resetEdges) {
              setEdgePoints(edge, null);
            }
  
            // Checks if terminal in same swimlane
            Object target = graph.getView().getVisibleTerminal(edge, invert);
            TreeNode tmp = dfs(target, parent, visited);
  
            if (tmp != null && model.getGeometry(target) != null) {
              if (prev == null) {
                node.child = tmp;
              } else {
                prev.next = tmp;
              }
  
              prev = tmp;
            }
          }
        }
      }
  
      return node;
    }