/**
   * Delete the node with the given path. The call will succeed if such a node exists, and the given
   * version matches the node's version (if the given version is -1, it matches any node's
   * versions).
   *
   * <p>A KeeperException with error code KeeperException.NoNode will be thrown if the nodes does
   * not exist.
   *
   * <p>A KeeperException with error code KeeperException.BadVersion will be thrown if the given
   * version does not match the node's version.
   *
   * <p>A KeeperException with error code KeeperException.NotEmpty will be thrown if the node has
   * children.
   *
   * <p>This operation, if successful, will trigger all the watches on the node of the given path
   * left by exists API calls, and the watches on the parent node left by getChildren API calls.
   *
   * @param path the path of the node to be deleted.
   * @param version the expected node version.
   * @throws InterruptedException IF the server transaction is interrupted
   * @throws KeeperException If the server signals an error with a non-zero return code.
   * @throws IllegalArgumentException if an invalid path is specified
   */
  public void delete(final String path, int version) throws InterruptedException, KeeperException {
    final String clientPath = path;
    PathUtils.validatePath(clientPath);

    final String serverPath;

    // maintain semantics even in chroot case
    // specifically - root cannot be deleted
    // I think this makes sense even in chroot case.
    if (clientPath.equals("/")) {
      // a bit of a hack, but delete(/) will never succeed and ensures
      // that the same semantics are maintained
      serverPath = clientPath;
    } else {
      serverPath = prependChroot(clientPath);
    }

    RequestHeader h = new RequestHeader();
    h.setType(ZooDefs.OpCode.delete);
    DeleteRequest request = new DeleteRequest();
    request.setPath(serverPath);
    request.setVersion(version);
    ReplyHeader r = cnxn.submitRequest(h, request, null, null);
    if (r.getErr() != 0) {
      throw KeeperException.create(KeeperException.Code.get(r.getErr()), clientPath);
    }
  }
  /**
   * The Asynchronous version of delete. The request doesn't actually until the asynchronous
   * callback is called.
   *
   * @see #delete(String, int)
   */
  public void delete(final String path, int version, VoidCallback cb, Object ctx) {
    final String clientPath = path;
    PathUtils.validatePath(clientPath);

    final String serverPath;

    // maintain semantics even in chroot case
    // specifically - root cannot be deleted
    // I think this makes sense even in chroot case.
    if (clientPath.equals("/")) {
      // a bit of a hack, but delete(/) will never succeed and ensures
      // that the same semantics are maintained
      serverPath = clientPath;
    } else {
      serverPath = prependChroot(clientPath);
    }

    RequestHeader h = new RequestHeader();
    h.setType(ZooDefs.OpCode.delete);
    DeleteRequest request = new DeleteRequest();
    request.setPath(serverPath);
    request.setVersion(version);
    cnxn.queuePacket(h, new ReplyHeader(), request, null, cb, clientPath, serverPath, ctx, null);
  }