protected JsonNode loadConfiguration(Map<String, String> properties, Map<String, String> vars) {

    // hopefully sharing the mapper between parsers is safe... Does it
    // change the state during parse?
    ObjectMapper textToJsonMapper = jacksonService.newObjectMapper();
    Map<ParserType, Function<InputStream, Optional<JsonNode>>> parsers =
        new EnumMap<>(ParserType.class);
    parsers.put(ParserType.YAML, new JsonNodeYamlParser(textToJsonMapper));
    parsers.put(ParserType.JSON, new JsonNodeJsonParser(textToJsonMapper));

    Function<URL, Optional<JsonNode>> parser = new MultiFormatJsonNodeParser(parsers, bootLogger);

    BinaryOperator<JsonNode> singleConfigMerger = new InPlaceLeftHandMerger(bootLogger);
    Function<JsonNode, JsonNode> overrider = new InPlaceMapOverrider(properties, true, '.');

    if (!vars.isEmpty()) {
      overrider = overrider.andThen(new InPlaceMapOverrider(vars, false, '_'));
    }

    return JsonNodeConfigurationBuilder.builder()
        .parser(parser)
        .merger(singleConfigMerger)
        .resources(configurationSource)
        .overrider(overrider)
        .build();
  }
  @Override
  public ConfigurationFactory get() {

    Map<String, String> vars = environment.frameworkVariables();
    Map<String, String> properties = environment.frameworkProperties();

    JsonNode rootNode = loadConfiguration(properties, vars);

    ObjectMapper jsonToObjectMapper = jacksonService.newObjectMapper();
    if (!vars.isEmpty()) {

      // switching to slower CI strategy for mapping properties...
      jsonToObjectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
    }

    return new JsonNodeConfigurationFactory(rootNode, jsonToObjectMapper);
  }