private void assertAttributes(
      Map<String, Map<String, String>> mergedAttributes, Map<String, String> specifiedAttributes) {
    assertEquals(1, mergedAttributes.size()); // only supports
    Map<String, String> supportsAttributes =
        mergedAttributes.get(ConfigurationInfo.Supports.KEYWORD);
    assertEquals(ConfigurationInfo.Supports.values().length, supportsAttributes.size());
    for (Map.Entry<String, String> attribute : supportsAttributes.entrySet()) {
      String attributeName = attribute.getKey();
      String attributeValue = attribute.getValue();

      // need to call toUpper() because propertyName is name().toLowerCase()
      ConfigurationInfo.Supports s =
          ConfigurationInfo.Supports.valueOf(attributeName.toUpperCase());
      String specifiedVal = specifiedAttributes.get(s.getXmlAttributeName());
      if (specifiedVal != null) {
        assertEquals(specifiedVal, attributeValue);
      } else {
        assertEquals(s.getDefaultValue(), attributeValue);
      }
    }
  }
  @Test
  public void testResolve_Configuration__attributes() throws Exception {
    ServiceInfo info = new ServiceInfo();
    ServiceInfo parentInfo = new ServiceInfo();

    // child configurations
    // FOO
    Collection<PropertyInfo> childFooProperties = new ArrayList<PropertyInfo>();
    PropertyInfo childProp1 = new PropertyInfo();
    childProp1.setName("childName1");
    childProp1.setValue("childVal1");
    childFooProperties.add(childProp1);

    // add attributes for parent FOO
    Map<String, String> childFooAttributes = new HashMap<String, String>();
    // override parents value
    childFooAttributes.put(
        ConfigurationInfo.Supports.ADDING_FORBIDDEN.getXmlAttributeName(), "false");

    // create child config modules
    ConfigurationModule childConfigModule1 =
        createConfigurationModule("FOO", childFooProperties, childFooAttributes);
    Collection<ConfigurationModule> childModules = new ArrayList<ConfigurationModule>();
    childModules.add(childConfigModule1);

    // parent configurations
    // FOO
    Collection<PropertyInfo> parentFooProperties = new ArrayList<PropertyInfo>();
    PropertyInfo parentProp1 = new PropertyInfo();
    parentProp1.setName("parentName1");
    parentProp1.setValue("parentVal1");
    parentFooProperties.add(parentProp1);

    // add attributes for parent FOO
    Map<String, String> parentFooAttributes = new HashMap<String, String>();
    // child will inherit
    parentFooAttributes.put(ConfigurationInfo.Supports.FINAL.getXmlAttributeName(), "true");
    // child will override
    parentFooAttributes.put(
        ConfigurationInfo.Supports.ADDING_FORBIDDEN.getXmlAttributeName(), "true");

    // BAR
    Collection<PropertyInfo> parentBarProperties = new ArrayList<PropertyInfo>();
    PropertyInfo parentProp2 = new PropertyInfo();
    parentProp2.setName("parentName2");
    parentProp2.setValue("parentVal2");
    parentBarProperties.add(parentProp2);

    // create parent config modules
    ConfigurationModule parentConfigModule1 =
        createConfigurationModule("FOO", parentFooProperties, parentFooAttributes);
    ConfigurationModule parentConfigModule2 = createConfigurationModule("BAR", parentBarProperties);
    Collection<ConfigurationModule> parentModules = new ArrayList<ConfigurationModule>();
    parentModules.add(parentConfigModule1);
    parentModules.add(parentConfigModule2);

    // create service modules
    ServiceModule child = createServiceModule(info, childModules);
    ServiceModule parent = createServiceModule(parentInfo, parentModules);

    // resolve child with parent
    resolveService(child, parent);

    // assertions
    Map<String, Map<String, Map<String, String>>> childTypeAttributes =
        child.getModuleInfo().getConfigTypeAttributes();
    Map<String, Map<String, Map<String, String>>> parentTypeAttributes =
        parent.getModuleInfo().getConfigTypeAttributes();
    assertTrue(childTypeAttributes.containsKey("FOO"));
    Map<String, Map<String, String>> mergedChildFooAttributes = childTypeAttributes.get("FOO");
    assertTrue(mergedChildFooAttributes.containsKey(ConfigurationInfo.Supports.KEYWORD));
    // inherited value
    assertEquals(
        "true",
        mergedChildFooAttributes
            .get(ConfigurationInfo.Supports.KEYWORD)
            .get(ConfigurationInfo.Supports.valueOf("FINAL").getPropertyName()));
    // overridden value
    assertEquals(
        "false",
        mergedChildFooAttributes
            .get(ConfigurationInfo.Supports.KEYWORD)
            .get(ConfigurationInfo.Supports.valueOf("ADDING_FORBIDDEN").getPropertyName()));

    assertEquals(2, childTypeAttributes.size());

    assertEquals(2, parentTypeAttributes.size());
    assertAttributes(parentTypeAttributes.get("FOO"), parentFooAttributes);
    assertAttributes(parentTypeAttributes.get("BAR"), Collections.<String, String>emptyMap());
  }