/*!
    Constructs a QNetworkConfigurationManager with the given \a parent.
*/
QNetworkConfigurationManager::QNetworkConfigurationManager( QObject* parent )
    : QObject(parent)
{
    QNetworkConfigurationManagerPrivate* priv = connManager();
    connect(priv, SIGNAL(configurationAdded(QNetworkConfiguration)),
            this, SIGNAL(configurationAdded(QNetworkConfiguration)));
    connect(priv, SIGNAL(configurationRemoved(QNetworkConfiguration)),
            this, SIGNAL(configurationRemoved(QNetworkConfiguration)));
    connect(priv, SIGNAL(configurationUpdateComplete()),
            this, SIGNAL(updateCompleted()));
    connect(priv, SIGNAL(onlineStateChanged(bool)),
            this, SIGNAL(onlineStateChanged(bool)));
    connect(priv, SIGNAL(configurationChanged(QNetworkConfiguration)),
            this, SIGNAL(configurationChanged(QNetworkConfiguration)));
}
void QNetworkConfigurationManagerPrivate::updateConfigurations()
{
    if (firstUpdate) {
        updateState = NotUpdating;
        onlineConfigurations = 0;

#if defined (Q_OS_DARWIN)
        coreWifi = QCoreWlanEngine::instance();
        if (coreWifi) {
            connect(coreWifi, SIGNAL(configurationsChanged()),
                    this, SLOT(updateConfigurations()));
        }
#else
#if defined(BACKEND_NM)
        nmWifi = QNmWifiEngine::instance();
        if (nmWifi) {
            connect(nmWifi, SIGNAL(configurationsChanged()),
                    this, SLOT(updateConfigurations()));
        } else {
#endif
            generic = QGenericEngine::instance();
            if (generic) {
                connect(generic, SIGNAL(configurationsChanged()),
                        this, SLOT(updateConfigurations()));
            }
#if defined(BACKEND_NM)
        }
#endif
#endif

#ifdef Q_OS_WIN
            nla = QNlaEngine::instance();
            if (nla) {
                connect(nla, SIGNAL(configurationsChanged()),
                        this, SLOT(updateConfigurations()));
            }
#endif

#ifdef Q_OS_WIN32
            nativeWifi = QNativeWifiEngine::instance();
            if (nativeWifi) {
                connect(nativeWifi, SIGNAL(configurationsChanged()),
                        this, SLOT(updateConfigurations()));

                capFlags |= QNetworkConfigurationManager::CanStartAndStopInterfaces;
            }
#endif
    }

    QNetworkSessionEngine *engine = qobject_cast<QNetworkSessionEngine *>(sender());
    if (updateState & Updating && engine) {
#if defined (Q_OS_DARWIN)
        if (engine == coreWifi)
            updateState &= ~CoreWifiUpdating;
#else
#if defined(BACKEND_NM)
        if (engine == nmWifi)
            updateState &= ~NmUpdating;
        else if (engine == generic)
            updateState &= ~GenericUpdating;
#else
        if (engine == generic)
            updateState &= ~GenericUpdating;
#endif
#endif

#ifdef Q_OS_WIN
        else if (engine == nla)
            updateState &= ~NlaUpdating;
#ifdef Q_OS_WIN32
        else if (engine == nativeWifi)
            updateState &= ~NativeWifiUpdating;
#endif
#endif
    }
    QList<QNetworkSessionEngine *> engines;
    if (firstUpdate) {
#if defined (Q_OS_DARWIN)
        if (coreWifi)
            engines << coreWifi;
#else
#if defined(BACKEND_NM)
        if (nmWifi)
            engines << nmWifi;
        else if (generic)
            engines << generic;
#else
        if (generic)
            engines << generic;
#endif
#endif

#ifdef Q_OS_WIN
        if (nla)
            engines << nla;
#ifdef Q_OS_WIN32
        if (nativeWifi)
            engines << nativeWifi;
#endif
#endif
    } else if (engine) {
        engines << engine;
    }

    while (!engines.isEmpty()) {
        engine = engines.takeFirst();

        bool ok;
        QList<QNetworkConfigurationPrivate *> foundConfigurations = engine->getConfigurations(&ok);

        // Find removed configurations.
        QList<QString> removedIdentifiers = configurationEngine.keys();
        for (int i = 0; i < foundConfigurations.count(); ++i)
            removedIdentifiers.removeOne(foundConfigurations.at(i)->id);

        // Update or add configurations.
        while (!foundConfigurations.isEmpty()) {
            QNetworkConfigurationPrivate *cpPriv = foundConfigurations.takeFirst();

            if (accessPointConfigurations.contains(cpPriv->id))
                configurationChanged(cpPriv);
            else
                configurationAdded(cpPriv, engine);

            delete cpPriv;
        }

        // Remove configurations.
        while (!removedIdentifiers.isEmpty()) {
            const QString id = removedIdentifiers.takeFirst();

            if (configurationEngine.value(id) == engine)
                configurationRemoved(id);
        }
    }

    updateInternetServiceConfiguration();

    if (updateState == Updating) {
        updateState = NotUpdating;
        emit configurationUpdateComplete();
    }

    if (firstUpdate)
        firstUpdate = false;
}