class Config {
        Integer startDelaySeconds = 0;
        String jmxUrl = "";
        String username = "";
        String password = "";
        boolean ssl = false;
        boolean lowercaseOutputName;
        boolean lowercaseOutputLabelNames;
        List<ObjectName> includeObjectNames = new ArrayList<>();
        List<ObjectName> excludeObjectNames = new ArrayList<>();
        ObjectNameAttributeFilter objectNameAttributeFilter;
        List<Rule> rules = new ArrayList<>();
        long lastUpdate = 0L;

        MatchedRulesCache rulesCache;
    }

    private PrometheusRegistry prometheusRegistry;
    private Config config;
    private File configFile;
    private long createTimeNanoSecs = System.nanoTime();

    private Counter configReloadSuccess;
    private Counter configReloadFailure;
    private Gauge jmxScrapeDurationSeconds;
    private Gauge jmxScrapeError;
    private Gauge jmxScrapeCachedBeans;

    private final JmxMBeanPropertyCache jmxMBeanPropertyCache = new JmxMBeanPropertyCache();

    public JmxCollector(File in) throws IOException, MalformedObjectNameException {
        this(in, null);
    }

    public JmxCollector(File in, Mode mode) throws IOException, MalformedObjectNameException {
        configFile = in;
        this.mode = mode;
        config = loadConfig(new Yaml().load(new FileReader(in)));
        config.lastUpdate = configFile.lastModified();
        exitOnConfigError();
    }

    public JmxCollector(String yamlConfig) throws MalformedObjectNameException {
        config = loadConfig(new Yaml().load(yamlConfig));
        mode = null;
    }

    public JmxCollector(InputStream inputStream) throws MalformedObjectNameException {
        config = loadConfig(new Yaml().load(inputStream));
        mode = null;
    }

    public JmxCollector register() {
        return register(PrometheusRegistry.defaultRegistry);
    }

    public JmxCollector register(PrometheusRegistry prometheusRegistry) {
        this.prometheusRegistry = prometheusRegistry;

        configReloadSuccess =
                Counter.builder()
                        .name("jmx_config_reload_success_total")
                        .help("Number of times configuration have successfully been reloaded.")
                        .register(prometheusRegistry);

        configReloadFailure =
                Counter.builder()
                        .name("jmx_config_reload_failure_total")
                        .help("Number of times configuration have failed to be reloaded.")
                        .register(prometheusRegistry);

        jmxScrapeDurationSeconds =
                Gauge.builder()
                        .name("jmx_scrape_duration_seconds")
                        .help("Time this JMX scrape took, in seconds.")
                        .unit(Unit.SECONDS)
                        .register(prometheusRegistry);

        jmxScrapeError =
                Gauge.builder()
                        .name("jmx_scrape_error")
                        .help("Non-zero if this scrape failed.")
                        .register(prometheusRegistry);

        jmxScrapeCachedBeans =
                Gauge.builder()
                        .name("jmx_scrape_cached_beans")
                        .help("Number of beans with their matching rule cached")
                        .register(prometheusRegistry);

        prometheusRegistry.register(this);

        return this;
    }

    private void exitOnConfigError() {
        if (mode == Mode.AGENT && !config.jmxUrl.isEmpty()) {
            LOGGER.log(
                    SEVERE,
                    "Configuration error: When running jmx_exporter as a Java agent, you must not"
                        + " configure 'jmxUrl' or 'hostPort' because you don't want to monitor a"
                        + " remote JVM.");
            System.exit(-1);
        }
        if (mode == Mode.STANDALONE && config.jmxUrl.isEmpty()) {
            LOGGER.log(
                    SEVERE,
                    "Configuration error: When running jmx_exporter in standalone mode (using"
                            + " jmx_prometheus_httpserver-*.jar) you must configure 'jmxUrl' or"
                            + " 'hostPort'.");
            System.exit(-1);
        }
    }

    private void reloadConfig() {<FILL_FUNCTION_BODY>

        try {
            FileReader fr = new FileReader(configFile);

            try {
                Map<String, Object> newYamlConfig = new Yaml().load(fr);
                config = loadConfig(newYamlConfig);
                config.lastUpdate = configFile.lastModified();
                configReloadSuccess.inc();
            } catch (Exception e) {
                LOGGER.log(SEVERE, "Configuration reload failed: %s: ", e);
                configReloadFailure.inc();
            } finally {
                fr.close();
            }

        } catch (IOException e) {
            LOGGER.log(SEVERE, "Configuration reload failed: %s", e);
            configReloadFailure.inc();
        }
    
<no_super_class>