class ConfigObserver {

    public <T> ConfigObserver onPrefixedOptionalValue(String prefix, ConfigListener.Transformer<T> transformer, ConfigValueListener<Optional<T>> listener) {
        return onConfigChange(new ConfigListener() {
            @Override
            public void onConfigChanged(Set<String> changedKeys, ConfigMap newConfiguration) {
                if (changeIncludes(changedKeys, prefix)) {
                    applyConfiguration(
                            listener,
                            newConfiguration.subMap(prefix).map(c -> transform(c, transformer))
                    );
                }
            }
        });
    }

    public  ConfigObserver(String applicationName);
    public  ConfigObserver(File configDirectory, String applicationName);
    public  ConfigObserver(File configDirectory, String applicationName, List<String> profiles);
    public  ConfigObserver(ConfigLoader configLoader);

}