docs: public ListenableFuture<SegmentsAndMetadata> publish(
        final TransactionalSegmentPublisher publisher,
        final Committer committer,
        final Collection<String> sequenceNames
    )
    {
      final List<SegmentIdWithShardSpec> theSegments = getSegmentWithStates(sequenceNames)
          .map(SegmentWithState::getSegmentIdentifier)
          .collect(Collectors.toList());
  
      final ListenableFuture<SegmentsAndMetadata> publishFuture = ListenableFutures.transformAsync(
          // useUniquePath=true prevents inconsistencies in segment data when task failures or replicas leads to a second
          // version of a segment with the same identifier containing different data; see DataSegmentPusher.push() docs
          pushInBackground(wrapCommitter(committer), theSegments, true),
          sam -> publishInBackground(
              sam,
              publisher
          )
      );
      return Futures.transform(
          publishFuture,
          (Function<? super SegmentsAndMetadata, ? extends SegmentsAndMetadata>) sam -> {
            synchronized (segments) {
              sequenceNames.forEach(segments::remove);
            }
            return sam;
          }
      );
    }