/**
   * Submits a command via the session.
   *
   * @param command The command to submit.
   * @param <T> The command output type.
   * @return A completable future to be completed with the command output.
   */
  public <T> CompletableFuture<T> submit(Command<T> command) {
    if (!isOpen()) return Futures.exceptionalFuture(new IllegalStateException("session not open"));

    CompletableFuture<T> future = new CompletableFuture<>();
    context
        .executor()
        .execute(
            () -> {
              CommandRequest request;
              if (command.consistency() == Command.ConsistencyLevel.NONE) {
                request =
                    CommandRequest.builder()
                        .withSession(id)
                        .withSequence(0)
                        .withCommand(command)
                        .build();
              } else {
                request =
                    CommandRequest.builder()
                        .withSession(id)
                        .withSequence(++commandRequest)
                        .withCommand(command)
                        .build();
              }

              submit(request, future);
            });
    return future;
  }
  /** Recursively submits a command. */
  @SuppressWarnings("unchecked")
  private <T> CompletableFuture<T> submit(CommandRequest request, CompletableFuture<T> future) {
    if (!isOpen()) {
      future.completeExceptionally(new IllegalStateException("session not open"));
      return future;
    }

    long sequence = ++requestSequence;

    this.<CommandRequest, CommandResponse>request(request)
        .whenComplete(
            (response, error) -> {
              if (error == null) {
                long responseSequence = request.sequence();
                sequenceResponse(
                    sequence,
                    () -> {
                      commandResponse = responseSequence;
                      completeResponse(response, future);
                    });
              } else {
                future.completeExceptionally(error);
              }
            });
    return future;
  }