docs: public static List<Span> merge(List<Span> spans) {
      int length = spans.size();
      if (length <= 1) return spans;
      List<Span> result = new ArrayList<>(spans);
      Collections.sort(result, CLEANUP_COMPARATOR);
  
      // Let's cleanup any spans and pick the longest ID
      String traceId = result.get(0).traceId();
      for (int i = 1; i < length; i++) {
        String nextTraceId = result.get(i).traceId();
        if (traceId.length() != 32) traceId = nextTraceId;
      }
  
      // Now start any fixes or merging
      Span last = null;
      for (int i = 0; i < length; i++) {
        Span span = result.get(i);
        //String previousId = last.id();
        boolean spanShared = Boolean.TRUE.equals(span.shared());
  
        // Choose the longest trace ID
        Span.Builder replacement = null;
        if (span.traceId().length() != traceId.length()) {
          replacement = span.toBuilder().traceId(traceId);
        }
  
        EndpointTracker localEndpoint = null;
        while (i + 1 < length) {
          Span next = result.get(i + 1);
          String nextId = next.id();
          if (!nextId.equals(span.id())) break;
  
          if (localEndpoint == null) {
            localEndpoint = new EndpointTracker();
            localEndpoint.tryMerge(span.localEndpoint());
          }
  
          // This cautiously merges with the next span, if we think it was sent in multiple pieces.
          boolean nextShared = Boolean.TRUE.equals(next.shared());
          if (spanShared == nextShared && localEndpoint.tryMerge(next.localEndpoint())) {
            if (replacement == null) replacement = span.toBuilder();
            replacement.merge(next);
  
            // remove the merged element
            length--;
            result.remove(i + 1);
            continue;
          }
          break;
        }
  
        // Zipkin and B3 originally used the same span ID between client and server. Some
        // instrumentation are inconsistent about adding the shared flag on the server side. Since we
        // have the entire trace, and it is ordered client-first, we can correct a missing shared flag.
        if (last != null && last.id().equals(span.id())) {
          // Backfill missing shared flag as some instrumentation doesn't add it
          if (last.kind() == Span.Kind.CLIENT && span.kind() == Span.Kind.SERVER && !spanShared) {
            spanShared = true;
            if (replacement == null) replacement = span.toBuilder();
            replacement.shared(true);
          }
  
          if (spanShared && span.parentId() == null && last.parentId() != null) {
            // handle a shared RPC server span that wasn't propagated its parent span ID
            if (replacement == null) replacement = span.toBuilder();
            replacement.parentId(last.parentId());
          }
        }
  
        if (replacement != null) {
          span = replacement.build();
          result.set(i, span);
        }
        last = span;
      }
  
      return result;
    }