--- src/plugins/bearer/corewlan/qcorewlanengine.mm
+++ src/plugins/bearer/corewlan/qcorewlanengine.mm
@@ -52,29 +52,17 @@
 #include <QtCore/qdebug.h>
 
 #include <QDir>
-#include <CoreWLAN/CoreWLAN.h>
-#include <CoreWLAN/CWInterface.h>
-#include <CoreWLAN/CWNetwork.h>
-#include <CoreWLAN/CWNetwork.h>
-#include <CoreWLAN/CW8021XProfile.h>
-
-#include <Foundation/NSEnumerator.h>
-#include <Foundation/NSKeyValueObserving.h>
-#include <Foundation/NSAutoreleasePool.h>
-#include <Foundation/NSLock.h>
-
-#include <SystemConfiguration/SCNetworkConfiguration.h>
+
+extern "C" { // Otherwise it won't find CWKeychain* symbols at link time
+#import <CoreWLAN/CoreWLAN.h>
+}
+
 #include "private/qcore_mac_p.h"
 
 #include <net/if.h>
 #include <ifaddrs.h>
 
-inline QString qt_NSStringToQString(const NSString *nsstr)
-{ return QCFString::toQString(reinterpret_cast<const CFStringRef>(nsstr)); }
-
-inline NSString *qt_QStringToNSString(const QString &qstr)
-{ return [const_cast<NSString *>(reinterpret_cast<const NSString *>(QCFString::toCFStringRef(qstr))) autorelease]; }
-
+#if __MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
 
 @interface QT_MANGLE_NAMESPACE(QNSListener) : NSObject
 {
@@ -86,6 +74,7 @@ inline NSString *qt_QStringToNSString(const QString &qstr)
 - (void)notificationHandler;//:(NSNotification *)notification;
 - (void)remove;
 - (void)setEngine:(QCoreWlanEngine *)coreEngine;
+- (QCoreWlanEngine *)engine;
 - (void)dealloc;
 
 @property (assign) QCoreWlanEngine* engine;
@@ -93,7 +82,6 @@ inline NSString *qt_QStringToNSString(const QString &qstr)
 @end
 
 @implementation QT_MANGLE_NAMESPACE(QNSListener)
-@synthesize engine;
 
 - (id) init
 {
@@ -101,7 +89,7 @@ inline NSString *qt_QStringToNSString(const QString &qstr)
     NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
     notificationCenter = [NSNotificationCenter defaultCenter];
     currentInterface = [CWInterface interfaceWithName:nil];
-    [notificationCenter addObserver:self selector:@selector(notificationHandler:) name:kCWPowerDidChangeNotification object:nil];
+    [notificationCenter addObserver:self selector:@selector(notificationHandler:) name:CWPowerDidChangeNotification object:nil];
     [locker unlock];
     [autoreleasepool release];
     return self;
@@ -120,6 +108,11 @@ inline NSString *qt_QStringToNSString(const QString &qstr)
     [locker unlock];
 }
 
+-(QCoreWlanEngine *)engine
+{
+    return engine;
+}
+
 -(void)remove
 {
     [locker lock];
@@ -133,7 +126,7 @@ inline NSString *qt_QStringToNSString(const QString &qstr)
 }
 @end
 
-QT_MANGLE_NAMESPACE(QNSListener) *listener = 0;
+static QT_MANGLE_NAMESPACE(QNSListener) *listener = 0;
 
 QT_BEGIN_NAMESPACE
 
@@ -170,36 +163,28 @@ void QScanThread::run()
     NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
     QStringList found;
     mutex.lock();
-    CWInterface *currentInterface = [CWInterface interfaceWithName:qt_QStringToNSString(interfaceName)];
+    CWInterface *currentInterface = [CWInterface interfaceWithName: (NSString *)QCFString::toCFStringRef(interfaceName)];
     mutex.unlock();
 
-    if([currentInterface power]) {
+    if (currentInterface.powerOn) {
         NSError *err = nil;
-        NSDictionary *parametersDict =  [NSDictionary dictionaryWithObjectsAndKeys:
-                                   [NSNumber numberWithBool:YES], kCWScanKeyMerge,
-                                   [NSNumber numberWithInt:kCWScanTypeFast], kCWScanKeyScanType,
-                                   [NSNumber numberWithInteger:100], kCWScanKeyRestTime, nil];
 
-        NSArray* apArray = [currentInterface scanForNetworksWithParameters:parametersDict error:&err];
-        CWNetwork *apNetwork;
+        NSSet* apSet = [currentInterface scanForNetworksWithName:nil error:&err];
 
         if (!err) {
-
-            for(uint row=0; row < [apArray count]; row++ ) {
-                apNetwork = [apArray objectAtIndex:row];
-
-                const QString networkSsid = qt_NSStringToQString([apNetwork ssid]);
+            for (CWNetwork *apNetwork in apSet) {
+                const QString networkSsid = QCFString::toQString(CFStringRef([apNetwork ssid]));
                 const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkSsid));
                 found.append(id);
 
                 QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined;
                 bool known = isKnownSsid(networkSsid);
-                if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) {
-                    if( networkSsid == qt_NSStringToQString( [currentInterface ssid])) {
+                if (currentInterface.serviceActive) {
+                    if( networkSsid == QCFString::toQString(CFStringRef([currentInterface ssid]))) {
                         state = QNetworkConfiguration::Active;
                     }
                 }
-                if(state == QNetworkConfiguration::Undefined) {
+                if (state == QNetworkConfiguration::Undefined) {
                     if(known) {
                         state = QNetworkConfiguration::Discovered;
                     } else {
@@ -207,7 +192,7 @@ void QScanThread::run()
                     }
                 }
                 QNetworkConfiguration::Purpose purpose = QNetworkConfiguration::UnknownPurpose;
-                if([[apNetwork securityMode] intValue] == kCWSecurityModeOpen) {
+                if ([apNetwork supportsSecurity:kCWSecurityNone]) {
                     purpose = QNetworkConfiguration::PublicPurpose;
                 } else {
                     purpose = QNetworkConfiguration::PrivatePurpose;
@@ -237,8 +222,8 @@ void QScanThread::run()
                 interfaceName = ij.value();
             }
 
-            if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) {
-                if( networkSsid == qt_NSStringToQString([currentInterface ssid])) {
+            if (currentInterface.serviceActive) {
+                if( networkSsid == QCFString::toQString(CFStringRef([currentInterface ssid]))) {
                     state = QNetworkConfiguration::Active;
                 }
             }
@@ -300,14 +285,14 @@ void QScanThread::getUserConfigurations()
     NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
     userProfiles.clear();
 
-    NSArray *wifiInterfaces = [CWInterface supportedInterfaces];
-    for(uint row=0; row < [wifiInterfaces count]; row++ ) {
+    NSSet *wifiInterfaces = [CWInterface interfaceNames];
+    for (NSString *ifName in wifiInterfaces) {
 
-        CWInterface *wifiInterface = [CWInterface interfaceWithName: [wifiInterfaces objectAtIndex:row]];
-        if ( ![wifiInterface power] )
+        CWInterface *wifiInterface = [CWInterface interfaceWithName: ifName];
+        if (!wifiInterface.powerOn)
             continue;
 
-        NSString *nsInterfaceName = [wifiInterface name];
+        NSString *nsInterfaceName = wifiInterface.ssid;
 // add user configured system networks
         SCDynamicStoreRef dynRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault, (CFStringRef)@"Qt corewlan", nil, nil);
         NSDictionary * airportPlist = (NSDictionary *)SCDynamicStoreCopyValue(dynRef, (CFStringRef)[NSString stringWithFormat:@"Setup:/Network/Interface/%@/AirPort", nsInterfaceName]);
@@ -316,11 +301,11 @@ void QScanThread::getUserConfigurations()
             NSDictionary *prefNetDict = [airportPlist objectForKey:@"PreferredNetworks"];
 
             NSArray *thisSsidarray = [prefNetDict valueForKey:@"SSID_STR"];
-            for(NSString *ssidkey in thisSsidarray) {
-                QString thisSsid = qt_NSStringToQString(ssidkey);
+            for (NSString *ssidkey in thisSsidarray) {
+                QString thisSsid = QCFString::toQString(CFStringRef(ssidkey));
                 if(!userProfiles.contains(thisSsid)) {
                     QMap <QString,QString> map;
-                    map.insert(thisSsid, qt_NSStringToQString(nsInterfaceName));
+                    map.insert(thisSsid, QCFString::toQString(CFStringRef(nsInterfaceName)));
                     userProfiles.insert(thisSsid, map);
                 }
             }
@@ -329,7 +314,7 @@ void QScanThread::getUserConfigurations()
 
         // 802.1X user profiles
         QString userProfilePath = QDir::homePath() + "/Library/Preferences/com.apple.eap.profiles.plist";
-        NSDictionary* eapDict = [[[NSDictionary alloc] initWithContentsOfFile:qt_QStringToNSString(userProfilePath)] autorelease];
+        NSDictionary* eapDict = [[[NSDictionary alloc] initWithContentsOfFile: (NSString *)QCFString::toCFStringRef(userProfilePath)] autorelease];
         if(eapDict != nil) {
             NSString *profileStr= @"Profiles";
             NSString *nameStr = @"UserDefinedName";
@@ -348,15 +333,15 @@ void QScanThread::getUserConfigurations()
                         QString ssid;
                         for(int i = 0; i < dictSize; i++) {
                             if([nameStr isEqualToString:keys[i]]) {
-                                networkName = qt_NSStringToQString(objects[i]);
+                                networkName = QCFString::toQString(CFStringRef(objects[i]));
                             }
                             if([networkSsidStr isEqualToString:keys[i]]) {
-                                ssid = qt_NSStringToQString(objects[i]);
+                                ssid = QCFString::toQString(CFStringRef(objects[i]));
                             }
                             if(!userProfiles.contains(networkName)
                                 && !ssid.isEmpty()) {
                                 QMap<QString,QString> map;
-                                map.insert(ssid, qt_NSStringToQString(nsInterfaceName));
+                                map.insert(ssid, QCFString::toQString(CFStringRef(nsInterfaceName)));
                                 userProfiles.insert(networkName, map);
                             }
                         }
@@ -444,7 +429,7 @@ void QCoreWlanEngine::initialize()
     QMutexLocker locker(&mutex);
     NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
 
-    if([[CWInterface supportedInterfaces] count] > 0 && !listener) {
+    if ([[CWInterface interfaceNames] count] > 0 && !listener) {
         listener = [[QT_MANGLE_NAMESPACE(QNSListener) alloc] init];
         listener.engine = this;
         hasWifi = true;
@@ -479,141 +464,68 @@ void QCoreWlanEngine::connectToId(const QString &id)
     QString interfaceString = getInterfaceFromId(id);
 
     CWInterface *wifiInterface =
-        [CWInterface interfaceWithName: qt_QStringToNSString(interfaceString)];
+        [CWInterface interfaceWithName: (NSString *)QCFString::toCFStringRef(interfaceString)];
 
-    if ([wifiInterface power]) {
+    if (wifiInterface.powerOn) {
         NSError *err = nil;
-        NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0];
-
         QString wantedSsid;
-
         QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
 
         const QString idHash = QString::number(qHash(QLatin1String("corewlan:") + ptr->name));
         const QString idHash2 = QString::number(qHash(QLatin1String("corewlan:") + scanThread->getNetworkNameFromSsid(ptr->name)));
 
-        bool using8021X = false;
-        if (idHash2 != id) {
-            NSArray *array = [CW8021XProfile allUser8021XProfiles];
-
-            for (NSUInteger i = 0; i < [array count]; ++i) {
-                const QString networkNameHashCheck = QString::number(qHash(QLatin1String("corewlan:") + qt_NSStringToQString([[array objectAtIndex:i] userDefinedName])));
-
-                const QString ssidHash = QString::number(qHash(QLatin1String("corewlan:") + qt_NSStringToQString([[array objectAtIndex:i] ssid])));
-
-                if (id == networkNameHashCheck || id == ssidHash) {
-                    const QString thisName = scanThread->getSsidFromNetworkName(id);
-                    if (thisName.isEmpty())
-                        wantedSsid = id;
-                    else
-                        wantedSsid = thisName;
-
-                    [params setValue: [array objectAtIndex:i] forKey:kCWAssocKey8021XProfile];
-                    using8021X = true;
-                    break;
-                }
+        QString wantedNetwork;
+        QMapIterator<QString, QMap<QString, QString> > i(scanThread->userProfiles);
+        while (i.hasNext()) {
+            i.next();
+            wantedNetwork = i.key();
+            const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") + wantedNetwork));
+            if (id == networkNameHash) {
+                wantedSsid = scanThread->getSsidFromNetworkName(wantedNetwork);
+                break;
             }
         }
 
-        if (!using8021X) {
-            QString wantedNetwork;
-            QMapIterator<QString, QMap<QString,QString> > i(scanThread->userProfiles);
-            while (i.hasNext()) {
-                i.next();
-                wantedNetwork = i.key();
-                const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") + wantedNetwork));
-                if (id == networkNameHash) {
-                    wantedSsid =  scanThread->getSsidFromNetworkName(wantedNetwork);
-                    break;
-                }
-            }
-        }
-        NSDictionary *scanParameters = [NSDictionary dictionaryWithObjectsAndKeys:
-                                        [NSNumber numberWithBool:YES], kCWScanKeyMerge,
-                                        [NSNumber numberWithInt:kCWScanTypeFast], kCWScanKeyScanType,
-                                        [NSNumber numberWithInteger:100], kCWScanKeyRestTime,
-                                        qt_QStringToNSString(wantedSsid), kCWScanKeySSID,
-                                        nil];
-
-        NSArray *scanArray = [wifiInterface scanForNetworksWithParameters:scanParameters error:&err];
+        NSSet *scanSet = [wifiInterface scanForNetworksWithName:(NSString *)QCFString::toCFStringRef(wantedSsid) error:&err];
 
         if(!err) {
-            for(uint row=0; row < [scanArray count]; row++ ) {
-                CWNetwork *apNetwork = [scanArray objectAtIndex:row];
-
-                if(wantedSsid == qt_NSStringToQString([apNetwork ssid])) {
-
-                    if(!using8021X) {
-                        SecKeychainAttribute attributes[3];
-
-                        NSString *account = [apNetwork ssid];
-                        NSString *keyKind = @"AirPort network password";
-                        NSString *keyName = account;
-
-                        attributes[0].tag = kSecAccountItemAttr;
-                        attributes[0].data = (void *)[account UTF8String];
-                        attributes[0].length = [account length];
-
-                        attributes[1].tag = kSecDescriptionItemAttr;
-                        attributes[1].data = (void *)[keyKind UTF8String];
-                        attributes[1].length = [keyKind length];
-
-                        attributes[2].tag = kSecLabelItemAttr;
-                        attributes[2].data = (void *)[keyName UTF8String];
-                        attributes[2].length = [keyName length];
-
-                        SecKeychainAttributeList attributeList = {3,attributes};
-
-                        SecKeychainSearchRef searchRef;
-                        SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, &attributeList, &searchRef);
-
-                        NSString *password = @"";
-                        SecKeychainItemRef searchItem;
-
-                        if (SecKeychainSearchCopyNext(searchRef, &searchItem) == noErr) {
-                            UInt32 realPasswordLength;
-                            SecKeychainAttribute attributesW[8];
-                            attributesW[0].tag = kSecAccountItemAttr;
-                            SecKeychainAttributeList listW = {1,attributesW};
-                            char *realPassword;
-                            OSStatus status = SecKeychainItemCopyContent(searchItem, NULL, &listW, &realPasswordLength,(void **)&realPassword);
-
-                            if (status == noErr) {
-                                if (realPassword != NULL) {
-
-                                    QByteArray pBuf;
-                                    pBuf.resize(realPasswordLength);
-                                    pBuf.prepend(realPassword);
-                                    pBuf.insert(realPasswordLength,'\0');
-
-                                    password = [NSString stringWithUTF8String:pBuf];
-                                }
-                                SecKeychainItemFreeContent(&listW, realPassword);
-                            }
-
-                            CFRelease(searchItem);
-                        } else {
-                            qDebug() << "SecKeychainSearchCopyNext error";
-                        }
-                        [params setValue: password forKey: kCWAssocKeyPassphrase];
-                    } // end using8021X
-
-
-                    bool result = [wifiInterface associateToNetwork: apNetwork parameters:[NSDictionary dictionaryWithDictionary:params] error:&err];
+            for (CWNetwork *apNetwork in scanSet) {
+                CFDataRef ssidData = (CFDataRef)[apNetwork ssidData];
+                bool result = false;
+
+                SecIdentityRef identity = 0;
+                // Check first whether we require IEEE 802.1X authentication for the wanted SSID
+                if (CWKeychainCopyEAPIdentity(ssidData, &identity) == errSecSuccess) {
+                    CFStringRef username = 0;
+                    CFStringRef password = 0;
+                    if (CWKeychainCopyEAPUsernameAndPassword(ssidData, &username, &password) == errSecSuccess) {
+                        result = [wifiInterface associateToEnterpriseNetwork:apNetwork
+                                    identity:identity username:(NSString *)username password:(NSString *)password
+                                    error:&err];
+                        CFRelease(username);
+                        CFRelease(password);
+                    }
+                    CFRelease(identity);
+                } else {
+                    CFStringRef password = 0;
+                    if (CWKeychainCopyPassword(ssidData, &password) == errSecSuccess) {
+                        result = [wifiInterface associateToNetwork:apNetwork password:(NSString *)password error:&err];
+                        CFRelease(password);
+                    }
+                }
 
-                    if(!err) {
-                        if(!result) {
-                            emit connectionError(id, ConnectError);
-                        } else {
-                            return;
-                        }
+                if (!err) {
+                    if (!result) {
+                        emit connectionError(id, ConnectError);
                     } else {
-                        qDebug() <<"associate ERROR"<<  qt_NSStringToQString([err localizedDescription ]);
+                        return;
                     }
+                } else {
+                    qDebug() <<"associate ERROR"<<  QCFString::toQString(CFStringRef([err localizedDescription ]));
                 }
             } //end scan network
         } else {
-            qDebug() <<"scan ERROR"<<  qt_NSStringToQString([err localizedDescription ]);
+            qDebug() <<"scan ERROR"<<  QCFString::toQString(CFStringRef([err localizedDescription ]));
         }
         emit connectionError(id, InterfaceLookupError);
     }
@@ -631,10 +543,10 @@ void QCoreWlanEngine::disconnectFromId(const QString &id)
     NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
 
     CWInterface *wifiInterface =
-        [CWInterface interfaceWithName: qt_QStringToNSString(interfaceString)];
+        [CWInterface interfaceWithName: (NSString *)QCFString::toCFStringRef(interfaceString)];
 
     [wifiInterface disassociate];
-    if ([[wifiInterface interfaceState]intValue] != kCWInterfaceStateInactive) {
+    if (wifiInterface.serviceActive) {
         locker.unlock();
         emit connectionError(id, DisconnectionError);
         locker.relock();
@@ -654,9 +566,9 @@ void QCoreWlanEngine::doRequestUpdate()
 
     NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
 
-    NSArray *wifiInterfaces = [CWInterface supportedInterfaces];
-    for (uint row = 0; row < [wifiInterfaces count]; ++row) {
-            scanThread->interfaceName = qt_NSStringToQString([wifiInterfaces objectAtIndex:row]);
+    NSSet *wifiInterfaces = [CWInterface interfaceNames];
+    for (NSString *ifName in wifiInterfaces) {
+            scanThread->interfaceName = QCFString::toQString(CFStringRef(ifName));
             scanThread->start();
     }
     locker.unlock();
@@ -669,8 +581,8 @@ bool QCoreWlanEngine::isWifiReady(const QString &wifiDeviceName)
     bool haswifi = false;
     if(hasWifi) {
         NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
-        CWInterface *defaultInterface = [CWInterface interfaceWithName: qt_QStringToNSString(wifiDeviceName)];
-        if([defaultInterface power]) {
+        CWInterface *defaultInterface = [CWInterface interfaceWithName: (NSString *)QCFString::toCFStringRef(wifiDeviceName)];
+        if (defaultInterface.powerOn) {
             haswifi = true;
         }
         [autoreleasepool release];
@@ -898,7 +810,7 @@ quint64 QCoreWlanEngine::startTime(const QString &identifier)
                 bool ok = false;
                 for(int i = 0; i < dictSize; i++) {
                     if([ssidStr isEqualToString:keys[i]]) {
-                        const QString ident = QString::number(qHash(QLatin1String("corewlan:") + qt_NSStringToQString(objects[i])));
+                        const QString ident = QString::number(qHash(QLatin1String("corewlan:") + QCFString::toQString(CFStringRef(objects[i]))));
                         if(ident == identifier) {
                             ok = true;
                         }
@@ -944,3 +856,7 @@ quint64 QCoreWlanEngine::getBytes(const QString &interfaceName, bool b)
 }
 
 QT_END_NAMESPACE
+
+#else // QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE
+#include "qcorewlanengine_10_6.mm"
+#endif
diff --git a/src/plugins/bearer/corewlan/qcorewlanengine_10_6.mm b/src/plugins/bearer/corewlan/qcorewlanengine_10_6.mm
new file mode 100644
index 0000000..a3bf615
--- /dev/null
+++ src/plugins/bearer/corewlan/qcorewlanengine_10_6.mm
@@ -0,0 +1,916 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <SystemConfiguration/SCNetworkConfiguration.h>
+
+@interface QT_MANGLE_NAMESPACE(QNSListener) : NSObject
+{
+    NSNotificationCenter *notificationCenter;
+    CWInterface *currentInterface;
+    QCoreWlanEngine *engine;
+    NSLock *locker;
+}
+- (void)notificationHandler;//:(NSNotification *)notification;
+- (void)remove;
+- (void)setEngine:(QCoreWlanEngine *)coreEngine;
+- (QCoreWlanEngine *)engine;
+- (void)dealloc;
+
+@property (assign) QCoreWlanEngine* engine;
+
+@end
+
+@implementation QT_MANGLE_NAMESPACE(QNSListener)
+
+- (id) init
+{
+    [locker lock];
+    NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+    notificationCenter = [NSNotificationCenter defaultCenter];
+    currentInterface = [CWInterface interfaceWithName:nil];
+    [notificationCenter addObserver:self selector:@selector(notificationHandler:) name:kCWPowerDidChangeNotification object:nil];
+    [locker unlock];
+    [autoreleasepool release];
+    return self;
+}
+
+-(void)dealloc
+{
+    [super dealloc];
+}
+
+-(void)setEngine:(QCoreWlanEngine *)coreEngine
+{
+    [locker lock];
+    if(!engine)
+        engine = coreEngine;
+    [locker unlock];
+}
+
+-(QCoreWlanEngine *)engine
+{
+    return engine;
+}
+
+-(void)remove
+{
+    [locker lock];
+    [notificationCenter removeObserver:self];
+    [locker unlock];
+}
+
+- (void)notificationHandler//:(NSNotification *)notification
+{
+    engine->requestUpdate();
+}
+@end
+
+static QT_MANGLE_NAMESPACE(QNSListener) *listener = 0;
+
+QT_BEGIN_NAMESPACE
+
+void networkChangeCallback(SCDynamicStoreRef/* store*/, CFArrayRef changedKeys, void *info)
+{
+    for ( long i = 0; i < CFArrayGetCount(changedKeys); i++) {
+
+        QString changed =  QCFString::toQString(CFStringRef((CFStringRef)CFArrayGetValueAtIndex(changedKeys, i)));
+        if( changed.contains("/Network/Global/IPv4")) {
+            QCoreWlanEngine* wlanEngine = static_cast<QCoreWlanEngine*>(info);
+            wlanEngine->requestUpdate();
+        }
+    }
+    return;
+}
+
+
+QScanThread::QScanThread(QObject *parent)
+    :QThread(parent)
+{
+}
+
+QScanThread::~QScanThread()
+{
+}
+
+void QScanThread::quit()
+{
+    wait();
+}
+
+void QScanThread::run()
+{
+    NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+    QStringList found;
+    mutex.lock();
+    CWInterface *currentInterface = [CWInterface interfaceWithName: (NSString *)QCFString::toCFStringRef(interfaceName)];
+    mutex.unlock();
+
+    if([currentInterface power]) {
+        NSError *err = nil;
+        NSDictionary *parametersDict =  [NSDictionary dictionaryWithObjectsAndKeys:
+                                   [NSNumber numberWithBool:YES], kCWScanKeyMerge,
+                                   [NSNumber numberWithInt:kCWScanTypeFast], kCWScanKeyScanType,
+                                   [NSNumber numberWithInteger:100], kCWScanKeyRestTime, nil];
+
+        NSArray* apArray = [currentInterface scanForNetworksWithParameters:parametersDict error:&err];
+        CWNetwork *apNetwork;
+
+        if (!err) {
+
+            for(uint row=0; row < [apArray count]; row++ ) {
+                apNetwork = [apArray objectAtIndex:row];
+
+                const QString networkSsid = QCFString::toQString(CFStringRef([apNetwork ssid]));
+                const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkSsid));
+                found.append(id);
+
+                QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined;
+                bool known = isKnownSsid(networkSsid);
+                if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) {
+                    if( networkSsid == QCFString::toQString(CFStringRef([currentInterface ssid]))) {
+                        state = QNetworkConfiguration::Active;
+                    }
+                }
+                if(state == QNetworkConfiguration::Undefined) {
+                    if(known) {
+                        state = QNetworkConfiguration::Discovered;
+                    } else {
+                        state = QNetworkConfiguration::Undefined;
+                    }
+                }
+                QNetworkConfiguration::Purpose purpose = QNetworkConfiguration::UnknownPurpose;
+                if([[apNetwork securityMode] intValue] == kCWSecurityModeOpen) {
+                    purpose = QNetworkConfiguration::PublicPurpose;
+                } else {
+                    purpose = QNetworkConfiguration::PrivatePurpose;
+                }
+
+                found.append(foundNetwork(id, networkSsid, state, interfaceName, purpose));
+
+            }
+        }
+    }
+    // add known configurations that are not around.
+    QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
+    while (i.hasNext()) {
+        i.next();
+
+        QString networkName = i.key();
+        const QString id = QString::number(qHash(QLatin1String("corewlan:") + networkName));
+
+        if(!found.contains(id)) {
+            QString networkSsid = getSsidFromNetworkName(networkName);
+            const QString ssidId = QString::number(qHash(QLatin1String("corewlan:") + networkSsid));
+            QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined;
+            QString interfaceName;
+            QMapIterator<QString, QString> ij(i.value());
+            while (ij.hasNext()) {
+                ij.next();
+                interfaceName = ij.value();
+            }
+
+            if( [currentInterface.interfaceState intValue] == kCWInterfaceStateRunning) {
+                if( networkSsid == QCFString::toQString(CFStringRef([currentInterface ssid]))) {
+                    state = QNetworkConfiguration::Active;
+                }
+            }
+            if(state == QNetworkConfiguration::Undefined) {
+                if( userProfiles.contains(networkName)
+                    && found.contains(ssidId)) {
+                    state = QNetworkConfiguration::Discovered;
+                }
+            }
+
+            if(state == QNetworkConfiguration::Undefined) {
+                state = QNetworkConfiguration::Defined;
+            }
+
+            found.append(foundNetwork(id, networkName, state, interfaceName, QNetworkConfiguration::UnknownPurpose));
+        }
+    }
+    emit networksChanged();
+    [autoreleasepool release];
+}
+
+QStringList QScanThread::foundNetwork(const QString &id, const QString &name, const QNetworkConfiguration::StateFlags state, const QString &interfaceName, const QNetworkConfiguration::Purpose purpose)
+{
+    QStringList found;
+    QMutexLocker locker(&mutex);
+        QNetworkConfigurationPrivate *ptr = new QNetworkConfigurationPrivate;
+
+        ptr->name = name;
+        ptr->isValid = true;
+        ptr->id = id;
+        ptr->state = state;
+        ptr->type = QNetworkConfiguration::InternetAccessPoint;
+        ptr->bearerType = QNetworkConfiguration::BearerWLAN;
+        ptr->purpose = purpose;
+
+        fetchedConfigurations.append( ptr);
+        configurationInterface.insert(ptr->id, interfaceName);
+
+        locker.unlock();
+        locker.relock();
+       found.append(id);
+    return found;
+}
+
+QList<QNetworkConfigurationPrivate *> QScanThread::getConfigurations()
+{
+    QMutexLocker locker(&mutex);
+
+    QList<QNetworkConfigurationPrivate *> foundConfigurations = fetchedConfigurations;
+    fetchedConfigurations.clear();
+
+    return foundConfigurations;
+}
+
+void QScanThread::getUserConfigurations()
+{
+    QMutexLocker locker(&mutex);
+
+    NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+    userProfiles.clear();
+
+    NSArray *wifiInterfaces = [CWInterface supportedInterfaces];
+    for(uint row=0; row < [wifiInterfaces count]; row++ ) {
+
+        CWInterface *wifiInterface = [CWInterface interfaceWithName: [wifiInterfaces objectAtIndex:row]];
+        if ( ![wifiInterface power] )
+            continue;
+
+        NSString *nsInterfaceName = [wifiInterface name];
+// add user configured system networks
+        SCDynamicStoreRef dynRef = SCDynamicStoreCreate(kCFAllocatorSystemDefault, (CFStringRef)@"Qt corewlan", nil, nil);
+        NSDictionary * airportPlist = (NSDictionary *)SCDynamicStoreCopyValue(dynRef, (CFStringRef)[NSString stringWithFormat:@"Setup:/Network/Interface/%@/AirPort", nsInterfaceName]);
+        CFRelease(dynRef);
+        if(airportPlist != nil) {
+            NSDictionary *prefNetDict = [airportPlist objectForKey:@"PreferredNetworks"];
+
+            NSArray *thisSsidarray = [prefNetDict valueForKey:@"SSID_STR"];
+            for(NSString *ssidkey in thisSsidarray) {
+                QString thisSsid = QCFString::toQString(CFStringRef(ssidkey));
+                if(!userProfiles.contains(thisSsid)) {
+                    QMap <QString,QString> map;
+                    map.insert(thisSsid, QCFString::toQString(CFStringRef(nsInterfaceName)));
+                    userProfiles.insert(thisSsid, map);
+                }
+            }
+            CFRelease(airportPlist);
+        }
+
+        // 802.1X user profiles
+        QString userProfilePath = QDir::homePath() + "/Library/Preferences/com.apple.eap.profiles.plist";
+        NSDictionary* eapDict = [[[NSDictionary alloc] initWithContentsOfFile: (NSString *)QCFString::toCFStringRef(userProfilePath)] autorelease];
+        if(eapDict != nil) {
+            NSString *profileStr= @"Profiles";
+            NSString *nameStr = @"UserDefinedName";
+            NSString *networkSsidStr = @"Wireless Network";
+            for (id profileKey in eapDict) {
+                if ([profileStr isEqualToString:profileKey]) {
+                    NSDictionary *itemDict = [eapDict objectForKey:profileKey];
+                    for (id itemKey in itemDict) {
+
+                        NSInteger dictSize = [itemKey count];
+                        id objects[dictSize];
+                        id keys[dictSize];
+
+                        [itemKey getObjects:objects andKeys:keys];
+                        QString networkName;
+                        QString ssid;
+                        for(int i = 0; i < dictSize; i++) {
+                            if([nameStr isEqualToString:keys[i]]) {
+                                networkName = QCFString::toQString(CFStringRef(objects[i]));
+                            }
+                            if([networkSsidStr isEqualToString:keys[i]]) {
+                                ssid = QCFString::toQString(CFStringRef(objects[i]));
+                            }
+                            if(!userProfiles.contains(networkName)
+                                && !ssid.isEmpty()) {
+                                QMap<QString,QString> map;
+                                map.insert(ssid, QCFString::toQString(CFStringRef(nsInterfaceName)));
+                                userProfiles.insert(networkName, map);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    [autoreleasepool release];
+}
+
+QString QScanThread::getSsidFromNetworkName(const QString &name)
+{
+    QMutexLocker locker(&mutex);
+
+    QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
+    while (i.hasNext()) {
+        i.next();
+        QMap<QString,QString> map = i.value();
+        QMapIterator<QString, QString> ij(i.value());
+         while (ij.hasNext()) {
+             ij.next();
+             const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") +i.key()));
+             if(name == i.key() || name == networkNameHash) {
+                 return ij.key();
+             }
+        }
+    }
+    return QString();
+}
+
+QString QScanThread::getNetworkNameFromSsid(const QString &ssid)
+{
+    QMutexLocker locker(&mutex);
+
+    QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
+    while (i.hasNext()) {
+        i.next();
+        QMap<QString,QString> map = i.value();
+        QMapIterator<QString, QString> ij(i.value());
+         while (ij.hasNext()) {
+             ij.next();
+             if(ij.key() == ssid) {
+                 return i.key();
+             }
+         }
+    }
+    return QString();
+}
+
+bool QScanThread::isKnownSsid(const QString &ssid)
+{
+    QMutexLocker locker(&mutex);
+
+    QMapIterator<QString, QMap<QString,QString> > i(userProfiles);
+    while (i.hasNext()) {
+        i.next();
+        QMap<QString,QString> map = i.value();
+        if(map.keys().contains(ssid)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+
+QCoreWlanEngine::QCoreWlanEngine(QObject *parent)
+:   QBearerEngineImpl(parent), scanThread(0)
+{
+    scanThread = new QScanThread(this);
+    connect(scanThread, SIGNAL(networksChanged()),
+            this, SLOT(networksChanged()));
+}
+
+QCoreWlanEngine::~QCoreWlanEngine()
+{
+    while (!foundConfigurations.isEmpty())
+        delete foundConfigurations.takeFirst();
+    [listener remove];
+    [listener release];
+}
+
+void QCoreWlanEngine::initialize()
+{
+    QMutexLocker locker(&mutex);
+    NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+
+    if([[CWInterface supportedInterfaces] count] > 0 && !listener) {
+        listener = [[QT_MANGLE_NAMESPACE(QNSListener) alloc] init];
+        listener.engine = this;
+        hasWifi = true;
+    } else {
+        hasWifi = false;
+    }
+    storeSession = NULL;
+
+    startNetworkChangeLoop();
+    [autoreleasepool release];
+}
+
+
+QString QCoreWlanEngine::getInterfaceFromId(const QString &id)
+{
+    QMutexLocker locker(&mutex);
+
+    return scanThread->configurationInterface.value(id);
+}
+
+bool QCoreWlanEngine::hasIdentifier(const QString &id)
+{
+    QMutexLocker locker(&mutex);
+
+    return scanThread->configurationInterface.contains(id);
+}
+
+void QCoreWlanEngine::connectToId(const QString &id)
+{
+    QMutexLocker locker(&mutex);
+    NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+    QString interfaceString = getInterfaceFromId(id);
+
+    CWInterface *wifiInterface =
+        [CWInterface interfaceWithName: (NSString *)QCFString::toCFStringRef(interfaceString)];
+
+    if ([wifiInterface power]) {
+        NSError *err = nil;
+        NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0];
+
+        QString wantedSsid;
+
+        QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
+
+        const QString idHash = QString::number(qHash(QLatin1String("corewlan:") + ptr->name));
+        const QString idHash2 = QString::number(qHash(QLatin1String("corewlan:") + scanThread->getNetworkNameFromSsid(ptr->name)));
+
+        bool using8021X = false;
+        if (idHash2 != id) {
+            NSArray *array = [CW8021XProfile allUser8021XProfiles];
+
+            for (NSUInteger i = 0; i < [array count]; ++i) {
+                const QString networkNameHashCheck = QString::number(qHash(QLatin1String("corewlan:") + QCFString::toQString(CFStringRef([[array objectAtIndex:i] userDefinedName]))));
+
+                const QString ssidHash = QString::number(qHash(QLatin1String("corewlan:") + QCFString::toQString(CFStringRef([[array objectAtIndex:i] ssid]))));
+
+                if (id == networkNameHashCheck || id == ssidHash) {
+                    const QString thisName = scanThread->getSsidFromNetworkName(id);
+                    if (thisName.isEmpty())
+                        wantedSsid = id;
+                    else
+                        wantedSsid = thisName;
+
+                    [params setValue: [array objectAtIndex:i] forKey:kCWAssocKey8021XProfile];
+                    using8021X = true;
+                    break;
+                }
+            }
+        }
+
+        if (!using8021X) {
+            QString wantedNetwork;
+            QMapIterator<QString, QMap<QString,QString> > i(scanThread->userProfiles);
+            while (i.hasNext()) {
+                i.next();
+                wantedNetwork = i.key();
+                const QString networkNameHash = QString::number(qHash(QLatin1String("corewlan:") + wantedNetwork));
+                if (id == networkNameHash) {
+                    wantedSsid =  scanThread->getSsidFromNetworkName(wantedNetwork);
+                    break;
+                }
+            }
+        }
+        NSDictionary *scanParameters = [NSDictionary dictionaryWithObjectsAndKeys:
+                                        [NSNumber numberWithBool:YES], kCWScanKeyMerge,
+                                        [NSNumber numberWithInt:kCWScanTypeFast], kCWScanKeyScanType,
+                                        [NSNumber numberWithInteger:100], kCWScanKeyRestTime,
+                                        (NSString *)QCFString::toCFStringRef(wantedSsid), kCWScanKeySSID,
+                                        nil];
+
+        NSArray *scanArray = [wifiInterface scanForNetworksWithParameters:scanParameters error:&err];
+
+        if(!err) {
+            for(uint row=0; row < [scanArray count]; row++ ) {
+                CWNetwork *apNetwork = [scanArray objectAtIndex:row];
+
+                if(wantedSsid == QCFString::toQString(CFStringRef([apNetwork ssid]))) {
+
+                    if(!using8021X) {
+                        SecKeychainAttribute attributes[3];
+
+                        NSString *account = [apNetwork ssid];
+                        NSString *keyKind = @"AirPort network password";
+                        NSString *keyName = account;
+
+                        attributes[0].tag = kSecAccountItemAttr;
+                        attributes[0].data = (void *)[account UTF8String];
+                        attributes[0].length = [account length];
+
+                        attributes[1].tag = kSecDescriptionItemAttr;
+                        attributes[1].data = (void *)[keyKind UTF8String];
+                        attributes[1].length = [keyKind length];
+
+                        attributes[2].tag = kSecLabelItemAttr;
+                        attributes[2].data = (void *)[keyName UTF8String];
+                        attributes[2].length = [keyName length];
+
+                        SecKeychainAttributeList attributeList = {3,attributes};
+
+                        SecKeychainSearchRef searchRef;
+                        SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, &attributeList, &searchRef);
+
+                        NSString *password = @"";
+                        SecKeychainItemRef searchItem;
+
+                        if (SecKeychainSearchCopyNext(searchRef, &searchItem) == noErr) {
+                            UInt32 realPasswordLength;
+                            SecKeychainAttribute attributesW[8];
+                            attributesW[0].tag = kSecAccountItemAttr;
+                            SecKeychainAttributeList listW = {1,attributesW};
+                            char *realPassword;
+                            OSStatus status = SecKeychainItemCopyContent(searchItem, NULL, &listW, &realPasswordLength,(void **)&realPassword);
+
+                            if (status == noErr) {
+                                if (realPassword != NULL) {
+
+                                    QByteArray pBuf;
+                                    pBuf.resize(realPasswordLength);
+                                    pBuf.prepend(realPassword);
+                                    pBuf.insert(realPasswordLength,'\0');
+
+                                    password = [NSString stringWithUTF8String:pBuf];
+                                }
+                                SecKeychainItemFreeContent(&listW, realPassword);
+                            }
+
+                            CFRelease(searchItem);
+                        } else {
+                            qDebug() << "SecKeychainSearchCopyNext error";
+                        }
+                        [params setValue: password forKey: kCWAssocKeyPassphrase];
+                    } // end using8021X
+
+
+                    bool result = [wifiInterface associateToNetwork: apNetwork parameters:[NSDictionary dictionaryWithDictionary:params] error:&err];
+
+                    if(!err) {
+                        if(!result) {
+                            emit connectionError(id, ConnectError);
+                        } else {
+                            return;
+                        }
+                    } else {
+                        qDebug() <<"associate ERROR"<<  QCFString::toQString(CFStringRef([err localizedDescription ]));
+                    }
+                }
+            } //end scan network
+        } else {
+            qDebug() <<"scan ERROR"<<  QCFString::toQString(CFStringRef([err localizedDescription ]));
+        }
+        emit connectionError(id, InterfaceLookupError);
+    }
+
+    locker.unlock();
+    emit connectionError(id, InterfaceLookupError);
+    [autoreleasepool release];
+}
+
+void QCoreWlanEngine::disconnectFromId(const QString &id)
+{
+    QMutexLocker locker(&mutex);
+
+    QString interfaceString = getInterfaceFromId(id);
+    NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+
+    CWInterface *wifiInterface =
+        [CWInterface interfaceWithName: (NSString *)QCFString::toCFStringRef(interfaceString)];
+
+    [wifiInterface disassociate];
+    if ([[wifiInterface interfaceState]intValue] != kCWInterfaceStateInactive) {
+        locker.unlock();
+        emit connectionError(id, DisconnectionError);
+        locker.relock();
+    }
+    [autoreleasepool release];
+}
+
+void QCoreWlanEngine::requestUpdate()
+{
+    scanThread->getUserConfigurations();
+    doRequestUpdate();
+}
+
+void QCoreWlanEngine::doRequestUpdate()
+{
+    QMutexLocker locker(&mutex);
+
+    NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+
+    NSArray *wifiInterfaces = [CWInterface supportedInterfaces];
+    for (uint row = 0; row < [wifiInterfaces count]; ++row) {
+            scanThread->interfaceName = QCFString::toQString(CFStringRef([wifiInterfaces objectAtIndex:row]));
+            scanThread->start();
+    }
+    locker.unlock();
+    [autoreleasepool release];
+}
+
+bool QCoreWlanEngine::isWifiReady(const QString &wifiDeviceName)
+{
+    QMutexLocker locker(&mutex);
+    bool haswifi = false;
+    if(hasWifi) {
+        NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+        CWInterface *defaultInterface = [CWInterface interfaceWithName: (NSString *)QCFString::toCFStringRef(wifiDeviceName)];
+        if([defaultInterface power]) {
+            haswifi = true;
+        }
+        [autoreleasepool release];
+    }
+    return haswifi;
+}
+
+
+QNetworkSession::State QCoreWlanEngine::sessionStateForId(const QString &id)
+{
+    QMutexLocker locker(&mutex);
+    QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
+
+    if (!ptr)
+        return QNetworkSession::Invalid;
+
+    if (!ptr->isValid) {
+        return QNetworkSession::Invalid;
+    } else if ((ptr->state & QNetworkConfiguration::Active) == QNetworkConfiguration::Active) {
+        return QNetworkSession::Connected;
+    } else if ((ptr->state & QNetworkConfiguration::Discovered) ==
+                QNetworkConfiguration::Discovered) {
+        return QNetworkSession::Disconnected;
+    } else if ((ptr->state & QNetworkConfiguration::Defined) == QNetworkConfiguration::Defined) {
+        return QNetworkSession::NotAvailable;
+    } else if ((ptr->state & QNetworkConfiguration::Undefined) ==
+                QNetworkConfiguration::Undefined) {
+        return QNetworkSession::NotAvailable;
+    }
+
+    return QNetworkSession::Invalid;
+}
+
+QNetworkConfigurationManager::Capabilities QCoreWlanEngine::capabilities() const
+{
+    return QNetworkConfigurationManager::ForcedRoaming;
+}
+
+void QCoreWlanEngine::startNetworkChangeLoop()
+{
+
+    SCDynamicStoreContext dynStoreContext = { 0, this/*(void *)storeSession*/, NULL, NULL, NULL };
+    storeSession = SCDynamicStoreCreate(NULL,
+                                 CFSTR("networkChangeCallback"),
+                                 networkChangeCallback,
+                                 &dynStoreContext);
+    if (!storeSession ) {
+        qWarning() << "could not open dynamic store: error:" << SCErrorString(SCError());
+        return;
+    }
+
+    CFMutableArrayRef notificationKeys;
+    notificationKeys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    CFMutableArrayRef patternsArray;
+    patternsArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+    CFStringRef storeKey;
+    storeKey = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+                                                     kSCDynamicStoreDomainState,
+                                                     kSCEntNetIPv4);
+    CFArrayAppendValue(notificationKeys, storeKey);
+    CFRelease(storeKey);
+
+    storeKey = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                      kSCDynamicStoreDomainState,
+                                                      kSCCompAnyRegex,
+                                                      kSCEntNetIPv4);
+    CFArrayAppendValue(patternsArray, storeKey);
+    CFRelease(storeKey);
+
+    if (!SCDynamicStoreSetNotificationKeys(storeSession , notificationKeys, patternsArray)) {
+        qWarning() << "register notification error:"<< SCErrorString(SCError());
+        CFRelease(storeSession );
+        CFRelease(notificationKeys);
+        CFRelease(patternsArray);
+        return;
+    }
+    CFRelease(notificationKeys);
+    CFRelease(patternsArray);
+
+    runloopSource = SCDynamicStoreCreateRunLoopSource(NULL, storeSession , 0);
+    if (!runloopSource) {
+        qWarning() << "runloop source error:"<< SCErrorString(SCError());
+        CFRelease(storeSession );
+        return;
+    }
+
+    CFRunLoopAddSource(CFRunLoopGetCurrent(), runloopSource, kCFRunLoopDefaultMode);
+    return;
+}
+
+QNetworkSessionPrivate *QCoreWlanEngine::createSessionBackend()
+{
+    return new QNetworkSessionPrivateImpl;
+}
+
+QNetworkConfigurationPrivatePointer QCoreWlanEngine::defaultConfiguration()
+{
+    return QNetworkConfigurationPrivatePointer();
+}
+
+bool QCoreWlanEngine::requiresPolling() const
+{
+    return true;
+}
+
+void QCoreWlanEngine::networksChanged()
+{
+    QMutexLocker locker(&mutex);
+
+    QStringList previous = accessPointConfigurations.keys();
+
+    QList<QNetworkConfigurationPrivate *> foundConfigurations = scanThread->getConfigurations();
+    while (!foundConfigurations.isEmpty()) {
+        QNetworkConfigurationPrivate *cpPriv = foundConfigurations.takeFirst();
+
+        previous.removeAll(cpPriv->id);
+
+        if (accessPointConfigurations.contains(cpPriv->id)) {
+            QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(cpPriv->id);
+
+            bool changed = false;
+
+            ptr->mutex.lock();
+
+            if (ptr->isValid != cpPriv->isValid) {
+                ptr->isValid = cpPriv->isValid;
+                changed = true;
+            }
+
+            if (ptr->name != cpPriv->name) {
+                ptr->name = cpPriv->name;
+                changed = true;
+            }
+
+            if (ptr->bearerType != cpPriv->bearerType) {
+                ptr->bearerType = cpPriv->bearerType;
+                changed = true;
+            }
+
+            if (ptr->state != cpPriv->state) {
+                ptr->state = cpPriv->state;
+                changed = true;
+            }
+
+            ptr->mutex.unlock();
+
+            if (changed) {
+                locker.unlock();
+                emit configurationChanged(ptr);
+                locker.relock();
+            }
+
+            delete cpPriv;
+        } else {
+            QNetworkConfigurationPrivatePointer ptr(cpPriv);
+
+            accessPointConfigurations.insert(ptr->id, ptr);
+
+            locker.unlock();
+            emit configurationAdded(ptr);
+            locker.relock();
+        }
+    }
+
+    while (!previous.isEmpty()) {
+        QNetworkConfigurationPrivatePointer ptr =
+            accessPointConfigurations.take(previous.takeFirst());
+
+        locker.unlock();
+        emit configurationRemoved(ptr);
+        locker.relock();
+    }
+
+    locker.unlock();
+    emit updateCompleted();
+
+}
+
+quint64 QCoreWlanEngine::bytesWritten(const QString &id)
+{
+    QMutexLocker locker(&mutex);
+    const QString interfaceStr = getInterfaceFromId(id);
+    return getBytes(interfaceStr,false);
+}
+
+quint64 QCoreWlanEngine::bytesReceived(const QString &id)
+{
+    QMutexLocker locker(&mutex);
+    const QString interfaceStr = getInterfaceFromId(id);
+    return getBytes(interfaceStr,true);
+}
+
+quint64 QCoreWlanEngine::startTime(const QString &identifier)
+{
+    QMutexLocker locker(&mutex);
+    NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
+    quint64 timestamp = 0;
+
+    NSString *filePath = @"/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist";
+    NSDictionary* plistDict = [[[NSDictionary alloc] initWithContentsOfFile:filePath] autorelease];
+    if(plistDict == nil)
+        return timestamp;
+    NSString *input = @"KnownNetworks";
+    NSString *timeStampStr = @"_timeStamp";
+
+    NSString *ssidStr = @"SSID_STR";
+
+    for (id key in plistDict) {
+        if ([input isEqualToString:key]) {
+
+            NSDictionary *knownNetworksDict = [plistDict objectForKey:key];
+            if(knownNetworksDict == nil)
+                return timestamp;
+            for (id networkKey in knownNetworksDict) {
+                bool isFound = false;
+                NSDictionary *itemDict = [knownNetworksDict objectForKey:networkKey];
+                if(itemDict == nil)
+                    return timestamp;
+                NSInteger dictSize = [itemDict count];
+                id objects[dictSize];
+                id keys[dictSize];
+
+                [itemDict getObjects:objects andKeys:keys];
+                bool ok = false;
+                for(int i = 0; i < dictSize; i++) {
+                    if([ssidStr isEqualToString:keys[i]]) {
+                        const QString ident = QString::number(qHash(QLatin1String("corewlan:") + QCFString::toQString(CFStringRef(objects[i]))));
+                        if(ident == identifier) {
+                            ok = true;
+                        }
+                    }
+                    if(ok && [timeStampStr isEqualToString:keys[i]]) {
+                        timestamp = (quint64)[objects[i] timeIntervalSince1970];
+                        isFound = true;
+                        break;
+                    }
+                }
+                if(isFound)
+                    break;
+            }
+        }
+    }
+    [autoreleasepool release];
+    return timestamp;
+}
+
+quint64 QCoreWlanEngine::getBytes(const QString &interfaceName, bool b)
+{
+    struct ifaddrs *ifAddressList, *ifAddress;
+    struct if_data *if_data;
+
+    quint64 bytes = 0;
+    ifAddressList = nil;
+    if(getifaddrs(&ifAddressList) == 0) {
+        for(ifAddress = ifAddressList; ifAddress; ifAddress = ifAddress->ifa_next) {
+            if(interfaceName == ifAddress->ifa_name) {
+                if_data = (struct if_data*)ifAddress->ifa_data;
+                if(b) {
+                    bytes = if_data->ifi_ibytes;
+                    break;
+                } else {
+                    bytes = if_data->ifi_obytes;
+                    break;
+                }
+            }
+        }
+        freeifaddrs(ifAddressList);
+    }
+    return bytes;
+}
+
+QT_END_NAMESPACE
