code: @VisibleForTesting
    public static RecordEventsSpanImpl startSpan(
        SpanContext context,
        String name,
        @Nullable Kind kind,
        @Nullable SpanId parentSpanId,
        @Nullable Boolean hasRemoteParent,
        TraceParams traceParams,
        StartEndHandler startEndHandler,
        @Nullable TimestampConverter timestampConverter,
        Clock clock) {
      RecordEventsSpanImpl span =
          new RecordEventsSpanImpl(
              context,
              name,
              kind,
              parentSpanId,
              hasRemoteParent,
              traceParams,
              startEndHandler,
              timestampConverter,
              clock);
      // Call onStart here instead of calling in the constructor to make sure the span is completely
      // initialized.
      startEndHandler.onStart(span);
      return span;
    }
docs: Creates and starts a span with the given configuration.
  
  @param context supplies the trace_id and span_id for the newly started span.
  @param name the displayed name for the new span.
  @param parentSpanId the span_id of the parent span, or null if the new span is a root span.
  @param hasRemoteParent {@code true} if the parentContext is remote. {@code null} if this is a
  root span.
  @param traceParams trace parameters like sampler and probability.
  @param startEndHandler handler called when the span starts and ends.
  @param timestampConverter null if the span is a root span or the parent is not sampled. If the
  parent is sampled, we should use the same converter to ensure ordering between tracing
  events.
  @param clock the clock used to get the time.
  @return a new and started span.