class PrometheusMetricProducer implements CollectionRegistration {

    private final PrometheusRegistry registry;
    private final Resource resource;
    private final InstrumentationScopeInfo instrumentationScopeInfo;

    public PrometheusMetricProducer(PrometheusRegistry registry, InstrumentationScopeInfo instrumentationScopeInfo, Resource resource) {
        this.registry = registry;
        this.instrumentationScopeInfo = instrumentationScopeInfo;
        this.resource = resource;
    }

    @Override
    public Collection<MetricData> collectAllMetrics() {<FILL_FUNCTION_BODY>}

    private Resource resourceFromTargetInfo(MetricSnapshots snapshots) {
        ResourceBuilder result = Resource.builder();
        for (MetricSnapshot snapshot : snapshots) {
            if (snapshot.getMetadata().getName().equals("target") && snapshot instanceof InfoSnapshot) {
                InfoSnapshot targetInfo = (InfoSnapshot) snapshot;
                if (targetInfo.getDataPoints().size() > 0) {
                    InfoSnapshot.InfoDataPointSnapshot data = targetInfo.getDataPoints().get(0);
                    Labels labels = data.getLabels();
                    for (int i = 0; i < labels.size(); i++) {
                        result.put(labels.getName(i), labels.getValue(i));
                    }
                }
            }
        }
        return result.build();
    }

    private InstrumentationScopeInfo instrumentationScopeFromOTelScopeInfo(MetricSnapshots snapshots) {
        for (MetricSnapshot snapshot : snapshots) {
            if (snapshot.getMetadata().getPrometheusName().equals("otel_scope") && snapshot instanceof InfoSnapshot) {
                InfoSnapshot scopeInfo = (InfoSnapshot) snapshot;
                if (scopeInfo.getDataPoints().size() > 0) {
                    Labels labels = scopeInfo.getDataPoints().get(0).getLabels();
                    String name = null;
                    String version = null;
                    AttributesBuilder attributesBuilder = Attributes.builder();
                    for (int i = 0; i < labels.size(); i++) {
                        if (labels.getPrometheusName(i).equals("otel_scope_name")) {
                            name = labels.getValue(i);
                        } else if (labels.getPrometheusName(i).equals("otel_scope_version")) {
                            version = labels.getValue(i);
                        } else {
                            attributesBuilder.put(labels.getName(i), labels.getValue(i));
                        }
                    }
                    if (name != null) {
                        return InstrumentationScopeInfo.builder(name)
                                .setVersion(version)
                                .setAttributes(attributesBuilder.build())
                                .build();
                    }
                }
            }
        }
        return null;
    }

    private void addUnlessNull(List<MetricData> result, MetricData data) {
        if (data != null) {
            result.add(data);
        }
    }
}

        // TODO: We could add a filter configuration for the OpenTelemetry exporter and call registry.scrape(filter) if a filter is configured, like in the Servlet exporter.
        MetricSnapshots snapshots = registry.scrape();
        Resource resourceWithTargetInfo = resource.merge(resourceFromTargetInfo(snapshots));
        InstrumentationScopeInfo scopeFromInfo = instrumentationScopeFromOTelScopeInfo(snapshots);
        List<MetricData> result = new ArrayList<>(snapshots.size());
        MetricDataFactory factory = new MetricDataFactory(resourceWithTargetInfo, scopeFromInfo != null ? scopeFromInfo : instrumentationScopeInfo, System.currentTimeMillis());
        for (MetricSnapshot snapshot : snapshots) {
            if (snapshot instanceof CounterSnapshot) {
                addUnlessNull(result, factory.create((CounterSnapshot) snapshot));
            } else if (snapshot instanceof GaugeSnapshot) {
                addUnlessNull(result, factory.create((GaugeSnapshot) snapshot));
            } else if (snapshot instanceof HistogramSnapshot) {
                if (!((HistogramSnapshot) snapshot).isGaugeHistogram()) {
                    addUnlessNull(result, factory.create((HistogramSnapshot) snapshot));
                }
            } else if (snapshot instanceof SummarySnapshot) {
                addUnlessNull(result, factory.create((SummarySnapshot) snapshot));
            } else if (snapshot instanceof InfoSnapshot) {
                String name = snapshot.getMetadata().getPrometheusName();
                if (!name.equals("target") && !name.equals("otel_scope")) {
                    addUnlessNull(result, factory.create((InfoSnapshot) snapshot));
                }
            } else if (snapshot instanceof StateSetSnapshot) {
                addUnlessNull(result, factory.create((StateSetSnapshot) snapshot));
            } else if (snapshot instanceof UnknownSnapshot) {
                addUnlessNull(result, factory.create((UnknownSnapshot) snapshot));
            }
        }
        return result;
    
<no_super_class>