@Override
  public AppSettings load() {
    Properties p = loadPropertiesFile(homeDir);
    Set<String> keysOverridableFromEnv = stream(ProcessProperties.Property.values()).map(ProcessProperties.Property::getKey)
      .collect(Collectors.toSet());
    keysOverridableFromEnv.addAll(p.stringPropertyNames());

    // 1st pass to load static properties
    Props staticProps = reloadProperties(keysOverridableFromEnv, p);
    keysOverridableFromEnv.addAll(getDynamicPropertiesKeys(staticProps));

    // 2nd pass to load dynamic properties like `ldap.*.url` or `ldap.*.baseDn` which keys depend on values of static
    // properties loaded in 1st step
    Props props = reloadProperties(keysOverridableFromEnv, p);

    new ProcessProperties(serviceLoaderWrapper).completeDefaults(props);
    stream(consumers).forEach(c -> c.accept(props));
    return new AppSettingsImpl(props);
  }
@Test
  public void command_line_arguments_take_precedence_over_properties_files() throws IOException {
    File homeDir = temp.newFolder();
    File propsFile = new File(homeDir, "conf/sonar.properties");
    FileUtils.write(propsFile, "sonar.foo=file", UTF_8);

    AppSettingsLoaderImpl underTest = new AppSettingsLoaderImpl(system, new String[] {"-Dsonar.foo=cli"}, homeDir, serviceLoaderWrapper);
    AppSettings settings = underTest.load();

    assertThat(settings.getProps().rawProperties()).contains(entry("sonar.foo", "cli"));
  }