@Test
public void testReplaceVariables() throws AmbariException {

  Map<String, Map<String, String>> configurations = new HashMap<String, Map<String, String>>() {
    {
      put("", new HashMap<String, String>() {{
        put("global_variable", "Hello World");
        put("variable-name", "dash");
        put("variable_name", "underscore");
        put("variable.name", "dot");
      }});
      put("config_type", new HashMap<String, String>() {{
        put("variable-name", "config_type_dash");
        put("variable_name", "config_type_underscore");
        put("variable.name", "config_type_dot");
      }});
      put("config.type", new HashMap<String, String>() {{
        put("variable-name", "config.type_dash");
        put("variable_name", "config.type_underscore");
        put("variable.name", "config.type_dot");
      }});
      put("config-type", new HashMap<String, String>() {{
        put("variable.name", "Replacement1");
        put("variable.name1", "${config-type2/variable.name}");
        put("variable.name2", "");
      }});
      put("config-type2", new HashMap<String, String>() {{
        put("variable.name", "Replacement2");
        put("self_reference", "${config-type2/self_reference}");  // This essentially references itself.
        put("${config-type/variable.name}_reference", "Replacement in the key");
      }});
    }
  };
  Assert.assertEquals("concrete",
      helper.replaceVariables("concrete", configurations));
  Assert.assertEquals("Hello World",
      helper.replaceVariables("${global_variable}", configurations));
  Assert.assertEquals("Replacement1",
      helper.replaceVariables("${config-type/variable.name}", configurations));
  Assert.assertEquals("Replacement1|Replacement2",
      helper.replaceVariables("${config-type/variable.name}|${config-type2/variable.name}", configurations));
  Assert.assertEquals("Replacement1|Replacement2|${config-type3/variable.name}",
      helper.replaceVariables("${config-type/variable.name}|${config-type2/variable.name}|${config-type3/variable.name}", configurations));
  Assert.assertEquals("Replacement2|Replacement2",
      helper.replaceVariables("${config-type/variable.name1}|${config-type2/variable.name}", configurations));
  Assert.assertEquals("Replacement1_reference",
      helper.replaceVariables("${config-type/variable.name}_reference", configurations));
  Assert.assertEquals("dash",
      helper.replaceVariables("${variable-name}", configurations));
  Assert.assertEquals("underscore",
      helper.replaceVariables("${variable_name}", configurations));
  Assert.assertEquals("config_type_dot",
      helper.replaceVariables("${config_type/variable.name}", configurations));
  Assert.assertEquals("config_type_dash",
      helper.replaceVariables("${config_type/variable-name}", configurations));
  Assert.assertEquals("config_type_underscore",
      helper.replaceVariables("${config_type/variable_name}", configurations));
  Assert.assertEquals("config.type_dot",
      helper.replaceVariables("${config.type/variable.name}", configurations));
  Assert.assertEquals("config.type_dash",
      helper.replaceVariables("${config.type/variable-name}", configurations));
  Assert.assertEquals("config.type_underscore",
      helper.replaceVariables("${config.type/variable_name}", configurations));
  Assert.assertEquals("dot",
      helper.replaceVariables("${variable.name}", configurations));
  // Replacement yields an empty string
  Assert.assertEquals("",
      helper.replaceVariables("${config-type/variable.name2}", configurations));
  // This might cause an infinite loop... we assume protection is in place...
  try {
    Assert.assertEquals("${config-type2/self_reference}",
        helper.replaceVariables("${config-type2/self_reference}", configurations));
    Assert.fail(String.format("%s expected to be thrown", AmbariException.class.getName()));
  } catch (AmbariException e) {
    // This is expected...
  }
}