bool HStateVariablesSetupData::insert(const HStateVariableInfo& setupData)
{
    if (m_setupData.contains(setupData.name()))
    {
        return false;
    }

    m_setupData.insert(setupData.name(), setupData);
    return true;
}
/*******************************************************************************
 * HServerStateVariable
 *******************************************************************************/
HServerStateVariable::HServerStateVariable(
    const HStateVariableInfo& info, HServerService* parent) :
        QObject(reinterpret_cast<QObject*>(parent)),
            h_ptr(new HStateVariablePrivate())
{
    Q_ASSERT_X(parent, H_AT, "Parent service must be defined.");
    Q_ASSERT_X(info.isValid(), H_AT, "Info object must be valid.");

    h_ptr->m_info = info;
    setValue(info.defaultValue());
}
bool HStateVariablesSetupData::setInclusionRequirement(
    const QString& name, HInclusionRequirement incReq)
{
    if (m_setupData.contains(name))
    {
        HStateVariableInfo setupInfo = m_setupData.value(name);
        setupInfo.setInclusionRequirement(incReq);
        m_setupData.insert(name, setupInfo);
        return true;
    }

    return false;
}
quint32 qHash(const HStateVariableInfo& key)
{
    QByteArray data = key.name().toLocal8Bit();
    return hash(data.constData(), data.size());
}
bool HServerModelCreator::parseStateVariables(
    HServerService* service, QDomElement stateVariableElement)
{
    HStateVariablesSetupData stateVariablesSetup =
        getStateVariablesSetupData(service);

    while(!stateVariableElement.isNull())
    {
        HStateVariableInfo svInfo;
        if (!m_docParser.parseStateVariable(stateVariableElement, &svInfo))
        {
            m_lastError = convert(m_docParser.lastError());
            m_lastErrorDescription = m_docParser.lastErrorDescription();
            return false;
        }

        QString name = svInfo.name();
        HStateVariableInfo setupData = stateVariablesSetup.get(name);
        if (!setupData.isValid() &&
            stateVariablesSetup.defaultInclusionPolicy() ==
            HStateVariablesSetupData::Deny)
        {
            m_lastError = InvalidServiceDescription;
            m_lastErrorDescription = QString(
                "Implementation of service [%1] does not support state variable"
                "[%2]").arg(service->info().serviceId().toString(), name);

            return false;
        }

        HDeviceValidator validator;
        if (!validator.validate(stateVariablesSetup.get(name), svInfo))
        {
            m_lastError = InvalidServiceDescription;
            m_lastErrorDescription =
                QString("Service [%1] validation error: %2").arg(
                    service->info().serviceId().toString(),
                    validator.lastErrorDescription());

            return false;
        }

        HDefaultServerStateVariable* sv =
            new HDefaultServerStateVariable(svInfo, service);

        service->h_ptr->addStateVariable(sv);

        bool ok = QObject::connect(
            sv,
            SIGNAL(valueChanged(
                Herqq::Upnp::HServerStateVariable*,
                const Herqq::Upnp::HStateVariableEvent&)),
            service,
            SLOT(notifyListeners()));

        Q_ASSERT(ok); Q_UNUSED(ok)

        stateVariableElement =
            stateVariableElement.nextSiblingElement("stateVariable");

        stateVariablesSetup.remove(name);
    }

    if (!stateVariablesSetup.isEmpty())
    {
        foreach(const QString& name, stateVariablesSetup.names())
        {
            HStateVariableInfo svSetup = stateVariablesSetup.get(name);
            if (svSetup.inclusionRequirement() == InclusionMandatory &&
                svSetup.version() <= service->info().serviceType().version())
            {
                m_lastError = InvalidServiceDescription;
                m_lastErrorDescription = QString(
                    "Service description is missing a mandatory state variable "
                    "[%1]").arg(name);

                return false;
            }
        }
    }