public static void deleteNodeRecursivelyMultiOrSequential(ZKWatcher zkw,
    boolean runSequentialOnMultiFailure, String... pathRoots) throws KeeperException {
    if (pathRoots == null || pathRoots.length <= 0) {
      LOG.warn("Given path is not valid!");
      return;
    }
    List<ZKUtilOp> ops = new ArrayList<>();
    for (String eachRoot : pathRoots) {
      List<String> children = listChildrenBFSNoWatch(zkw, eachRoot);
      // Delete the leaves first and eventually get rid of the root
      for (int i = children.size() - 1; i >= 0; --i) {
        ops.add(ZKUtilOp.deleteNodeFailSilent(children.get(i)));
      }
      try {
        if (zkw.getRecoverableZooKeeper().exists(eachRoot, zkw) != null) {
          ops.add(ZKUtilOp.deleteNodeFailSilent(eachRoot));
        }
      } catch (InterruptedException e) {
        zkw.interruptedException(e);
      }
    }
    submitBatchedMultiOrSequential(zkw, runSequentialOnMultiFailure, ops);
  }
Delete the specified node and its children. This traverse the znode tree for listing the
children and then delete these znodes including the parent using multi-update api or sequential
based on the specified configurations.
<p>
Sets no watches. Throws all exceptions besides dealing with deletion of children.
<p>
If the following is true:
<ul>
<li>runSequentialOnMultiFailure is true
</ul>
on calling multi, we get a ZooKeeper exception that can be handled by a sequential call(*), we
retry the operations one-by-one (sequentially). - zk reference - if true when we get a
ZooKeeper exception that could retry the operations one-by-one (sequentially) - path of the
parent node(s)
@throws KeeperException.NotEmptyException if node has children while deleting if unexpected
                                          ZooKeeper exception if an invalid path is specified
hbase-zookeeper/src/main/java/org/apache/hadoop/hbase/zookeeper/ZKUtil.java