/**
   * Resolve locale-specific inheritance. First, resolve parent's inheritance, then set template to
   * the parent's template. Also copy attributes setted in parent, and not set in child If instance
   * doesn't extend anything, do nothing.
   *
   * @param definition The definition to resolve
   * @param locale The locale to use.
   * @param alreadyResolvedDefinitions The set of the definitions that have been already resolved.
   * @throws NoSuchDefinitionException If an inheritance can not be solved.
   */
  protected void resolveInheritance(
      Definition definition, Locale locale, Set<String> alreadyResolvedDefinitions)
      throws NoSuchDefinitionException {
    // Already done, or not needed ?
    if (!definition.isExtending() || alreadyResolvedDefinitions.contains(definition.getName())) {
      return;
    }

    if (log.isDebugEnabled()) {
      log.debug(
          "Resolve definition for child name='"
              + definition.getName()
              + "' extends='"
              + definition.getExtends()
              + "'.");
    }

    // Set as visited to avoid endless recurisvity.
    alreadyResolvedDefinitions.add(definition.getName());

    // Resolve parent before itself.
    Definition parent = getDefinition(definition.getExtends(), locale);
    if (parent == null) { // error
      String msg =
          "Error while resolving definition inheritance: child '"
              + definition.getName()
              + "' can't find its ancestor '"
              + definition.getExtends()
              + "'. Please check your description file.";
      log.error(msg);
      // to do : find better exception
      throw new NoSuchDefinitionException(msg);
    }

    resolveInheritance(parent, locale, alreadyResolvedDefinitions);

    overload(parent, definition);
  }
 // FIXME This is the same as DefinitionManager.overload.
 protected void overload(Definition parent, Definition child) {
   // Iterate on each parent's attribute and add it if not defined in child.
   for (Map.Entry<String, Attribute> entry : parent.getAttributes().entrySet()) {
     if (!child.hasAttributeValue(entry.getKey())) {
       child.putAttribute(entry.getKey(), new Attribute(entry.getValue()));
     }
   }
   // Set template and role if not setted
   if (child.getTemplate() == null) {
     child.setTemplate(parent.getTemplate());
   }
   if (child.getRole() == null) {
     child.setRole(parent.getRole());
   }
   if (child.getPreparer() == null) {
     child.setPreparer(parent.getPreparer());
   }
 }