class JvmBufferPoolMetrics {

    private static final String JVM_BUFFER_POOL_USED_BYTES = "jvm_buffer_pool_used_bytes";
    private static final String JVM_BUFFER_POOL_CAPACITY_BYTES = "jvm_buffer_pool_capacity_bytes";
    private static final String JVM_BUFFER_POOL_USED_BUFFERS = "jvm_buffer_pool_used_buffers";

    private final PrometheusProperties config;
    private final List<BufferPoolMXBean> bufferPoolBeans;

    private JvmBufferPoolMetrics(List<BufferPoolMXBean> bufferPoolBeans, PrometheusProperties config) {
        this.config = config;
        this.bufferPoolBeans = bufferPoolBeans;
    }

    private void register(PrometheusRegistry registry) {<FILL_FUNCTION_BODY>}

    public static Builder builder() {
        return new Builder(PrometheusProperties.get());
    }

    public static Builder builder(PrometheusProperties config) {
        return new Builder(config);
    }

    public static class Builder {

        private final PrometheusProperties config;
        private List<BufferPoolMXBean> bufferPoolBeans;

        private Builder(PrometheusProperties config) {
            this.config = config;
        }

        /**
         * Package private. For testing only.
         */
        Builder bufferPoolBeans(List<BufferPoolMXBean> bufferPoolBeans) {
            this.bufferPoolBeans = bufferPoolBeans;
            return this;
        }

        public void register() {
            register(PrometheusRegistry.defaultRegistry);
        }

        public void register(PrometheusRegistry registry) {
            List<BufferPoolMXBean> bufferPoolBeans = this.bufferPoolBeans;
            if (bufferPoolBeans == null) {
                bufferPoolBeans = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);
            }
            new JvmBufferPoolMetrics(bufferPoolBeans, config).register(registry);
        }
    }
}


        GaugeWithCallback.builder(config)
                .name(JVM_BUFFER_POOL_USED_BYTES)
                .help("Used bytes of a given JVM buffer pool.")
                .unit(Unit.BYTES)
                .labelNames("pool")
                .callback(callback -> {
                    for (BufferPoolMXBean pool : bufferPoolBeans) {
                        callback.call(pool.getMemoryUsed(), pool.getName());
                    }
                })
                .register(registry);

        GaugeWithCallback.builder(config)
                .name(JVM_BUFFER_POOL_CAPACITY_BYTES)
                .help("Bytes capacity of a given JVM buffer pool.")
                .unit(Unit.BYTES)
                .labelNames("pool")
                .callback(callback -> {
                    for (BufferPoolMXBean pool : bufferPoolBeans) {
                        callback.call(pool.getTotalCapacity(), pool.getName());
                    }
                })
                .register(registry);

        GaugeWithCallback.builder(config)
                .name(JVM_BUFFER_POOL_USED_BUFFERS)
                .help("Used buffers of a given JVM buffer pool.")
                .labelNames("pool")
                .callback(callback -> {
                    for (BufferPoolMXBean pool : bufferPoolBeans) {
                        callback.call(pool.getCount(), pool.getName());
                    }
                })
                .register(registry);
    
<no_super_class>