// Serialize one configuration for one configurable element
bool CDomainConfiguration::importOneConfigurableElementSettings(
    CAreaConfiguration *areaConfiguration, CXmlElement &xmlConfigurableElementSettingsElement,
    CXmlDomainImportContext &context)
{
    const CConfigurableElement *destination = areaConfiguration->getConfigurableElement();

    // Check structure
    if (xmlConfigurableElementSettingsElement.getNbChildElements() != 1) {

        // Structure error
        context.setError("Struture error encountered while parsing settings of " +
                         destination->getKind() + " " + destination->getName() +
                         " in Configuration " + getPath());

        return false;
    }

    // Element content
    CXmlElement xmlConfigurableElementSettingsElementContent;
    // Check name and kind
    if (!xmlConfigurableElementSettingsElement.getChildElement(
            destination->getXmlElementName(), destination->getName(),
            xmlConfigurableElementSettingsElementContent)) {

        // "Component" tag has been renamed to "ParameterBlock", but retro-compatibility shall
        // be ensured.
        //
        // So checking if this case occurs, i.e. element name is "ParameterBlock"
        // but found xml setting name is "Component".
        bool compatibilityCase =
            (destination->getXmlElementName() == "ParameterBlock") &&
            xmlConfigurableElementSettingsElement.getChildElement(
                "Component", destination->getName(), xmlConfigurableElementSettingsElementContent);

        // Error if the compatibility case does not occur.
        if (!compatibilityCase) {
            context.setError("Couldn't find settings for " + destination->getXmlElementName() +
                             " " + destination->getName() + " for Configuration " + getPath());

            return false;
        }
    }

    // Create configuration access context
    string error;
    CConfigurationAccessContext configurationAccessContext(error, false);

    // Have domain configuration parse settings for configurable element
    bool success = areaConfiguration->serializeXmlSettings(
        xmlConfigurableElementSettingsElementContent, configurationAccessContext);

    context.appendToError(error);
    return success;
}
// Parse configurable elements
bool CConfigurableDomain::parseConfigurableElements(const CXmlElement &xmlElement,
                                                    CXmlDomainImportContext &serializingContext)
{
    CSystemClass &systemClass = serializingContext.getSystemClass();

    // Get ConfigurableElements element
    CXmlElement xmlConfigurableElementsElement;
    xmlElement.getChildElement("ConfigurableElements", xmlConfigurableElementsElement);

    // Parse it and associate found configurable elements to it
    CXmlElement::CChildIterator it(xmlConfigurableElementsElement);

    CXmlElement xmlConfigurableElementElement;

    while (it.next(xmlConfigurableElementElement)) {

        // Locate configurable element
        string strConfigurableElementPath;
        xmlConfigurableElementElement.getAttribute("Path", strConfigurableElementPath);

        CPathNavigator pathNavigator(strConfigurableElementPath);
        string strError;

        // Is there an element and does it match system class name?
        if (!pathNavigator.navigateThrough(systemClass.getName(), strError)) {

            serializingContext.setError(
                "Could not find configurable element of path " + strConfigurableElementPath +
                " from ConfigurableDomain description " + getName() + " (" + strError + ")");

            return false;
        }
        // Browse system class for configurable element
        CConfigurableElement *pConfigurableElement =
            static_cast<CConfigurableElement *>(systemClass.findDescendant(pathNavigator));

        if (!pConfigurableElement) {

            serializingContext.setError("Could not find configurable element of path " +
                                        strConfigurableElementPath +
                                        " from ConfigurableDomain description " + getName());

            return false;
        }
        // Add found element to domain
        core::Results infos;
        if (!addConfigurableElement(pConfigurableElement, NULL, infos)) {

            strError = utility::asString(infos);
            serializingContext.setError(strError);

            return false;
        }
    }

    return true;
}
// From IXmlSink
bool CSubsystem::fromXml(const CXmlElement& xmlElement, CXmlSerializingContext& serializingContext)
{
    // Context
    CXmlParameterSerializingContext& parameterBuildContext = static_cast<CXmlParameterSerializingContext&>(serializingContext);

    // Install temporary component library for further component creation
    parameterBuildContext.setComponentLibrary(_pComponentLibrary);

    CXmlElement childElement;

    // XML populate ComponentLibrary
    xmlElement.getChildElement("ComponentLibrary", childElement);

    if (!_pComponentLibrary->fromXml(childElement, serializingContext)) {

        return false;
    }

    // XML populate InstanceDefintion
    xmlElement.getChildElement("InstanceDefintion", childElement);
    if (!_pInstanceDefinition->fromXml(childElement, serializingContext)) {

        return false;
    }

    // Create components
    _pInstanceDefinition->createInstances(this);

    // Execute mapping to create subsystem mapping entities
    string strError;
    if (!mapSubsystemElements(strError)) {

        serializingContext.setError(strError);

        return false;
    }

    // Endianness
    _bBigEndian = xmlElement.getAttributeBoolean("Endianness", "Big");

    return true;
}
// XML parsing
bool CConfigurableDomain::parseDomainConfigurations(const CXmlElement &xmlElement,
                                                    CXmlDomainImportContext &serializingContext)
{
    // We're supposedly clean
    assert(_configurableElementList.empty());

    // Get Configurations element
    CXmlElement xmlConfigurationsElement;

    xmlElement.getChildElement("Configurations", xmlConfigurationsElement);

    // Parse it and create domain configuration objects
    return base::fromXml(xmlConfigurationsElement, serializingContext);
}
// Parse settings
bool CConfigurableDomain::parseSettings(const CXmlElement &xmlElement,
                                        CXmlDomainImportContext &serializingContext)
{
    // Check we actually need to parse configuration settings
    if (!serializingContext.withSettings()) {

        // No parsing required
        return true;
    }

    // Get Settings element
    CXmlElement xmlSettingsElement;
    if (!xmlElement.getChildElement("Settings", xmlSettingsElement)) {

        // No settings, bail out successfully
        return true;
    }

    // Parse configuration settings
    CXmlElement::CChildIterator it(xmlSettingsElement);

    CXmlElement xmlConfigurationSettingsElement;

    while (it.next(xmlConfigurationSettingsElement)) {
        // Get domain configuration
        CDomainConfiguration *pDomainConfiguration = static_cast<CDomainConfiguration *>(
            findChild(xmlConfigurationSettingsElement.getNameAttribute()));

        if (!pDomainConfiguration) {

            serializingContext.setError("Could not find domain configuration referred to by"
                                        " configurable domain \"" +
                                        getName() + "\".");

            return false;
        }
        // Have domain configuration parse settings for all configurable elements
        if (!pDomainConfiguration->parseSettings(xmlConfigurationSettingsElement,
                                                 serializingContext)) {

            return false;
        }
    }

    return true;
}