class GoogleHadoopSyncableOutputStream extends OutputStream implements Syncable {

  @Override
  public void close() throws IOException {
    logger.atFine().log(
        "close(): Current tail file: %s final destination: %s", curGcsPath, finalGcsPath);
    if (!isOpen()) {
      logger.atFinest().log("close(): Ignoring; stream already closed.");
      return;
    }
    commitCurrentFile();

    // null denotes stream closed.
    // TODO(user): Add checks which throw IOException if further operations are attempted on a
    // closed stream, except for multiple calls to close(), which should behave as no-ops.
    curGcsPath = null;
    curDelegate = null;

    logger.atFine().log("close(): Awaiting %s deletionFutures", deletionFutures.size());
    for (Future<?> deletion : deletionFutures) {
      try {
        deletion.get();
      } catch (ExecutionException | InterruptedException e) {
        if (e instanceof InterruptedException) {
          Thread.currentThread().interrupt();
        }
        throw new IOException("Failed to delete files while closing stream", e);
      }
    }
  }

  public  GoogleHadoopSyncableOutputStream(
      GoogleHadoopFileSystemBase ghfs,
      URI gcsPath,
      FileSystem.Statistics statistics,
      CreateFileOptions createFileOptions,
      SyncableOutputStreamOptions options);
  @VisibleForTesting  GoogleHadoopSyncableOutputStream(
      GoogleHadoopFileSystemBase ghfs,
      URI gcsPath,
      FileSystem.Statistics statistics,
      CreateFileOptions createFileOptions,
      SyncableOutputStreamOptions options,
      ExecutorService cleanupThreadpool);

}