class PrometheusData<T extends PointData> implements Data<T> {

    private final MetricDataType type;

    public PrometheusData(MetricDataType type) {
        this.type = type;
    }

    public MetricDataType getType() {
        return type;
    }

    protected Attributes labelsToAttributes(Labels labels) {
        if (labels.isEmpty()) {
            return Attributes.empty();
        } else {
            AttributesBuilder builder = Attributes.builder();
            for (int i=0; i<labels.size(); i++) {
                builder.put(labels.getName(i), labels.getValue(i));
            }
            return builder.build();
        }
    }

    protected List<DoubleExemplarData> convertExemplar(Exemplar exemplar) {
        if (exemplar == null) {
            return Collections.emptyList();
        }
        return convertExemplars(Exemplars.of(exemplar));
    }

    protected List<DoubleExemplarData> convertExemplars(Exemplars exemplars) {
        return StreamSupport.stream(exemplars.spliterator(), false)
                .map(this::toDoubleExemplarData)
                .collect(Collectors.toList());
    }

    protected DoubleExemplarData toDoubleExemplarData(Exemplar exemplar) {<FILL_FUNCTION_BODY>}

    protected long getStartEpochNanos(DataPointSnapshot dataPoint) {
        return dataPoint.hasCreatedTimestamp() ? TimeUnit.MILLISECONDS.toNanos(dataPoint.getCreatedTimestampMillis()) : 0L;
    }

    protected long getEpochNanos(DataPointSnapshot dataPoint, long currentTimeMillis) {
        return dataPoint.hasScrapeTimestamp() ? TimeUnit.MILLISECONDS.toNanos(dataPoint.getScrapeTimestampMillis()) : TimeUnit.MILLISECONDS.toNanos(currentTimeMillis);
    }

}

        if (exemplar == null) {
            return null;
        }
        
        AttributesBuilder filteredAttributesBuilder = Attributes.builder();
        String traceId = null;
        String spanId = null;
        for (Label label : exemplar.getLabels()) {
            if (label.getName().equals(Exemplar.TRACE_ID)) {
                traceId = label.getValue();
            }
            else if (label.getName().equals(Exemplar.SPAN_ID)) {
                spanId = label.getValue();
            } else {
                filteredAttributesBuilder.put(label.getName(), label.getValue());
            }
        }
        Attributes filteredAttributes = filteredAttributesBuilder.build();

        SpanContext spanContext = (traceId != null && spanId != null) 
                ? SpanContext.create(traceId, spanId, TraceFlags.getSampled(), TraceState.getDefault()) 
                : SpanContext.getInvalid();

        return ImmutableDoubleExemplarData.create(
                filteredAttributes, 
                TimeUnit.MILLISECONDS.toNanos(exemplar.getTimestampMillis()), 
                spanContext,
                exemplar.getValue());
    
<no_super_class>