docs: private static List<JoinNode> generateFullJoinOrdersForTree(JoinNode subTree) {
          assert(subTree != null);
          List<JoinNode> joinOrders = new ArrayList<>();
          if (!(subTree instanceof BranchNode)) {
              // End of recursion
              joinOrders.add(subTree);
              return joinOrders;
          }
          BranchNode branchNode = (BranchNode) subTree;
          // Descend to the left branch
          assert(branchNode.getLeftNode() != null);
          List<JoinNode> leftJoinOrders = generateFullJoinOrdersForTree(branchNode.getLeftNode());
          assert(!leftJoinOrders.isEmpty());
          // Descend to the right branch
          assert(branchNode.getRightNode() != null);
          List<JoinNode> rightJoinOrders = generateFullJoinOrdersForTree(branchNode.getRightNode());
          assert(!rightJoinOrders.isEmpty());
          // Create permutation pairing left and right nodes and the revere variant
          for (JoinNode leftNode : leftJoinOrders) {
              for (JoinNode rightNode : rightJoinOrders) {
                  JoinNode resultOne = new BranchNode(branchNode.getId(), branchNode.getJoinType(),
                          (JoinNode) leftNode.clone(), (JoinNode) rightNode.clone());
                  JoinNode resultTwo = new BranchNode(branchNode.getId(), branchNode.getJoinType(),
                          (JoinNode) rightNode.clone(), (JoinNode) leftNode.clone());
                  if (branchNode.getJoinExpression() != null) {
                      resultOne.setJoinExpression(branchNode.getJoinExpression().clone());
                      resultTwo.setJoinExpression(branchNode.getJoinExpression().clone());
                  }
                  if (branchNode.getWhereExpression() != null) {
                      resultOne.setWhereExpression(branchNode.getWhereExpression().clone());
                      resultTwo.setWhereExpression(branchNode.getWhereExpression().clone());
                  }
                  joinOrders.add(resultOne);
                  joinOrders.add(resultTwo);
              }
          }
          return joinOrders;
      }