/**
   * The Asynchronous version of getACL. The request doesn't actually until the asynchronous
   * callback is called.
   *
   * @see #getACL(String, Stat)
   */
  public void getACL(final String path, Stat stat, ACLCallback cb, Object ctx) {
    final String clientPath = path;
    PathUtils.validatePath(clientPath);

    final String serverPath = prependChroot(clientPath);

    RequestHeader h = new RequestHeader();
    h.setType(ZooDefs.OpCode.getACL);
    GetACLRequest request = new GetACLRequest();
    request.setPath(serverPath);
    GetACLResponse response = new GetACLResponse();
    cnxn.queuePacket(
        h, new ReplyHeader(), request, response, cb, clientPath, serverPath, ctx, null);
  }
  /**
   * Return the ACL and stat of the node of the given path.
   *
   * <p>A KeeperException with error code KeeperException.NoNode will be thrown if no node with the
   * given path exists.
   *
   * @param path the given path for the node
   * @param stat the stat of the node will be copied to this parameter.
   * @return the ACL array of the given node.
   * @throws InterruptedException If the server transaction is interrupted.
   * @throws KeeperException If the server signals an error with a non-zero error code.
   * @throws IllegalArgumentException if an invalid path is specified
   */
  public List<ACL> getACL(final String path, Stat stat)
      throws KeeperException, InterruptedException {
    final String clientPath = path;
    PathUtils.validatePath(clientPath);

    final String serverPath = prependChroot(clientPath);

    RequestHeader h = new RequestHeader();
    h.setType(ZooDefs.OpCode.getACL);
    GetACLRequest request = new GetACLRequest();
    request.setPath(serverPath);
    GetACLResponse response = new GetACLResponse();
    ReplyHeader r = cnxn.submitRequest(h, request, response, null);
    if (r.getErr() != 0) {
      throw KeeperException.create(KeeperException.Code.get(r.getErr()), clientPath);
    }
    DataTree.copyStat(response.getStat(), stat);
    return response.getAcl();
  }