public static void main(String[] args) throws IOException {
//        final ConfigMapper configMapper = new ConfigMapper();
        final Set<String> simpleNames = new HashSet<>();
        final Map<String, List<String>> simpleNameToFullNamesMap = new HashMap<>();

        final ProxyConfigProvider proxyConfigProvider = new ProxyConfigProvider(new ProxyConfig());
        final Set<Class<? extends AbstractConfig>> injectableClasses = proxyConfigProvider.getInjectableClasses();

        final String header = String.format(CLASS_HEADER,
                GenerateProxyConfigProvidersModule.class.getName(),
                GenerateProxyConfigProvidersModule.class.getName());

        final String methodsStr = injectableClasses
                .stream()
                .sorted(Comparator.comparing(Class::getName))
                .map(clazz -> {
                    final StringBuilder stringBuilder = new StringBuilder();
                    stringBuilder.append(buildMethod(simpleNames, simpleNameToFullNamesMap, clazz));
                    NullSafe.consume(CUSTOM_CLASS_MAPPINGS.get(clazz), interfaceClass ->
                            stringBuilder
                                    .append("\n")
                                    .append("    // Binding ")
                                    .append(clazz.getSimpleName())
                                    .append(" to additional interface ")
                                    .append(interfaceClass.getSimpleName())
                                    .append("\n")
                                    .append(buildMethod(
                                            simpleNames,
                                            simpleNameToFullNamesMap,
                                            clazz,
                                            interfaceClass)));
                    return stringBuilder.toString();
                })
                .collect(Collectors.joining("\n"));

        final Predicate<String> packageNameFilter = name ->
                name.startsWith("stroom") && !name.contains("shaded");

        // Methods that throw for non injectable config
        // We don't want the risk of a dev accidentally injecting a NotInjectable config
        // with the resulting confusion it will cause when it has the wrong values so make
        // providers that always throw.
        final ClassLoader classLoader = GenerateProxyConfigProvidersModule.class.getClassLoader();
        final String notInjectableMethodsStr = ClassPath.from(classLoader)
                .getAllClasses()
                .stream()
                .filter(classInfo -> packageNameFilter.test(classInfo.getPackageName()))
                .map(ClassInfo::load)
                .filter(clazz -> clazz.isAnnotationPresent(NotInjectableConfig.class))
                .filter(AbstractConfig.class::isAssignableFrom)
                .filter(clazz -> IsProxyConfig.class.isAssignableFrom(clazz))
                .sorted(Comparator.comparing(Class::getName))
                .map(clazz ->
                        buildThrowingMethod(simpleNames, simpleNameToFullNamesMap,
                                (Class<? extends AbstractConfig>) clazz))
                .collect(Collectors.joining("\n"));

        final String fileContent = String.join(
                "\n",
                header,
                SEPARATOR,
                methodsStr,
                """
                            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                        """,
                notInjectableMethodsStr,
                CLASS_FOOTER);

        updateFile(fileContent);
    }
IMPORTANT - This whole file is generated using
{@link %s}
DO NOT edit it directly
stroom-proxy/stroom-proxy-app/src/test/java/stroom/proxy/app/guice/GenerateProxyConfigProvidersModule.java