public static void buildObjectInfoMap(
            final ObjectMapper objectMapper,
            final AbstractConfig config,
            final PropertyPath path,
            final Map<PropertyPath, ObjectInfo<? extends AbstractConfig>> objectInfoMap) {

        config.setBasePath(path);

        final ObjectInfo<AbstractConfig> objectInfo = PropertyUtil.getObjectInfo(
                objectMapper,
                path.getPropertyName(),
                config);

        if (objectInfo.getConstructor() == null) {
            throw new RuntimeException("No JsonCreator constructor for " + config.getClass().getName());
        }

        // Decorate the config object with its path info, so it knows where it lives in the tree
        objectInfoMap.put(path, objectInfo);

        objectInfo.getPropertyMap()
                .forEach((k, prop) -> {
                    final PropertyPath fullPath = path.merge(prop.getName());

                    final Class<?> valueType = prop.getValueClass();

                    LOGGER.trace(() -> LogUtil.message("prop: {}, class: {}", prop, prop.getValueClass()));

                    if (AbstractConfig.class.isAssignableFrom(valueType)) {
                        final AbstractConfig childConfigObject = (AbstractConfig) prop.getValueFromConfigObject();
                        // This must be a branch, i.e. config object so recurse into that
                        if (childConfigObject != null) {
                            // Recurse into the child
                            buildObjectInfoMap(
                                    objectMapper,
                                    childConfigObject,
                                    fullPath,
                                    objectInfoMap);
                        }
                    }
                });

    }
Populates objectInfoMap with an {@link ObjectInfo} object for each sub-class of {@link AbstractConfig}
that is not marked as {@link stroom.util.shared.NotInjectableConfig}. It walks the object tree from
the passed config object downwards. path is used as the property path for the root config

@param config The root config
stroom-util/src/main/java/stroom/util/config/AbstractConfigUtil.java