static fromSegment(segment, transaction, parentId = null, isRoot = false) {
    const spanContext = segment.getSpanContext()

    // Since segments already hold span agent attributes and we want to leverage
    // filtering, we add to the segment attributes prior to processing.
    if (spanContext.hasError && !transaction.hasIgnoredErrorStatusCode()) {
      const details = spanContext.errorDetails
      segment.addSpanAttribute('error.message', details.message)
      segment.addSpanAttribute('error.class', details.type)
      if (details.expected) {
        segment.addSpanAttribute('error.expected', details.expected)
      }
    }

    const attributes = segment.attributes.get(DESTINATIONS.SPAN_EVENT)

    const customAttributes = spanContext.customAttributes.get(DESTINATIONS.SPAN_EVENT)

    let span = null
    if (HttpSpanEvent.testSegment(segment)) {
      span = new HttpSpanEvent(attributes, customAttributes)
    } else if (DatastoreSpanEvent.testSegment(segment)) {
      span = new DatastoreSpanEvent(attributes, customAttributes)
    } else {
      span = new SpanEvent(attributes, customAttributes)
    }

    for (const [key, value] of Object.entries(spanContext.intrinsicAttributes)) {
      span.intrinsics[key] = value
    }

    span.intrinsics.traceId = transaction.traceId
    span.intrinsics.guid = segment.id
    span.intrinsics.parentId = parentId
    span.intrinsics.transactionId = transaction.id
    span.intrinsics.sampled = transaction.sampled
    span.intrinsics.priority = transaction.priority
    span.intrinsics.name = segment.name

    if (isRoot) {
      span.intrinsics.trustedParentId = transaction.traceContext.trustedParentId
      if (transaction.traceContext.tracingVendors) {
        span.intrinsics.tracingVendors = transaction.traceContext.tracingVendors
      }
    }

    // Only set this if it will be `true`. Must be `null` otherwise.
    if (transaction.baseSegment === segment) {
      span.intrinsics['nr.entryPoint'] = true
    }

    // Timestamp in milliseconds, duration in seconds. Yay consistency!
    span.intrinsics.timestamp = segment.timer.start
    span.intrinsics.duration = segment.timer.getDurationInMillis() / 1000

    addSpanKind({ segment, span })
    return span
  }
Constructs a `SpanEvent` from the given segment.

The constructed span event will contain extra data depending on the
category of the segment.

@param {TraceSegment} segment segment to turn into a span event.
@param {Transaction} transaction active transaction
@param {?string} [parentId] ID of the segment's parent.
@param {boolean} isRoot if segment is root segment
@returns {SpanEvent} The constructed event.