@NotNull
    private PathCreator getPathCreator(final JsonNode rootNode) {
        Objects.requireNonNull(rootNode);

        final Optional<String> optHome = getNodeValue(rootNode, STROOM_HOME_JSON_POINTER);
        final Optional<String> optTemp = getNodeValue(rootNode, STROOM_TEMP_JSON_POINTER);

        // A vanilla PathConfig with the hard coded defaults
        StroomPathConfig pathConfig = new StroomPathConfig();

        final String homeSource = Objects.equals(pathConfig.getHome(), optHome.orElse(null))
                ? SOURCE_DEFAULTS
                : SOURCE_YAML;
        final String tempSource = Objects.equals(pathConfig.getTemp(), optTemp.orElse(null))
                ? SOURCE_DEFAULTS
                : SOURCE_YAML;

        // Set the values from the YAML if we have them
        pathConfig = optHome.map(pathConfig::withHome)
                .orElse(pathConfig);
        pathConfig = optTemp.map(pathConfig::withTemp)
                .orElse(pathConfig);

        final HomeDirProvider homeDirProvider = new HomeDirProviderImpl(pathConfig);
        final TempDirProvider tempDirProvider = new TempDirProviderImpl(pathConfig, homeDirProvider);
        final PathCreator pathCreator = new SimplePathCreator(homeDirProvider, tempDirProvider);

        log("Using stroom home [{}] from {} for Drop Wizard config path substitutions",
                homeDirProvider.get().toAbsolutePath(),
                homeSource);
        log("Using stroom temp [{}] from {} for Drop Wizard config path substitutions",
                tempDirProvider.get().toAbsolutePath(),
                tempSource);
        return pathCreator;
    }
Merge our compile time defaults with the de-serialised config so we have a full tree
stroom-config/stroom-config-app/src/main/java/stroom/config/app/StroomConfigurationSourceProvider.java