diff --git a/examples/bluetooth/heartlistener/heartrate.cpp b/examples/bluetooth/heartlistener/heartrate.cpp
index fe53a740c3c906a556f2b603961e637016b12d04..08433195876f5b878110e3d287137926ae13f574 100644
--- a/examples/bluetooth/heartlistener/heartrate.cpp
+++ b/examples/bluetooth/heartlistener/heartrate.cpp
@@ -41,6 +41,8 @@
 
 #include "heartrate.h"
 
+#include <QtEndian>
+
 HeartRate::HeartRate():
     m_currentDevice(QBluetoothDeviceInfo()), foundHeartRateService(false),
     m_max(0), m_min(0), calories(0), m_control(0), timer(0),
@@ -301,16 +303,16 @@ void HeartRate::updateHeartRateValue(const QLowEnergyCharacteristic &c,
         return;
 
 
-    const char *data = value.constData();
+    const quint8 *data = reinterpret_cast<const quint8 *>(value.constData());
     quint8 flags = data[0];
 
     //Heart Rate
     if (flags & 0x1) { // HR 16 bit? otherwise 8 bit
-        quint16 *heartRate = (quint16 *) &data[1];
-        //qDebug() << "16 bit HR value:" << *heartRate;
-        m_measurements.append(*heartRate);
+        const quint16 heartRate = qFromLittleEndian<quint16>(data[1]);
+        //qDebug() << "16 bit HR value:" << heartRate;
+        m_measurements.append(heartRate);
     } else {
-        quint8 *heartRate = (quint8 *) &data[1];
+        const quint8 *heartRate = &data[1];
         m_measurements.append(*heartRate);
         //qDebug() << "8 bit HR value:" << *heartRate;
     }
@@ -318,8 +320,8 @@ void HeartRate::updateHeartRateValue(const QLowEnergyCharacteristic &c,
     //Energy Expended
     if (flags & 0x8) {
         int index = (flags & 0x1) ? 5 : 3;
-        quint16 *energy = (quint16 *) &data[index];
-        qDebug() << "Used Energy:" << *energy;
+        const quint16 energy = qFromLittleEndian<quint16>(data[index]);
+        qDebug() << "Used Energy:" << energy;
     }
     //! [Reading value 1]
 
diff --git a/qtconnectivity.pro b/qtconnectivity.pro
index 82346519a07092b6dfe8747a588c0e87ddf038c4..5eb864b88bea5adb74a754184d82c858fc949118 100644
--- a/qtconnectivity.pro
+++ b/qtconnectivity.pro
@@ -1,3 +1,5 @@
+require(!android|qtHaveModule(androidextras))
+
 load(configure)
 qtCompileTest(bluez)
 qtCompileTest(bluez_le)
diff --git a/src/bluetooth/android/jni_android.cpp b/src/bluetooth/android/jni_android.cpp
index b42095003296ddb18296bf6b02cde7d281694461..061d7d962102ec0f7d1908eaf5b2dbb862aaf39a 100644
--- a/src/bluetooth/android/jni_android.cpp
+++ b/src/bluetooth/android/jni_android.cpp
@@ -249,7 +249,7 @@ static bool registerNatives(JNIEnv *env)
     FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/bluetooth/QtBluetoothBroadcastReceiver");
 
     if (env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
-        __android_log_print(ANDROID_LOG_FATAL, logTag, "RegisterNatives for BraodcastReceiver failed");
+        __android_log_print(ANDROID_LOG_FATAL, logTag, "RegisterNatives for BroadcastReceiver failed");
         return false;
     }
 
diff --git a/src/bluetooth/osx/osxbt.pri b/src/bluetooth/osx/osxbt.pri
index 06389fcc1a644f1d5039f0c8aded7fd28ade71bf..bb382866f4f825497a73ab0774bbc22fe180f71d 100644
--- a/src/bluetooth/osx/osxbt.pri
+++ b/src/bluetooth/osx/osxbt.pri
@@ -1,4 +1,4 @@
-SOURCES += osx/uistrings.cpp
+SOURCES += osx/uistrings.cpp osx/osxbtnotifier.cpp
 PRIVATE_HEADERS += osx/uistrings_p.h
 
 CONFIG(osx) {
@@ -15,7 +15,8 @@ CONFIG(osx) {
                        osx/osxbtobexsession_p.h \
                        osx/osxbtledeviceinquiry_p.h \
                        osx/corebluetoothwrapper_p.h \
-                       osx/osxbtcentralmanager_p.h
+                       osx/osxbtcentralmanager_p.h \
+                       osx/osxbtnotifier_p.h
 
     OBJECTIVE_SOURCES += osx/osxbtutility.mm \
                          osx/osxbtdevicepair.mm \
@@ -34,7 +35,8 @@ CONFIG(osx) {
     PRIVATE_HEADERS += osx/osxbtutility_p.h \
                        osx/osxbtledeviceinquiry_p.h \
                        osx/corebluetoothwrapper_p.h \
-                       osx/osxbtcentralmanager_p.h
+                       osx/osxbtcentralmanager_p.h \
+                       osx/osxbtnotifier_p.h
 
     OBJECTIVE_SOURCES += osx/osxbtutility.mm \
                          osx/osxbtledeviceinquiry.mm \
diff --git a/src/bluetooth/osx/osxbtcentralmanager.mm b/src/bluetooth/osx/osxbtcentralmanager.mm
index 614e4ae5410a70e3ff53f228d997433877f90b0a..2f881f794a61f9f1c9e8c20da7bc0375902c7bb6 100644
--- a/src/bluetooth/osx/osxbtcentralmanager.mm
+++ b/src/bluetooth/osx/osxbtcentralmanager.mm
@@ -34,7 +34,7 @@
 #include "qlowenergyserviceprivate_p.h"
 #include "qlowenergycharacteristic.h"
 #include "osxbtcentralmanager_p.h"
-
+#include "osxbtnotifier_p.h"
 
 #include <QtCore/qloggingcategory.h>
 #include <QtCore/qsysinfo.h>
@@ -45,11 +45,11 @@
 
 QT_BEGIN_NAMESPACE
 
-namespace OSXBluetooth {
+Q_DECLARE_METATYPE(QLowEnergyCharacteristic)
+Q_DECLARE_METATYPE(QLowEnergyDescriptor)
+Q_DECLARE_METATYPE(QLowEnergyHandle)
 
-CentralManagerDelegate::~CentralManagerDelegate()
-{
-}
+namespace OSXBluetooth {
 
 NSUInteger qt_countGATTEntries(CBService *service)
 {
@@ -80,15 +80,12 @@ NSUInteger qt_countGATTEntries(CBService *service)
 
 QT_END_NAMESPACE
 
-
-#ifdef QT_NAMESPACE
-using namespace QT_NAMESPACE;
-#endif
+QT_USE_NAMESPACE
 
 @interface QT_MANGLE_NAMESPACE(OSXBTCentralManager) (PrivateAPI)
 
-- (QLowEnergyController::Error)connectToDevice; // "Device" is in Qt's world ...
-- (void)connectToPeripheral; // "Peripheral" is in Core Bluetooth.
+- (void)retrievePeripheralAndConnect;
+- (void)connectToPeripheral;
 - (void)discoverIncludedServices;
 - (void)readCharacteristics:(CBService *)service;
 - (void)serviceDetailsDiscoveryFinished:(CBService *)service;
@@ -114,16 +111,14 @@ using namespace QT_NAMESPACE;
 
 @implementation QT_MANGLE_NAMESPACE(OSXBTCentralManager)
 
-- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth)::CentralManagerDelegate *)aDelegate
+- (id)initWith:(OSXBluetooth::LECentralNotifier *)aNotifier
 {
-    Q_ASSERT_X(aDelegate, Q_FUNC_INFO, "invalid delegate (null)");
-
     if (self = [super init]) {
         manager = nil;
         managerState = OSXBluetooth::CentralManagerIdle;
         disconnectPending = false;
         peripheral = nil;
-        delegate = aDelegate;
+        notifier = aNotifier;
         currentService = 0;
         lastValidHandle = 0;
         requestPending = false;
@@ -150,32 +145,37 @@ using namespace QT_NAMESPACE;
     [peripheral setDelegate:nil];
     [peripheral release];
 
+    if (notifier)
+        notifier->deleteLater();
+
     [super dealloc];
 }
 
-- (QLowEnergyController::Error)connectToDevice:(const QBluetoothUuid &)aDeviceUuid
+- (void)connectToDevice:(const QBluetoothUuid &)aDeviceUuid
 {
-    Q_ASSERT_X(managerState == OSXBluetooth::CentralManagerIdle,
-               Q_FUNC_INFO, "invalid state");
-
+    disconnectPending = false; // Cancel the previous disconnect if any.
     deviceUuid = aDeviceUuid;
 
     if (!manager) {
-        managerState = OSXBluetooth::CentralManagerUpdating; // We'll have to wait for updated state.
-        manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
+        // The first time we try to connect, no manager created yet,
+        // no status update received.
+        if (const dispatch_queue_t leQueue = OSXBluetooth::qt_LE_queue()) {
+            managerState = OSXBluetooth::CentralManagerUpdating;
+            manager = [[CBCentralManager alloc] initWithDelegate:self queue:leQueue];
+        }
+
         if (!manager) {
             managerState = OSXBluetooth::CentralManagerIdle;
-            qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "failed to allocate a "
-                                    "central manager";
-            return QLowEnergyController::ConnectionError;
+            qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "failed to allocate a central manager";
+            if (notifier)
+                emit notifier->CBCentralManagerError(QLowEnergyController::ConnectionError);
         }
-        return QLowEnergyController::NoError;
-    } else {
-        return [self connectToDevice];
+    } else if (managerState != OSXBluetooth::CentralManagerUpdating) {
+        [self retrievePeripheralAndConnect];
     }
 }
 
-- (QLowEnergyController::Error)connectToDevice
+- (void)retrievePeripheralAndConnect
 {
     Q_ASSERT_X(manager, Q_FUNC_INFO, "invalid central manager (nil)");
     Q_ASSERT_X(managerState == OSXBluetooth::CentralManagerIdle,
@@ -183,13 +183,14 @@ using namespace QT_NAMESPACE;
 
     if ([self isConnected]) {
         qCDebug(QT_BT_OSX) << Q_FUNC_INFO << "already connected";
-        delegate->connectSuccess();
-        return QLowEnergyController::NoError;
+        if (notifier)
+            emit notifier->connected();
+        return;
     } else if (peripheral) {
         // Was retrieved already, but not connected
         // or disconnected.
         [self connectToPeripheral];
-        return QLowEnergyController::NoError;
+        return;
     }
 
     using namespace OSXBluetooth;
@@ -198,7 +199,9 @@ using namespace QT_NAMESPACE;
     ObjCScopedPointer<NSMutableArray> uuids([[NSMutableArray alloc] init]);
     if (!uuids) {
         qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "failed to allocate identifiers";
-        return QLowEnergyController::ConnectionError;
+        if (notifier)
+            emit notifier->CBCentralManagerError(QLowEnergyController::ConnectionError);
+        return;
     }
 
 #if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_9, __IPHONE_7_0)
@@ -210,43 +213,47 @@ using namespace QT_NAMESPACE;
         const ObjCScopedPointer<NSUUID> nsUuid([[NSUUID alloc] initWithUUIDBytes:uuidData]);
         if (!nsUuid) {
             qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "failed to allocate NSUUID identifier";
-            return QLowEnergyController::ConnectionError;
+            if (notifier)
+                emit notifier->CBCentralManagerError(QLowEnergyController::ConnectionError);
+            return;
         }
 
         [uuids addObject:nsUuid];
-
         // With the latest CoreBluetooth, we can synchronously retrive peripherals:
         QT_BT_MAC_AUTORELEASEPOOL;
         NSArray *const peripherals = [manager retrievePeripheralsWithIdentifiers:uuids];
         if (!peripherals || peripherals.count != 1) {
             qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "failed to retrive a peripheral";
-            return QLowEnergyController::UnknownRemoteDeviceError;
+            if (notifier)
+                emit notifier->CBCentralManagerError(QLowEnergyController::UnknownRemoteDeviceError);
+            return;
         }
 
         peripheral = [static_cast<CBPeripheral *>([peripherals objectAtIndex:0]) retain];
         [self connectToPeripheral];
-
-        return QLowEnergyController::NoError;
+        return;
     }
 #endif
     // Either SDK or the target is below 10.9/7.0
     if (![manager respondsToSelector:@selector(retrievePeripherals:)]) {
         qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "failed to retrive a peripheral";
-        return QLowEnergyController::UnknownRemoteDeviceError;
+        if (notifier)
+            emit notifier->CBCentralManagerError(QLowEnergyController::UnknownRemoteDeviceError);
+        return;
     }
 
     OSXBluetooth::CFStrongReference<CFUUIDRef> cfUuid(OSXBluetooth::cf_uuid(deviceUuid));
     if (!cfUuid) {
         qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "failed to create CFUUID object";
-        return QLowEnergyController::ConnectionError;
+        if (notifier)
+            emit notifier->CBCentralManagerError(QLowEnergyController::ConnectionError);
+        return;
     }
-    // TODO: With ARC this cast will be illegal:
+    // With ARC this cast will be illegal:
     [uuids addObject:(id)cfUuid.data()];
     // Unfortunately, with old Core Bluetooth this call is asynchronous ...
     managerState = OSXBluetooth::CentralManagerConnecting;
     [manager performSelector:@selector(retrievePeripherals:) withObject:uuids.data()];
-
-    return QLowEnergyController::NoError;
 }
 
 - (void)connectToPeripheral
@@ -259,7 +266,8 @@ using namespace QT_NAMESPACE;
     // The state is still the same - connecting.
     if ([self isConnected]) {
         qCDebug(QT_BT_OSX) << Q_FUNC_INFO << "already connected";
-        delegate->connectSuccess();
+        if (notifier)
+            emit notifier->connected();
     } else {
         qCDebug(QT_BT_OSX) << Q_FUNC_INFO << "trying to connect";
         managerState = OSXBluetooth::CentralManagerConnecting;
@@ -291,10 +299,17 @@ using namespace QT_NAMESPACE;
     [self reset];
 
     if (managerState == OSXBluetooth::CentralManagerUpdating) {
-        disconnectPending = true;
+        disconnectPending = true; // this is for 'didUpdate' method.
+        if (notifier) {
+            // We were waiting for the first update
+            // with 'PoweredOn' status, when suddenly got disconnected called.
+            // Since we have not attempted to connect yet, emit now.
+            // Note: we do not change the state, since we still maybe interested
+            // in the status update before the next connect attempt.
+            emit notifier->disconnected();
+        }
     } else {
         disconnectPending = false;
-
         if ([self isConnected])
             managerState = OSXBluetooth::CentralManagerDisconnecting;
         else
@@ -303,8 +318,9 @@ using namespace QT_NAMESPACE;
         // We have to call -cancelPeripheralConnection: even
         // if not connected (to cancel a pending connect attempt).
         // Unfortunately, didDisconnect callback is not always called
-        // (despite of Apple's docs saying it _must_).
-        [manager cancelPeripheralConnection:peripheral];
+        // (despite of Apple's docs saying it _must_ be).
+        if (peripheral)
+            [manager cancelPeripheralConnection:peripheral];
     }
 }
 
@@ -321,7 +337,6 @@ using namespace QT_NAMESPACE;
     //parameter to nil is considerably slower and is not recommended."
     //
     // ... but we'd like to have them all:
-
     [peripheral setDelegate:self];
     managerState = OSXBluetooth::CentralManagerDiscovering;
     [peripheral discoverServices:nil];
@@ -331,19 +346,17 @@ using namespace QT_NAMESPACE;
 {
     using namespace OSXBluetooth;
 
-    Q_ASSERT_X(managerState == CentralManagerIdle, Q_FUNC_INFO,
-               "invalid state");
+    Q_ASSERT_X(managerState == CentralManagerIdle, Q_FUNC_INFO, "invalid state");
     Q_ASSERT_X(manager, Q_FUNC_INFO, "invalid manager (nil)");
     Q_ASSERT_X(peripheral, Q_FUNC_INFO, "invalid peripheral (nil)");
 
     QT_BT_MAC_AUTORELEASEPOOL;
 
     NSArray *const services = peripheral.services;
-    if (!services || !services.count) { // Actually, !services.count works in both cases, but ...
+    if (!services || !services.count) {
         // A peripheral without any services at all.
-        Q_ASSERT_X(delegate, Q_FUNC_INFO,
-                   "invalid delegate (null)");
-        delegate->serviceDiscoveryFinished(ObjCStrongReference<NSArray>());
+        if (notifier)
+            emit notifier->serviceDiscoveryFinished();
     } else {
         // 'reset' also calls retain on a parameter.
         servicesToVisitNext.reset(nil);
@@ -358,7 +371,7 @@ using namespace QT_NAMESPACE;
     }
 }
 
-- (bool)discoverServiceDetails:(const QBluetoothUuid &)serviceUuid
+- (void)discoverServiceDetails:(const QBluetoothUuid &)serviceUuid
 {
     // This function does not change 'managerState', since it
     // can be called concurrently (not waiting for the previous
@@ -373,7 +386,7 @@ using namespace QT_NAMESPACE;
     if (servicesToDiscoverDetails.contains(serviceUuid)) {
         qCWarning(QT_BT_OSX) << Q_FUNC_INFO <<"already discovering for "
                              << serviceUuid;
-        return true;
+        return;
     }
 
     QT_BT_MAC_AUTORELEASEPOOL;
@@ -381,13 +394,16 @@ using namespace QT_NAMESPACE;
     if (CBService *const service = [self serviceForUUID:serviceUuid]) {
         servicesToDiscoverDetails.append(serviceUuid);
         [peripheral discoverCharacteristics:nil forService:service];
-        return true;
+        return;
     }
 
     qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "unknown service uuid "
                          << serviceUuid;
 
-    return false;
+    if (notifier) {
+        emit notifier->CBCentralManagerError(serviceUuid,
+                       QLowEnergyService::UnknownError);
+    }
 }
 
 - (void)readCharacteristics:(CBService *)service
@@ -400,11 +416,9 @@ using namespace QT_NAMESPACE;
 
     QT_BT_MAC_AUTORELEASEPOOL;
 
-    Q_ASSERT_X(managerState != CentralManagerUpdating, Q_FUNC_INFO,
-               "invalid state");
+    Q_ASSERT_X(managerState != CentralManagerUpdating, Q_FUNC_INFO, "invalid state");
     Q_ASSERT_X(manager, Q_FUNC_INFO, "invalid manager (nil)");
     Q_ASSERT_X(peripheral, Q_FUNC_INFO, "invalid peripheral (nil)");
-    Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
 
     if (!service.characteristics || !service.characteristics.count)
         return [self serviceDetailsDiscoveryFinished:service];
@@ -444,20 +458,16 @@ using namespace QT_NAMESPACE;
 
 - (void)readDescriptors:(CBService *)service
 {
-    Q_ASSERT_X(service, "-readDescriptors:",
-               "invalid service (nil)");
+    Q_ASSERT_X(service, Q_FUNC_INFO, "invalid service (nil)");
     Q_ASSERT_X(managerState != OSXBluetooth::CentralManagerUpdating,
-               "-readDescriptors:",
-               "invalid state");
-    Q_ASSERT_X(peripheral, "-readDescriptors:",
-               "invalid peripheral (nil)");
+               Q_FUNC_INFO, "invalid state");
+    Q_ASSERT_X(peripheral, Q_FUNC_INFO, "invalid peripheral (nil)");
 
     QT_BT_MAC_AUTORELEASEPOOL;
 
     NSArray *const cs = service.characteristics;
     // We can never be here if we have no characteristics.
-    Q_ASSERT_X(cs && cs.count, "-readDescriptors:",
-               "invalid service");
+    Q_ASSERT_X(cs && cs.count, Q_FUNC_INFO, "invalid service");
     for (CBCharacteristic *c in cs) {
         if (c.descriptors && c.descriptors.count)
             return [peripheral readValueForDescriptor:[c.descriptors objectAtIndex:0]];
@@ -469,9 +479,7 @@ using namespace QT_NAMESPACE;
 
 - (void)serviceDetailsDiscoveryFinished:(CBService *)service
 {
-    //
     Q_ASSERT_X(service, Q_FUNC_INFO, "invalid service (nil)");
-    Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
 
     using namespace OSXBluetooth;
 
@@ -487,7 +495,8 @@ using namespace QT_NAMESPACE;
     if (nHandles >= maxHandle || lastValidHandle > maxHandle - nHandles) {
         // Well, that's unlikely :) But we must be sure.
         qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "can not allocate more handles";
-        delegate->error(serviceUuid, QLowEnergyService::OperationError);
+        if (notifier)
+            notifier->CBCentralManagerError(serviceUuid, QLowEnergyService::OperationError);
         return;
     }
 
@@ -550,8 +559,8 @@ using namespace QT_NAMESPACE;
 
     qtService->endHandle = lastValidHandle;
 
-    ObjCStrongReference<CBService> leService(service, true);
-    delegate->serviceDetailsDiscoveryFinished(qtService);
+    if (notifier)
+        emit notifier->serviceDetailsDiscoveryFinished(qtService);
 }
 
 - (void)performNextRequest
@@ -694,28 +703,37 @@ using namespace QT_NAMESPACE;
     }
 }
 
-- (bool)setNotifyValue:(const QByteArray &)value
-        forCharacteristic:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))charHandle
+- (void)setNotifyValue:(const QByteArray &)value
+        forCharacteristic:(QLowEnergyHandle)charHandle
+        onService:(const QBluetoothUuid &)serviceUuid
 {
     using namespace OSXBluetooth;
 
     Q_ASSERT_X(charHandle, Q_FUNC_INFO, "invalid characteristic handle (0)");
-    Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
 
     if (!charMap.contains(charHandle)) {
         qCWarning(QT_BT_OSX) << Q_FUNC_INFO
-                             << "unknown characteristic handle " << charHandle;
-        return false;
+                             << "unknown characteristic handle "
+                             << charHandle;
+        if (notifier) {
+            emit notifier->CBCentralManagerError(serviceUuid,
+                           QLowEnergyService::DescriptorWriteError);
+        }
+        return;
     }
 
     // At the moment we call setNotifyValue _only_ from 'writeDescriptor';
-    // from Qt's API POV it's a descriptor write oprtation and we must report
+    // from Qt's API POV it's a descriptor write operation and we must report
     // it back, so check _now_ that we really have this descriptor.
     const QBluetoothUuid qtUuid(QBluetoothUuid::ClientCharacteristicConfiguration);
     if (![self descriptor:qtUuid forCharacteristic:charMap[charHandle]]) {
         qCWarning(QT_BT_OSX) << Q_FUNC_INFO
                              << "no client characteristic configuration found";
-        return false;
+        if (notifier) {
+            emit notifier->CBCentralManagerError(serviceUuid,
+                           QLowEnergyService::DescriptorWriteError);
+        }
+        return;
     }
 
     LERequest request;
@@ -725,11 +743,10 @@ using namespace QT_NAMESPACE;
 
     requests.enqueue(request);
     [self performNextRequest];
-
-    return true;
 }
 
-- (bool)readCharacteristic:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))charHandle
+- (void)readCharacteristic:(QLowEnergyHandle)charHandle
+        onService:(const QBluetoothUuid &)serviceUuid
 {
     using namespace OSXBluetooth;
 
@@ -739,7 +756,12 @@ using namespace QT_NAMESPACE;
 
     if (!charMap.contains(charHandle)) {
         qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "characteristic: " << charHandle << " not found";
-        return false;
+        if (notifier) {
+            emit notifier->CBCentralManagerError(serviceUuid,
+                           QLowEnergyService::CharacteristicReadError);
+
+        }
+        return;
     }
 
     LERequest request;
@@ -748,12 +770,11 @@ using namespace QT_NAMESPACE;
 
     requests.enqueue(request);
     [self performNextRequest];
-
-    return true;
 }
 
-- (bool)write:(const QT_PREPEND_NAMESPACE(QByteArray) &)value
-        charHandle:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))charHandle
+- (void)write:(const QByteArray &)value
+        charHandle:(QLowEnergyHandle)charHandle
+        onService:(const QBluetoothUuid &)serviceUuid
         withResponse:(bool)withResponse
 {
     using namespace OSXBluetooth;
@@ -763,8 +784,13 @@ using namespace QT_NAMESPACE;
     QT_BT_MAC_AUTORELEASEPOOL;
 
     if (!charMap.contains(charHandle)) {
-        qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "characteristic: " << charHandle << " not found";
-        return false;
+        qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "characteristic: "
+                             << charHandle << " not found";
+        if (notifier) {
+            emit notifier->CBCentralManagerError(serviceUuid,
+                           QLowEnergyService::CharacteristicWriteError);
+        }
+        return;
     }
 
     LERequest request;
@@ -775,11 +801,10 @@ using namespace QT_NAMESPACE;
 
     requests.enqueue(request);
     [self performNextRequest];
-
-    return true;
 }
 
-- (bool)readDescriptor:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))descHandle
+- (void)readDescriptor:(QLowEnergyHandle)descHandle
+        onService:(const QBluetoothUuid &)serviceUuid
 {
     using namespace OSXBluetooth;
 
@@ -788,7 +813,11 @@ using namespace QT_NAMESPACE;
     if (!descMap.contains(descHandle)) {
         qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "handle:"
                              << descHandle << "not found";
-        return false;
+        if (notifier) {
+            emit notifier->CBCentralManagerError(serviceUuid,
+                           QLowEnergyService::DescriptorReadError);
+        }
+        return;
     }
 
     LERequest request;
@@ -797,11 +826,11 @@ using namespace QT_NAMESPACE;
 
     requests.enqueue(request);
     [self performNextRequest];
-
-    return true;
 }
 
-- (bool)write:(const QByteArray &)value descHandle:(QLowEnergyHandle)descHandle
+- (void)write:(const QByteArray &)value
+        descHandle:(QLowEnergyHandle)descHandle
+        onService:(const QBluetoothUuid &)serviceUuid
 {
     using namespace OSXBluetooth;
 
@@ -810,7 +839,11 @@ using namespace QT_NAMESPACE;
     if (!descMap.contains(descHandle)) {
         qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "handle: "
                              << descHandle << " not found";
-        return false;
+        if (notifier) {
+            emit notifier->CBCentralManagerError(serviceUuid,
+                           QLowEnergyService::DescriptorWriteError);
+        }
+        return;
     }
 
     LERequest request;
@@ -820,8 +853,6 @@ using namespace QT_NAMESPACE;
 
     requests.enqueue(request);
     [self performNextRequest];
-
-    return true;
 }
 
 // Aux. methods:
@@ -1039,8 +1070,6 @@ using namespace QT_NAMESPACE;
 
 - (void)centralManagerDidUpdateState:(CBCentralManager *)central
 {
-    Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
-
     using namespace OSXBluetooth;
 
     const CBCentralManagerState state = central.state;
@@ -1055,47 +1084,42 @@ using namespace QT_NAMESPACE;
         return;
     }
 
-    if (disconnectPending) {
-        disconnectPending = false;
-        managerState = OSXBluetooth::CentralManagerIdle;
-        return [self disconnectFromDevice];
-    }
-
     // Let's check some states we do not like first:
     if (state == CBCentralManagerStateUnsupported || state == CBCentralManagerStateUnauthorized) {
         if (managerState == CentralManagerUpdating) {
             // We tried to connect just to realize, LE is not supported. Report this.
             managerState = CentralManagerIdle;
-            delegate->LEnotSupported();
+            if (notifier)
+                emit notifier->LEnotSupported();
         } else {
             // TODO: if we are here, LE _was_ supported and we first managed to update
             // and reset managerState from CentralManagerUpdating.
             managerState = CentralManagerIdle;
-            delegate->error(QLowEnergyController::InvalidBluetoothAdapterError);
+            if (notifier)
+                emit notifier->CBCentralManagerError(QLowEnergyController::InvalidBluetoothAdapterError);
         }
         return;
     }
 
     if (state == CBCentralManagerStatePoweredOff) {
+        managerState = CentralManagerIdle;
         if (managerState == CentralManagerUpdating) {
-            // I've seen this instead of Unsopported on OS X.
-            managerState = CentralManagerIdle;
-            delegate->LEnotSupported();
+            // I've seen this instead of Unsupported on OS X.
+            if (notifier)
+                emit notifier->LEnotSupported();
         } else {
-            managerState = CentralManagerIdle;
             // TODO: we need a better error +
             // what will happen if later the state changes to PoweredOn???
-            delegate->error(QLowEnergyController::InvalidBluetoothAdapterError);
+            if (notifier)
+                emit notifier->CBCentralManagerError(QLowEnergyController::InvalidBluetoothAdapterError);
         }
         return;
     }
 
     if (state == CBCentralManagerStatePoweredOn) {
-        if (managerState == CentralManagerUpdating) {
+        if (managerState == CentralManagerUpdating && !disconnectPending) {
             managerState = CentralManagerIdle;
-            const QLowEnergyController::Error status = [self connectToDevice];
-            if (status != QLowEnergyController::NoError)// An allocation problem?
-                delegate->error(status);
+            [self retrievePeripheralAndConnect];
         }
     } else {
         // We actually handled all known states, but .. Core Bluetooth can change?
@@ -1118,12 +1142,9 @@ using namespace QT_NAMESPACE;
     managerState = OSXBluetooth::CentralManagerIdle;
 
     if (!peripherals || peripherals.count != 1) {
-        Q_ASSERT_X(delegate, Q_FUNC_INFO,
-                   "invalid delegate (null)");
-
         qCDebug(QT_BT_OSX) << Q_FUNC_INFO <<"unexpected number of peripherals (!= 1)";
-
-        delegate->error(QLowEnergyController::UnknownRemoteDeviceError);
+        if (notifier)
+            emit notifier->CBCentralManagerError(QLowEnergyController::UnknownRemoteDeviceError);
     } else {
         peripheral = [static_cast<CBPeripheral *>([peripherals objectAtIndex:0]) retain];
         [self connectToPeripheral];
@@ -1135,15 +1156,14 @@ using namespace QT_NAMESPACE;
     Q_UNUSED(central)
     Q_UNUSED(aPeripheral)
 
-    Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
-
     if (managerState != OSXBluetooth::CentralManagerConnecting) {
         // We called cancel but before disconnected, managed to connect?
         return;
     }
 
     managerState = OSXBluetooth::CentralManagerIdle;
-    delegate->connectSuccess();
+    if (notifier)
+        emit notifier->connected();
 }
 
 - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)aPeripheral
@@ -1153,8 +1173,6 @@ using namespace QT_NAMESPACE;
     Q_UNUSED(aPeripheral)
     Q_UNUSED(error)
 
-    Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
-
     if (managerState != OSXBluetooth::CentralManagerConnecting) {
         // Canceled already.
         return;
@@ -1162,7 +1180,8 @@ using namespace QT_NAMESPACE;
 
     managerState = OSXBluetooth::CentralManagerIdle;
     // TODO: better error mapping is required.
-    delegate->error(QLowEnergyController::UnknownRemoteDeviceError);
+    if (notifier)
+        notifier->CBCentralManagerError(QLowEnergyController::UnknownRemoteDeviceError);
 }
 
 - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)aPeripheral
@@ -1171,19 +1190,18 @@ using namespace QT_NAMESPACE;
     Q_UNUSED(central)
     Q_UNUSED(aPeripheral)
 
-    Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
-
     // Clear internal caches/data.
     [self reset];
 
     if (error && managerState == OSXBluetooth::CentralManagerDisconnecting) {
         managerState = OSXBluetooth::CentralManagerIdle;
         qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "failed to disconnect";
-        // TODO: instead of 'unknown' - .. ?
-        delegate->error(QLowEnergyController::UnknownRemoteDeviceError);
+        if (notifier)
+            emit notifier->CBCentralManagerError(QLowEnergyController::UnknownRemoteDeviceError);
     } else {
         managerState = OSXBluetooth::CentralManagerIdle;
-        delegate->disconnected();
+        if (notifier)
+            emit notifier->disconnected();
     }
 }
 
@@ -1201,10 +1219,10 @@ using namespace QT_NAMESPACE;
     managerState = OSXBluetooth::CentralManagerIdle;
 
     if (error) {
-        // NSLog, not qCDebug/Warning - to print the error.
         NSLog(@"%s failed with error %@", Q_FUNC_INFO, error);
         // TODO: better error mapping required.
-        delegate->error(QLowEnergyController::UnknownError);
+        if (notifier)
+            emit notifier->CBCentralManagerError(QLowEnergyController::UnknownError);
     } else {
         [self discoverIncludedServices];
     }
@@ -1225,14 +1243,11 @@ using namespace QT_NAMESPACE;
 
     QT_BT_MAC_AUTORELEASEPOOL;
 
-    Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
     Q_ASSERT_X(peripheral, Q_FUNC_INFO, "invalid peripheral (nil)");
-    // TODO: asserts on other "pointers" ...
 
     managerState = CentralManagerIdle;
 
     if (error) {
-        // NSLog, not qCWarning/Critical - to log the actual NSError and service UUID.
         NSLog(@"%s: finished with error %@ for service %@",
               Q_FUNC_INFO, error, service.UUID);
     } else if (service.includedServices && service.includedServices.count) {
@@ -1279,8 +1294,8 @@ using namespace QT_NAMESPACE;
     servicesToVisit.reset(nil);
     servicesToVisitNext.reset(nil);
 
-    const ObjCStrongReference<NSArray> services(peripheral.services, true); // true == retain.
-    delegate->serviceDiscoveryFinished(services);
+    if (notifier)
+        emit notifier->serviceDiscoveryFinished();
 }
 
 - (void)peripheral:(CBPeripheral *)aPeripheral didDiscoverCharacteristicsForService:(CBService *)service
@@ -1290,21 +1305,20 @@ using namespace QT_NAMESPACE;
     // discoveries active.
     Q_UNUSED(aPeripheral)
 
-    // TODO: check that this can never be called after cancelPeripheralConnection was executed.
+    if (!notifier) {
+        // Detached.
+        return;
+    }
 
     using namespace OSXBluetooth;
 
-    Q_ASSERT_X(managerState != CentralManagerUpdating,
-               Q_FUNC_INFO, "invalid state");
-    Q_ASSERT_X(delegate, Q_FUNC_INFO,
-               "invalid delegate (null)");
+    Q_ASSERT_X(managerState != CentralManagerUpdating, Q_FUNC_INFO, "invalid state");
 
     if (error) {
-        // NSLog to show the actual NSError (can contain something interesting).
         NSLog(@"%s failed with error: %@", Q_FUNC_INFO, error);
         // We did not discover any characteristics and can not discover descriptors,
         // inform our delegate (it will set a service state also).
-        delegate->error(qt_uuid(service.UUID), QLowEnergyController::UnknownError);
+        emit notifier->CBCentralManagerError(qt_uuid(service.UUID), QLowEnergyController::UnknownError);
     } else {
         [self readCharacteristics:service];
     }
@@ -1316,11 +1330,15 @@ using namespace QT_NAMESPACE;
 {
     Q_UNUSED(aPeripheral)
 
+    if (!notifier) {
+        // Detached.
+        return;
+    }
+
     using namespace OSXBluetooth;
 
     Q_ASSERT_X(managerState != CentralManagerUpdating, Q_FUNC_INFO, "invalid state");
     Q_ASSERT_X(peripheral, Q_FUNC_INFO, "invalid peripheral (nil)");
-    Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
 
     QT_BT_MAC_AUTORELEASEPOOL;
     // First, let's check if we're discovering a service details now.
@@ -1330,13 +1348,12 @@ using namespace QT_NAMESPACE;
     const QLowEnergyHandle chHandle = charMap.key(characteristic);
 
     if (error) {
-        // Use NSLog, not qCDebug/qCWarning to log the actual error.
         NSLog(@"%s failed with error %@", Q_FUNC_INFO, error);
         if (!isDetailsDiscovery) {
             if (chHandle && chHandle == currentReadHandle) {
                 currentReadHandle = 0;
                 requestPending = false;
-                delegate->error(qtUuid, QLowEnergyService::CharacteristicReadError);
+                emit notifier->CBCentralManagerError(qtUuid, QLowEnergyService::CharacteristicReadError);
                 [self performNextRequest];
             }
             return;
@@ -1370,10 +1387,10 @@ using namespace QT_NAMESPACE;
             requestPending = false;
             currentReadHandle = 0;
             //
-            delegate->characteristicReadNotification(chHandle, qt_bytearray(characteristic.value));
+            emit notifier->characteristicRead(chHandle, qt_bytearray(characteristic.value));
             [self performNextRequest];
         } else {
-            delegate->characteristicUpdateNotification(chHandle, qt_bytearray(characteristic.value));
+            emit notifier->characteristicUpdated(chHandle, qt_bytearray(characteristic.value));
         }
     }
 }
@@ -1386,12 +1403,16 @@ using namespace QT_NAMESPACE;
     // have several discoveries active at the same time.
     Q_UNUSED(aPeripheral)
 
+    if (!notifier) {
+        // Detached, no need to continue ...
+        return;
+    }
+
     QT_BT_MAC_AUTORELEASEPOOL;
 
     using namespace OSXBluetooth;
 
     if (error) {
-        // Log the error using NSLog:
         NSLog(@"%s failed with error %@", Q_FUNC_INFO, error);
         // We can continue though ...
     }
@@ -1413,6 +1434,11 @@ using namespace QT_NAMESPACE;
 
     Q_ASSERT_X(peripheral, Q_FUNC_INFO, "invalid peripheral (nil)");
 
+    if (!notifier) {
+        // Detached ...
+        return;
+    }
+
     QT_BT_MAC_AUTORELEASEPOOL;
 
     using namespace OSXBluetooth;
@@ -1423,14 +1449,13 @@ using namespace QT_NAMESPACE;
     const QLowEnergyHandle dHandle = descMap.key(descriptor);
 
     if (error) {
-        // NSLog to log the actual error ...
         NSLog(@"%s failed with error %@", Q_FUNC_INFO, error);
 
         if (!isDetailsDiscovery) {
             if (dHandle && dHandle == currentReadHandle) {
                 currentReadHandle = 0;
                 requestPending = false;
-                delegate->error(qtUuid, QLowEnergyService::DescriptorReadError);
+                emit notifier->CBCentralManagerError(qtUuid, QLowEnergyService::DescriptorReadError);
                 [self performNextRequest];
             }
             return;
@@ -1470,7 +1495,7 @@ using namespace QT_NAMESPACE;
         if (dHandle == currentReadHandle) {
             currentReadHandle = 0;
             requestPending = false;
-            delegate->descriptorReadNotification(dHandle, qt_bytearray(static_cast<NSObject *>(descriptor.value)));
+            emit notifier->descriptorRead(dHandle, qt_bytearray(static_cast<NSObject *>(descriptor.value)));
             [self performNextRequest];
         }
     }
@@ -1483,6 +1508,11 @@ using namespace QT_NAMESPACE;
     Q_UNUSED(aPeripheral)
     Q_UNUSED(characteristic)
 
+    if (!notifier) {
+        // Detached.
+        return;
+    }
+
     // From docs:
     //
     // "This method is invoked only when your app calls the writeValue:forCharacteristic:type:
@@ -1496,8 +1526,6 @@ using namespace QT_NAMESPACE;
 
     requestPending = false;
 
-    Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
-
 
     // Error or not, but the cached value has to be deleted ...
     const QByteArray valueToReport(valuesToWrite.value(characteristic, QByteArray()));
@@ -1507,15 +1535,12 @@ using namespace QT_NAMESPACE;
     }
 
     if (error) {
-        // Use NSLog to log the actual error:
         NSLog(@"%s failed with error %@", Q_FUNC_INFO, error);
-        delegate->error(qt_uuid(characteristic.service.UUID),
-                        QLowEnergyService::CharacteristicWriteError);
+        emit notifier->CBCentralManagerError(qt_uuid(characteristic.service.UUID),
+                                             QLowEnergyService::CharacteristicWriteError);
     } else {
-        // Keys are unique.
         const QLowEnergyHandle cHandle = charMap.key(characteristic);
-        Q_ASSERT_X(cHandle, Q_FUNC_INFO, "invalid handle, not found in the characteristics map");
-        delegate->characteristicWriteNotification(cHandle, valueToReport);
+        emit notifier->characteristicWritten(cHandle, valueToReport);
     }
 
     [self performNextRequest];
@@ -1527,7 +1552,10 @@ using namespace QT_NAMESPACE;
 {
     Q_UNUSED(aPeripheral)
 
-    Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (null)");
+    if (!notifier) {
+        // Detached already.
+        return;
+    }
 
     using namespace OSXBluetooth;
 
@@ -1535,23 +1563,20 @@ using namespace QT_NAMESPACE;
 
     requestPending = false;
 
-    using namespace OSXBluetooth;
-
     // Error or not, a value (if any) must be removed.
     const QByteArray valueToReport(valuesToWrite.value(descriptor, QByteArray()));
     if (!valuesToWrite.remove(descriptor))
         qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "no updated value found";
 
     if (error) {
-        // NSLog to log the actual NSError:
         NSLog(@"%s failed with error %@", Q_FUNC_INFO, error);
-        delegate->error(qt_uuid(descriptor.characteristic.service.UUID),
-                        QLowEnergyService::DescriptorWriteError);
+        emit notifier->CBCentralManagerError(qt_uuid(descriptor.characteristic.service.UUID),
+                       QLowEnergyService::DescriptorWriteError);
     } else {
         const QLowEnergyHandle dHandle = descMap.key(descriptor);
         Q_ASSERT_X(dHandle, Q_FUNC_INFO,
                    "descriptor not found in the descriptors map");
-        delegate->descriptorWriteNotification(dHandle, valueToReport);
+        emit notifier->descriptorWritten(dHandle, valueToReport);
     }
 
     [self performNextRequest];
@@ -1563,40 +1588,42 @@ using namespace QT_NAMESPACE;
 {
     Q_UNUSED(aPeripheral)
 
+    if (!notifier)
+        return;
+
     using namespace OSXBluetooth;
 
     QT_BT_MAC_AUTORELEASEPOOL;
 
     requestPending = false;
 
-    Q_ASSERT_X(delegate, Q_FUNC_INFO, "invalid delegate (nil)");
-
     const QBluetoothUuid qtUuid(QBluetoothUuid::ClientCharacteristicConfiguration);
     CBDescriptor *const descriptor = [self descriptor:qtUuid forCharacteristic:characteristic];
     const QByteArray valueToReport(valuesToWrite.value(descriptor, QByteArray()));
     const int nRemoved = valuesToWrite.remove(descriptor);
 
     if (error) {
-        // NSLog to log the actual NSError:
         NSLog(@"%s failed with error %@", Q_FUNC_INFO, error);
-        delegate->error(qt_uuid(characteristic.service.UUID),
-                        // In Qt's API it's a descriptor write actually.
-                        QLowEnergyService::DescriptorWriteError);
-    } else {
-        if (nRemoved) {
-            const QLowEnergyHandle dHandle = descMap.key(descriptor);
-            delegate->descriptorWriteNotification(dHandle, valueToReport);
-        } else {
-            /*
-            qCWarning(QT_BT_OSX) << Q_FUNC_INFO << ": notification value set to "
-                                 << int(characteristic.isNotifying)
-                                 << " but no client characteristic configuration descriptor found"
-                                    " or no previous writeDescriptor request found";
-            */
-        }
+        // In Qt's API it's a descriptor write actually.
+        emit notifier->CBCentralManagerError(qt_uuid(characteristic.service.UUID),
+                                             QLowEnergyService::DescriptorWriteError);
+    } else if (nRemoved) {
+        const QLowEnergyHandle dHandle = descMap.key(descriptor);
+        emit notifier->descriptorWritten(dHandle, valueToReport);
     }
 
     [self performNextRequest];
 }
 
+- (void)detach
+{
+    if (notifier) {
+        notifier->disconnect();
+        notifier->deleteLater();
+        notifier = 0;
+    }
+
+    [self disconnectFromDevice];
+}
+
 @end
diff --git a/src/bluetooth/osx/osxbtcentralmanager_p.h b/src/bluetooth/osx/osxbtcentralmanager_p.h
index 429bae91358829cb3cdbe3ec2f280b30853bcc20..1ff33c127827520a3121a92cf32eebedec968a14 100644
--- a/src/bluetooth/osx/osxbtcentralmanager_p.h
+++ b/src/bluetooth/osx/osxbtcentralmanager_p.h
@@ -69,41 +69,7 @@ class QLowEnergyServicePrivate;
 
 namespace OSXBluetooth {
 
-class CentralManagerDelegate
-{
-public:
-    typedef QT_MANGLE_NAMESPACE(OSXBTCentralManager) ObjCCentralManager;
-    typedef ObjCStrongReference<NSArray> LEServices;
-    typedef QSharedPointer<QLowEnergyServicePrivate> LEService;
-    typedef ObjCStrongReference<CBCharacteristic> LECharacteristic;
-
-    virtual ~CentralManagerDelegate();
-
-    virtual void LEnotSupported() = 0;
-    virtual void connectSuccess() = 0;
-    virtual void serviceDiscoveryFinished(LEServices services) = 0;
-    virtual void serviceDetailsDiscoveryFinished(LEService service) = 0;
-    virtual void characteristicReadNotification(QLowEnergyHandle charHandle,
-                                                const QByteArray &value) = 0;
-    virtual void characteristicWriteNotification(QLowEnergyHandle charHandle,
-                                                 const QByteArray &value) = 0;
-    virtual void characteristicUpdateNotification(QLowEnergyHandle charHandle,
-                                                  const QByteArray &value) = 0;
-    virtual void descriptorReadNotification(QLowEnergyHandle descHandle,
-                                            const QByteArray &value) = 0;
-    virtual void descriptorWriteNotification(QLowEnergyHandle descHandle,
-                                             const QByteArray &value) = 0;
-    virtual void disconnected() = 0;
-
-    // General errors.
-    virtual void error(QLowEnergyController::Error error) = 0;
-    // Service related errors.
-    virtual void error(const QBluetoothUuid &serviceUuid,
-                       QLowEnergyController::Error error) = 0;
-    // Characteristics/descriptors related errors.
-    virtual void error(const QBluetoothUuid &serviceUuid,
-                       QLowEnergyService::ServiceError error) = 0;
-};
+class LECentralNotifier;
 
 enum CentralManagerState
 {
@@ -126,8 +92,8 @@ typedef QHash<QLowEnergyHandle, CBService *> ServiceHash;
 typedef QHash<QLowEnergyHandle, CBCharacteristic *> CharHash;
 typedef QHash<QLowEnergyHandle, CBDescriptor *> DescHash;
 
-// Descriptor/charactesirsti read/write requests
-// - we have to serialize 'concurrent' write requests.
+// Descriptor/charactesirstic read/write requests
+// - we have to serialize 'concurrent' requests.
 struct LERequest {
     enum RequestType {
         CharRead,
@@ -165,14 +131,14 @@ QT_END_NAMESPACE
 
 @interface QT_MANGLE_NAMESPACE(OSXBTCentralManager) : NSObject<CBCentralManagerDelegate, CBPeripheralDelegate>
 {
+@private
     CBCentralManager *manager;
     QT_PREPEND_NAMESPACE(OSXBluetooth)::CentralManagerState managerState;
     bool disconnectPending;
 
     QT_PREPEND_NAMESPACE(QBluetoothUuid) deviceUuid;
-    CBPeripheral *peripheral;
 
-    QT_PREPEND_NAMESPACE(OSXBluetooth)::CentralManagerDelegate *delegate;
+    QT_PREPEND_NAMESPACE(OSXBluetooth)::LECentralNotifier *notifier;
 
     // Quite a verbose service discovery machinery
     // (a "graph traversal").
@@ -197,32 +163,43 @@ QT_END_NAMESPACE
     QT_PREPEND_NAMESPACE(QLowEnergyHandle) currentReadHandle;
 
     QT_PREPEND_NAMESPACE(OSXBluetooth)::ValueHash valuesToWrite;
+@public
+    CBPeripheral *peripheral;
 }
 
-- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth)::CentralManagerDelegate *)aDelegate;
+- (id)initWith:(QT_PREPEND_NAMESPACE(OSXBluetooth)::LECentralNotifier *)notifier;
 - (void)dealloc;
 
-- (QT_PREPEND_NAMESPACE(QLowEnergyController)::Error)
-    connectToDevice:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)aDeviceUuid;
+// IMPORTANT: _all_ these methods are to be executed on qt_LE_queue,
+// when passing parameters - C++ objects _must_ be copied (see the controller's code).
+- (void)connectToDevice:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)aDeviceUuid;
 
 - (void)disconnectFromDevice;
 
 - (void)discoverServices;
-- (bool)discoverServiceDetails:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)serviceUuid;
+- (void)discoverServiceDetails:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)serviceUuid;
 
-- (bool)setNotifyValue:(const QT_PREPEND_NAMESPACE(QByteArray) &)value
-        forCharacteristic:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))charHandle;
+- (void)setNotifyValue:(const QT_PREPEND_NAMESPACE(QByteArray) &)value
+        forCharacteristic:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))charHandle
+        onService:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)serviceUuid;
 
-- (bool)readCharacteristic:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))charHandle;
+- (void)readCharacteristic:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))charHandle
+        onService:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)serviceUuid;
 
-- (bool)write:(const QT_PREPEND_NAMESPACE(QByteArray) &)value
+- (void)write:(const QT_PREPEND_NAMESPACE(QByteArray) &)value
         charHandle:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))charHandle
+        onService:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)serviceUuid
         withResponse:(bool)writeWithResponse;
 
-- (bool)readDescriptor:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))descHandle;
+- (void)readDescriptor:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))descHandle
+        onService:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)serviceUuid;
+
+- (void)write:(const QT_PREPEND_NAMESPACE(QByteArray) &)value
+        descHandle:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))descHandle
+        onService:(const QT_PREPEND_NAMESPACE(QBluetoothUuid) &)serviceUuid;
+
+- (void)detach;
 
-- (bool)write:(const QT_PREPEND_NAMESPACE(QByteArray) &)value
-        descHandle:(QT_PREPEND_NAMESPACE(QLowEnergyHandle))descHandle;
 @end
 
 #endif
diff --git a/src/bluetooth/osx/osxbtnotifier.cpp b/src/bluetooth/osx/osxbtnotifier.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0e0343cfc23a1f59cb2ffda457741fbc252a11c3
--- /dev/null
+++ b/src/bluetooth/osx/osxbtnotifier.cpp
@@ -0,0 +1 @@
+#include "osxbtnotifier_p.h"
diff --git a/src/bluetooth/osx/osxbtnotifier_p.h b/src/bluetooth/osx/osxbtnotifier_p.h
new file mode 100644
index 0000000000000000000000000000000000000000..7b4d18e47f65f7b0c04059878f25f9dcc4ec5cce
--- /dev/null
+++ b/src/bluetooth/osx/osxbtnotifier_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtBluetooth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** 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 The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OSXBTNOTIFIER_P_H
+#define OSXBTNOTIFIER_P_H
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists purely as an
+// implementation detail.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#include "qlowenergycontroller.h"
+#include "qbluetoothuuid.h"
+#include "qbluetooth.h"
+
+#include <QtCore/qsharedpointer.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qglobal.h>
+#include <QtCore/qobject.h>
+
+QT_BEGIN_NAMESPACE
+
+class QLowEnergyServicePrivate;
+
+namespace OSXBluetooth
+{
+
+class LECentralNotifier : public QObject
+{
+    Q_OBJECT
+
+Q_SIGNALS:
+    void connected();
+    void disconnected();
+
+    void serviceDiscoveryFinished();
+    void serviceDetailsDiscoveryFinished(QSharedPointer<QLowEnergyServicePrivate> service);
+    void characteristicRead(QLowEnergyHandle charHandle, const QByteArray &value);
+    void characteristicWritten(QLowEnergyHandle charHandle, const QByteArray &value);
+    void characteristicUpdated(QLowEnergyHandle charHandle, const QByteArray &value);
+    void descriptorRead(QLowEnergyHandle descHandle, const QByteArray &value);
+    void descriptorWritten(QLowEnergyHandle descHandle, const QByteArray &value);
+
+    void LEnotSupported();
+    void CBCentralManagerError(QLowEnergyController::Error error);
+    void CBCentralManagerError(const QBluetoothUuid &serviceUuid, QLowEnergyController::Error error);
+    void CBCentralManagerError(const QBluetoothUuid &serviceUuid, QLowEnergyService::ServiceError error);
+
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/bluetooth/osx/osxbtobexsession_p.h b/src/bluetooth/osx/osxbtobexsession_p.h
index ac2699cfbefa46e4be79f5ae03968502ea701d37..0e72ecea5e176e31e455e37a47111fef23478a4e 100644
--- a/src/bluetooth/osx/osxbtobexsession_p.h
+++ b/src/bluetooth/osx/osxbtobexsession_p.h
@@ -31,6 +31,17 @@
 **
 ****************************************************************************/
 
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists purely as an
+// implementation detail.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
 #include <QtCore/qvariant.h>
 #include <QtCore/qglobal.h>
 
diff --git a/src/bluetooth/qbluetoothserviceinfo.cpp b/src/bluetooth/qbluetoothserviceinfo.cpp
index fefb2549bfd54d079848e5ea36081a2e0017284d..f41f1e7970ec6c9bba82a13ff85109e1335582f7 100644
--- a/src/bluetooth/qbluetoothserviceinfo.cpp
+++ b/src/bluetooth/qbluetoothserviceinfo.cpp
@@ -548,6 +548,7 @@ static void dumpAttributeVariant(const QVariant &var, const QString indent)
         break;
     case QMetaType::UShort:
         qDebug("%sushort %u", indent.toLocal8Bit().constData(), var.toUInt());
+        break;
     case QMetaType::UInt:
         qDebug("%suint %u", indent.toLocal8Bit().constData(), var.toUInt());
         break;
diff --git a/src/bluetooth/qbluetoothtransferreply.cpp b/src/bluetooth/qbluetoothtransferreply.cpp
index e0d30a6055d4f2d474274035f7ab52dafa6c6ea1..9c5d976d81a1e838d82f32a9a028a766fa927fa5 100644
--- a/src/bluetooth/qbluetoothtransferreply.cpp
+++ b/src/bluetooth/qbluetoothtransferreply.cpp
@@ -200,6 +200,7 @@ void QBluetoothTransferReply::setRequest(const QBluetoothTransferRequest &reques
 */
 
 QBluetoothTransferReplyPrivate::QBluetoothTransferReplyPrivate()
+    : m_manager(0)
 {
 }
 
diff --git a/src/bluetooth/qlowenergycontroller_android.cpp b/src/bluetooth/qlowenergycontroller_android.cpp
index 767c91f8815ca1f656e34014a94b55dc4e20a884..fd4ea753c048b4bab5685f4ac18ded7e7a065e83 100644
--- a/src/bluetooth/qlowenergycontroller_android.cpp
+++ b/src/bluetooth/qlowenergycontroller_android.cpp
@@ -263,7 +263,7 @@ void QLowEnergyControllerPrivate::readCharacteristic(
     }
 
     if (!result)
-        service->setError(QLowEnergyService::CharacteristicWriteError);
+        service->setError(QLowEnergyService::CharacteristicReadError);
 }
 
 void QLowEnergyControllerPrivate::readDescriptor(
@@ -289,7 +289,7 @@ void QLowEnergyControllerPrivate::readDescriptor(
     }
 
     if (!result)
-        service->setError(QLowEnergyService::DescriptorWriteError);
+        service->setError(QLowEnergyService::DescriptorReadError);
 }
 
 void QLowEnergyControllerPrivate::connectionUpdated(
diff --git a/src/bluetooth/qlowenergycontroller_osx.mm b/src/bluetooth/qlowenergycontroller_osx.mm
index 396f82bbb9721dc495368e694ff5b84844411dba..e38442e2bc1381731552b170b949e2b03d99c6ad 100644
--- a/src/bluetooth/qlowenergycontroller_osx.mm
+++ b/src/bluetooth/qlowenergycontroller_osx.mm
@@ -62,6 +62,8 @@ static void registerQLowEnergyControllerMetaType()
     if (!initDone) {
         qRegisterMetaType<QLowEnergyController::ControllerState>();
         qRegisterMetaType<QLowEnergyController::Error>();
+        qRegisterMetaType<QLowEnergyHandle>("QLowEnergyHandle");
+        qRegisterMetaType<QSharedPointer<QLowEnergyServicePrivate> >();
         initDone = true;
     }
 }
@@ -139,12 +141,23 @@ QLowEnergyControllerPrivateOSX::QLowEnergyControllerPrivateOSX(QLowEnergyControl
 
     // This is the "wrong" constructor - no valid device UUID to connect later.
     Q_ASSERT_X(q, Q_FUNC_INFO, "invalid q_ptr (null)");
+
+    using OSXBluetooth::LECentralNotifier;
+
     // We still create a manager, to simplify error handling later.
-    centralManager.reset([[ObjCCentralManager alloc] initWithDelegate:this]);
+    QScopedPointer<LECentralNotifier> notifier(new LECentralNotifier);
+    centralManager.reset([[ObjCCentralManager alloc] initWith:notifier.data()]);
     if (!centralManager) {
         qCWarning(QT_BT_OSX) << Q_FUNC_INFO
                              << "failed to initialize central manager";
+        return;
+    } else if (!connectSlots(notifier.data())) {
+        qCWarning(QT_BT_OSX) << Q_FUNC_INFO
+                             << "failed to connect to notifier's signals";
     }
+
+    // Ownership was taken by central manager.
+    notifier.take();
 }
 
 QLowEnergyControllerPrivateOSX::QLowEnergyControllerPrivateOSX(QLowEnergyController *q,
@@ -160,33 +173,41 @@ QLowEnergyControllerPrivateOSX::QLowEnergyControllerPrivateOSX(QLowEnergyControl
     registerQLowEnergyControllerMetaType();
 
     Q_ASSERT_X(q, Q_FUNC_INFO, "invalid q_ptr (null)");
-    centralManager.reset([[ObjCCentralManager alloc] initWithDelegate:this]);
+
+    using OSXBluetooth::LECentralNotifier;
+
+    QScopedPointer<LECentralNotifier> notifier(new LECentralNotifier);
+    centralManager.reset([[ObjCCentralManager alloc] initWith:notifier.data()]);
     if (!centralManager) {
         qCWarning(QT_BT_OSX) << Q_FUNC_INFO
                              << "failed to initialize central manager";
+        return;
+    } else if (!connectSlots(notifier.data())) {
+        qCWarning(QT_BT_OSX) << Q_FUNC_INFO
+                             << "failed to connect to notifier's signals";
     }
+
+    // Ownership was taken by central manager.
+    notifier.take();
 }
 
 QLowEnergyControllerPrivateOSX::~QLowEnergyControllerPrivateOSX()
 {
+    // TODO: dispatch_sync 'setDelegate:Q_NULLPRT' to our CBCentralManager's delegate.
+    if (dispatch_queue_t leQueue = OSXBluetooth::qt_LE_queue()) {
+        ObjCCentralManager *manager = centralManager.data();
+        dispatch_sync(leQueue, ^{
+            [manager detach];
+        });
+    }
 }
 
 bool QLowEnergyControllerPrivateOSX::isValid() const
 {
-    // isValid means only "was able to allocate all resources",
-    // nothing more.
     return centralManager;
 }
 
-void QLowEnergyControllerPrivateOSX::LEnotSupported()
-{
-    // Report as an error. But this should not be possible
-    // actually: before connecting to any device, we have
-    // to discover it, if it was discovered ... LE _must_
-    // be supported.
-}
-
-void QLowEnergyControllerPrivateOSX::connectSuccess()
+void QLowEnergyControllerPrivateOSX::_q_connected()
 {
     Q_ASSERT_X(controllerState == QLowEnergyController::ConnectingState,
                Q_FUNC_INFO, "invalid state");
@@ -199,7 +220,17 @@ void QLowEnergyControllerPrivateOSX::connectSuccess()
     }
 }
 
-void QLowEnergyControllerPrivateOSX::serviceDiscoveryFinished(LEServices services)
+void QLowEnergyControllerPrivateOSX::_q_disconnected()
+{
+    controllerState = QLowEnergyController::UnconnectedState;
+
+    if (!isConnecting) {
+        emit q_ptr->stateChanged(QLowEnergyController::UnconnectedState);
+        emit q_ptr->disconnected();
+    }
+}
+
+void QLowEnergyControllerPrivateOSX::_q_serviceDiscoveryFinished()
 {
     Q_ASSERT_X(controllerState == QLowEnergyController::DiscoveringState,
                Q_FUNC_INFO, "invalid state");
@@ -208,6 +239,7 @@ void QLowEnergyControllerPrivateOSX::serviceDiscoveryFinished(LEServices service
 
     QT_BT_MAC_AUTORELEASEPOOL;
 
+    NSArray *const services = centralManager.data()->peripheral.services;
     // Now we have to traverse the discovered services tree.
     // Essentially it's an iterative version of more complicated code from the
     // OSXBTCentralManager's code.
@@ -218,7 +250,7 @@ void QLowEnergyControllerPrivateOSX::serviceDiscoveryFinished(LEServices service
         //   during the pass 2); we also ignore duplicates (== services with the same UUID)
         // - since we do not have a way to distinguish them later
         //   (our API is using uuids when creating QLowEnergyServices).
-        for (CBService *cbService in services.data()) {
+        for (CBService *cbService in services) {
             const ServicePrivate newService(qt_createLEService(this, cbService, false));
             if (!newService.data())
                 continue;
@@ -281,7 +313,6 @@ void QLowEnergyControllerPrivateOSX::serviceDiscoveryFinished(LEServices service
 
     for (ServiceMap::const_iterator it = discoveredServices.constBegin(); it != discoveredServices.constEnd(); ++it) {
         const QBluetoothUuid &uuid = it.key();
-
         QMetaObject::invokeMethod(q_ptr, "serviceDiscovered", Qt::QueuedConnection,
                                  Q_ARG(QBluetoothUuid, uuid));
     }
@@ -292,12 +323,12 @@ void QLowEnergyControllerPrivateOSX::serviceDiscoveryFinished(LEServices service
     QMetaObject::invokeMethod(q_ptr, "discoveryFinished", Qt::QueuedConnection);
 }
 
-void QLowEnergyControllerPrivateOSX::serviceDetailsDiscoveryFinished(LEService service)
+void QLowEnergyControllerPrivateOSX::_q_serviceDetailsDiscoveryFinished(QSharedPointer<QLowEnergyServicePrivate> service)
 {
-    Q_ASSERT_X(!service.isNull(), Q_FUNC_INFO, "invalid service (null)");
-
     QT_BT_MAC_AUTORELEASEPOOL;
 
+    Q_ASSERT(service);
+
     if (!discoveredServices.contains(service->uuid)) {
         qCDebug(QT_BT_OSX) << Q_FUNC_INFO << "unknown service uuid: "
                            << service->uuid;
@@ -313,8 +344,8 @@ void QLowEnergyControllerPrivateOSX::serviceDetailsDiscoveryFinished(LEService s
     qtService->setState(QLowEnergyService::ServiceDiscovered);
 }
 
-void QLowEnergyControllerPrivateOSX::characteristicReadNotification(QLowEnergyHandle charHandle,
-                                                                    const QByteArray &value)
+void QLowEnergyControllerPrivateOSX::_q_characteristicRead(QLowEnergyHandle charHandle,
+                                                           const QByteArray &value)
 {
     Q_ASSERT_X(charHandle, Q_FUNC_INFO, "invalid characteristic handle(0)");
 
@@ -334,8 +365,8 @@ void QLowEnergyControllerPrivateOSX::characteristicReadNotification(QLowEnergyHa
     emit service->characteristicRead(characteristic, value);
 }
 
-void QLowEnergyControllerPrivateOSX::characteristicWriteNotification(QLowEnergyHandle charHandle,
-                                                                     const QByteArray &value)
+void QLowEnergyControllerPrivateOSX::_q_characteristicWritten(QLowEnergyHandle charHandle,
+                                                              const QByteArray &value)
 {
     Q_ASSERT_X(charHandle, Q_FUNC_INFO, "invalid characteristic handle(0)");
 
@@ -358,8 +389,8 @@ void QLowEnergyControllerPrivateOSX::characteristicWriteNotification(QLowEnergyH
     emit service->characteristicWritten(characteristic, value);
 }
 
-void QLowEnergyControllerPrivateOSX::characteristicUpdateNotification(QLowEnergyHandle charHandle,
-                                                                     const QByteArray &value)
+void QLowEnergyControllerPrivateOSX::_q_characteristicUpdated(QLowEnergyHandle charHandle,
+                                                              const QByteArray &value)
 {
     // TODO: write/update notifications are quite similar (except asserts/warnings messages
     // and different signals emitted). Merge them into one function?
@@ -387,7 +418,8 @@ void QLowEnergyControllerPrivateOSX::characteristicUpdateNotification(QLowEnergy
     emit service->characteristicChanged(characteristic, value);
 }
 
-void QLowEnergyControllerPrivateOSX::descriptorReadNotification(QLowEnergyHandle dHandle, const QByteArray &value)
+void QLowEnergyControllerPrivateOSX::_q_descriptorRead(QLowEnergyHandle dHandle,
+                                                       const QByteArray &value)
 {
     Q_ASSERT_X(dHandle, Q_FUNC_INFO, "invalid descriptor handle (0)");
 
@@ -402,7 +434,8 @@ void QLowEnergyControllerPrivateOSX::descriptorReadNotification(QLowEnergyHandle
     emit service->descriptorRead(qtDescriptor, value);
 }
 
-void QLowEnergyControllerPrivateOSX::descriptorWriteNotification(QLowEnergyHandle dHandle, const QByteArray &value)
+void QLowEnergyControllerPrivateOSX::_q_descriptorWritten(QLowEnergyHandle dHandle,
+                                                          const QByteArray &value)
 {
     Q_ASSERT_X(dHandle, Q_FUNC_INFO, "invalid descriptor handle (0)");
 
@@ -418,29 +451,18 @@ void QLowEnergyControllerPrivateOSX::descriptorWriteNotification(QLowEnergyHandl
     emit service->descriptorWritten(qtDescriptor, value);
 }
 
-void QLowEnergyControllerPrivateOSX::disconnected()
+void QLowEnergyControllerPrivateOSX::_q_LEnotSupported()
 {
-    controllerState = QLowEnergyController::UnconnectedState;
-
-    if (!isConnecting) {
-        emit q_ptr->stateChanged(QLowEnergyController::UnconnectedState);
-        emit q_ptr->disconnected();
-    }
+    // Report as an error. But this should not be possible
+    // actually: before connecting to any device, we have
+    // to discover it, if it was discovered ... LE _must_
+    // be supported.
 }
 
-void QLowEnergyControllerPrivateOSX::error(QLowEnergyController::Error errorCode)
+void QLowEnergyControllerPrivateOSX::_q_CBCentralManagerError(QLowEnergyController::Error errorCode)
 {
     // Errors reported during connect and general errors.
 
-    // We're still in connectToDevice,
-    // some error was reported synchronously.
-    // Return, the error will be correctly set later
-    // by connectToDevice.
-    if (isConnecting) {
-        lastError = errorCode;
-        return;
-    }
-
     setErrorDescription(errorCode);
     emit q_ptr->error(lastError);
 
@@ -454,8 +476,8 @@ void QLowEnergyControllerPrivateOSX::error(QLowEnergyController::Error errorCode
       // a service/characteristic - related error.
 }
 
-void QLowEnergyControllerPrivateOSX::error(const QBluetoothUuid &serviceUuid,
-                                           QLowEnergyController::Error errorCode)
+void QLowEnergyControllerPrivateOSX::_q_CBCentralManagerError(const QBluetoothUuid &serviceUuid,
+                                                              QLowEnergyController::Error errorCode)
 {
     // Errors reported while discovering service details etc.
     Q_UNUSED(errorCode) // TODO: setError?
@@ -470,8 +492,8 @@ void QLowEnergyControllerPrivateOSX::error(const QBluetoothUuid &serviceUuid,
     }
 }
 
-void QLowEnergyControllerPrivateOSX::error(const QBluetoothUuid &serviceUuid,
-                                           QLowEnergyService::ServiceError errorCode)
+void QLowEnergyControllerPrivateOSX::_q_CBCentralManagerError(const QBluetoothUuid &serviceUuid,
+                                                              QLowEnergyService::ServiceError errorCode)
 {
     if (!discoveredServices.contains(serviceUuid)) {
         qCDebug(QT_BT_OSX) << Q_FUNC_INFO << "unknown service uuid: "
@@ -493,30 +515,21 @@ void QLowEnergyControllerPrivateOSX::connectToDevice()
     Q_ASSERT_X(!isConnecting, Q_FUNC_INFO,
                "recursive connectToDevice call");
 
-    setErrorDescription(QLowEnergyController::NoError);
+    dispatch_queue_t leQueue(OSXBluetooth::qt_LE_queue());
+    if (!leQueue) {
+        qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "no LE queue found";
+        setErrorDescription(QLowEnergyController::UnknownError);
+        return;
+    }
 
-    isConnecting = true;// Do not emit signals if some callback is executed synchronously.
+    setErrorDescription(QLowEnergyController::NoError);
     controllerState = QLowEnergyController::ConnectingState;
-    const QLowEnergyController::Error status = [centralManager connectToDevice:deviceUuid];
-    isConnecting = false;
 
-    if (status == QLowEnergyController::NoError && lastError == QLowEnergyController::NoError) {
-        emit q_ptr->stateChanged(controllerState);
-        if (controllerState == QLowEnergyController::ConnectedState) {
-            // If a peripheral is connected already from the Core Bluetooth's
-            // POV:
-            emit q_ptr->connected();
-        } else if (controllerState == QLowEnergyController::UnconnectedState) {
-            // Ooops, tried to connect, got peripheral disconnect instead -
-            // this happens with Core Bluetooth.
-            emit q_ptr->disconnected();
-        }
-    } else if (status != QLowEnergyController::NoError) {
-        error(status);
-    } else {
-        // Re-set the error/description and emit.
-        error(lastError);
-    }
+    const QBluetoothUuid deviceUuidCopy(deviceUuid);
+    ObjCCentralManager *manager = centralManager.data();
+    dispatch_async(leQueue, ^{
+        [manager connectToDevice:deviceUuidCopy];
+    });
 }
 
 void QLowEnergyControllerPrivateOSX::discoverServices()
@@ -525,9 +538,20 @@ void QLowEnergyControllerPrivateOSX::discoverServices()
     Q_ASSERT_X(controllerState != QLowEnergyController::UnconnectedState,
                Q_FUNC_INFO, "not connected to peripheral");
 
+    dispatch_queue_t leQueue(OSXBluetooth::qt_LE_queue());
+    if (!leQueue) {
+        qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "no LE queue found";
+        setErrorDescription(QLowEnergyController::UnknownError);
+        return;
+    }
+
     controllerState = QLowEnergyController::DiscoveringState;
     emit q_ptr->stateChanged(QLowEnergyController::DiscoveringState);
-    [centralManager discoverServices];
+
+    ObjCCentralManager *manager = centralManager.data();
+    dispatch_async(leQueue, ^{
+        [manager discoverServices];
+    });
 }
 
 void QLowEnergyControllerPrivateOSX::discoverServiceDetails(const QBluetoothUuid &serviceUuid)
@@ -546,14 +570,20 @@ void QLowEnergyControllerPrivateOSX::discoverServiceDetails(const QBluetoothUuid
         return;
     }
 
-    ServicePrivate qtService(discoveredServices.value(serviceUuid));
-    if ([centralManager discoverServiceDetails:serviceUuid]) {
-        qtService->setState(QLowEnergyService::DiscoveringServices);
-    } else {
-        // The error is returned by CentralManager - no
-        // service with a given UUID found on a peripheral.
-        qtService->setState(QLowEnergyService::InvalidService);
+    dispatch_queue_t leQueue(OSXBluetooth::qt_LE_queue());
+    if (!leQueue) {
+        qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "no LE queue found";
+        return;
     }
+
+    ServicePrivate qtService(discoveredServices.value(serviceUuid));
+    qtService->setState(QLowEnergyService::DiscoveringServices);
+    // Copy objects ...
+    ObjCCentralManager *manager = centralManager.data();
+    const QBluetoothUuid serviceUuidCopy(serviceUuid);
+    dispatch_async(leQueue, ^{
+        [manager discoverServiceDetails:serviceUuidCopy];
+    });
 }
 
 void QLowEnergyControllerPrivateOSX::setNotifyValue(QSharedPointer<QLowEnergyServicePrivate> service,
@@ -586,8 +616,19 @@ void QLowEnergyControllerPrivateOSX::setNotifyValue(QSharedPointer<QLowEnergySer
         return;
     }
 
-    if (![centralManager setNotifyValue:newValue forCharacteristic:charHandle])
-        service->setError(QLowEnergyService::DescriptorWriteError);
+    dispatch_queue_t leQueue(OSXBluetooth::qt_LE_queue());
+    if (!leQueue) {
+        qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "no LE queue found";
+        return;
+    }
+    ObjCCentralManager *manager = centralManager.data();
+    const QBluetoothUuid serviceUuid(service->uuid);
+    const QByteArray newValueCopy(newValue);
+    dispatch_async(leQueue, ^{
+        [manager setNotifyValue:newValueCopy
+                 forCharacteristic:charHandle
+                 onService:serviceUuid];
+    });
 }
 
 void QLowEnergyControllerPrivateOSX::readCharacteristic(QSharedPointer<QLowEnergyServicePrivate> service,
@@ -608,8 +649,17 @@ void QLowEnergyControllerPrivateOSX::readCharacteristic(QSharedPointer<QLowEnerg
         return;
     }
 
-    if (![centralManager readCharacteristic:charHandle])
-        service->setError(QLowEnergyService::CharacteristicReadError);
+    dispatch_queue_t leQueue(OSXBluetooth::qt_LE_queue());
+    if (!leQueue) {
+        qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "no LE queue found";
+        return;
+    }
+    // Attention! We have to copy UUID.
+    ObjCCentralManager *manager = centralManager.data();
+    const QBluetoothUuid serviceUuid(service->uuid);
+    dispatch_async(leQueue, ^{
+        [manager readCharacteristic:charHandle onService:serviceUuid];
+    });
 }
 
 void QLowEnergyControllerPrivateOSX::writeCharacteristic(QSharedPointer<QLowEnergyServicePrivate> service,
@@ -634,11 +684,21 @@ void QLowEnergyControllerPrivateOSX::writeCharacteristic(QSharedPointer<QLowEner
         return;
     }
 
-    const bool result = [centralManager write:newValue
-                                        charHandle:charHandle
-                                        withResponse:writeWithResponse];
-    if (!result)
-        service->setError(QLowEnergyService::CharacteristicWriteError);
+    dispatch_queue_t leQueue(OSXBluetooth::qt_LE_queue());
+    if (!leQueue) {
+        qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "no LE queue found";
+        return;
+    }
+    // Attention! Copy objects!
+    const QBluetoothUuid serviceUuid(service->uuid);
+    const QByteArray newValueCopy(newValue);
+    ObjCCentralManager *const manager = centralManager.data();
+    dispatch_async(leQueue, ^{
+        [manager write:newValueCopy
+                 charHandle:charHandle
+                 onService:serviceUuid
+                 withResponse:writeWithResponse];
+    });
 }
 
 quint16 QLowEnergyControllerPrivateOSX::updateValueOfCharacteristic(QLowEnergyHandle charHandle,
@@ -650,7 +710,6 @@ quint16 QLowEnergyControllerPrivateOSX::updateValueOfCharacteristic(QLowEnergyHa
         CharacteristicDataMap::iterator charIt = service->characteristicList.find(charHandle);
         if (charIt != service->characteristicList.end()) {
             QLowEnergyServicePrivate::CharData &charData = charIt.value();
-
             if (appendValue)
                 charData.value += value;
             else
@@ -675,8 +734,18 @@ void QLowEnergyControllerPrivateOSX::readDescriptor(QSharedPointer<QLowEnergySer
         return;
     }
 
-    if (![centralManager readDescriptor:descriptorHandle])
-        service->setError(QLowEnergyService::DescriptorReadError);
+    dispatch_queue_t leQueue(OSXBluetooth::qt_LE_queue());
+    if (!leQueue) {
+        qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "no LE queue found";
+        return;
+    }
+    // Attention! Copy objects!
+    const QBluetoothUuid serviceUuid(service->uuid);
+    ObjCCentralManager * const manager = centralManager.data();
+    dispatch_async(leQueue, ^{
+        [manager readDescriptor:descriptorHandle
+                 onService:serviceUuid];
+    });
 }
 
 void QLowEnergyControllerPrivateOSX::writeDescriptor(QSharedPointer<QLowEnergyServicePrivate> service,
@@ -695,8 +764,20 @@ void QLowEnergyControllerPrivateOSX::writeDescriptor(QSharedPointer<QLowEnergySe
         return;
     }
 
-    if (![centralManager write:newValue descHandle:descriptorHandle])
-        service->setError(QLowEnergyService::DescriptorWriteError);
+    dispatch_queue_t leQueue(OSXBluetooth::qt_LE_queue());
+    if (!leQueue) {
+        qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "no LE queue found";
+        return;
+    }
+    // Attention! Copy objects!
+    const QBluetoothUuid serviceUuid(service->uuid);
+    ObjCCentralManager * const manager = centralManager.data();
+    const QByteArray newValueCopy(newValue);
+    dispatch_async(leQueue, ^{
+        [manager write:newValueCopy
+                 descHandle:descriptorHandle
+                 onService:serviceUuid];
+    });
 }
 
 quint16 QLowEnergyControllerPrivateOSX::updateValueOfDescriptor(QLowEnergyHandle charHandle, QLowEnergyHandle descHandle,
@@ -812,6 +893,45 @@ void QLowEnergyControllerPrivateOSX::invalidateServices()
     discoveredServices.clear();
 }
 
+bool QLowEnergyControllerPrivateOSX::connectSlots(OSXBluetooth::LECentralNotifier *notifier)
+{
+    using OSXBluetooth::LECentralNotifier;
+
+    Q_ASSERT_X(notifier, Q_FUNC_INFO, "invalid notifier object (null)");
+
+    bool ok = connect(notifier, &LECentralNotifier::connected,
+                      this, &QLowEnergyControllerPrivateOSX::_q_connected);
+    ok = ok && connect(notifier, &LECentralNotifier::disconnected,
+                       this, &QLowEnergyControllerPrivateOSX::_q_disconnected);
+    ok = ok && connect(notifier, &LECentralNotifier::serviceDiscoveryFinished,
+                       this, &QLowEnergyControllerPrivateOSX::_q_serviceDiscoveryFinished);
+    ok = ok && connect(notifier, &LECentralNotifier::serviceDetailsDiscoveryFinished,
+                       this, &QLowEnergyControllerPrivateOSX::_q_serviceDetailsDiscoveryFinished);
+    ok = ok && connect(notifier, &LECentralNotifier::characteristicRead,
+                       this, &QLowEnergyControllerPrivateOSX::_q_characteristicRead);
+    ok = ok && connect(notifier, &LECentralNotifier::characteristicWritten,
+                       this, &QLowEnergyControllerPrivateOSX::_q_characteristicWritten);
+    ok = ok && connect(notifier, &LECentralNotifier::characteristicUpdated,
+                       this, &QLowEnergyControllerPrivateOSX::_q_characteristicUpdated);
+    ok = ok && connect(notifier, &LECentralNotifier::descriptorRead,
+                       this, &QLowEnergyControllerPrivateOSX::_q_descriptorRead);
+    ok = ok && connect(notifier, &LECentralNotifier::descriptorWritten,
+                       this, &QLowEnergyControllerPrivateOSX::_q_descriptorWritten);
+    ok = ok && connect(notifier, &LECentralNotifier::LEnotSupported,
+                       this, &QLowEnergyControllerPrivateOSX::_q_LEnotSupported);
+    ok = ok && connect(notifier, SIGNAL(CBCentralManagerError(QLowEnergyController::Error)),
+                       this, SLOT(_q_CBCentralManagerError(QLowEnergyController::Error)));
+    ok = ok && connect(notifier, SIGNAL(CBCentralManagerError(const QBluetoothUuid &, QLowEnergyController::Error)),
+                       this, SLOT(_q_CBCentralManagerError(const QBluetoothUuid &, QLowEnergyController::Error)));
+    ok = ok && connect(notifier, SIGNAL(CBCentralManagerError(const QBluetoothUuid &, QLowEnergyService::ServiceError)),
+                       this, SLOT(_q_CBCentralManagerError(const QBluetoothUuid &, QLowEnergyService::ServiceError)));
+
+    if (!ok)
+        notifier->disconnect();
+
+    return ok;
+}
+
 QLowEnergyController::QLowEnergyController(const QBluetoothAddress &remoteAddress,
                                            QObject *parent)
     : QObject(parent),
@@ -909,11 +1029,11 @@ void QLowEnergyController::connectToDevice()
 
     // A memory allocation problem.
     if (!osx_d_ptr->isValid())
-        return osx_d_ptr->error(UnknownError);
+        return osx_d_ptr->_q_CBCentralManagerError(UnknownError);
 
     // No QBluetoothDeviceInfo provided during construction.
     if (osx_d_ptr->deviceUuid.isNull())
-        return osx_d_ptr->error(UnknownRemoteDeviceError);
+        return osx_d_ptr->_q_CBCentralManagerError(UnknownRemoteDeviceError);
 
     if (osx_d_ptr->controllerState != UnconnectedState)
         return;
@@ -931,18 +1051,28 @@ void QLowEnergyController::disconnectFromDevice()
     if (osx_d_ptr->isValid()) {
         const ControllerState oldState = osx_d_ptr->controllerState;
 
-        osx_d_ptr->controllerState = ClosingState;
-        emit stateChanged(ClosingState);
-        osx_d_ptr->invalidateServices();
-        [osx_d_ptr->centralManager disconnectFromDevice];
-
-        if (oldState == ConnectingState) {
-            // With a pending connect attempt there is no
-            // guarantee we'll ever have didDisconnect callback,
-            // set the state here and now to make sure we still
-            // can connect.
-            osx_d_ptr->controllerState = UnconnectedState;
-            emit stateChanged(UnconnectedState);
+        if (dispatch_queue_t leQueue = OSXBluetooth::qt_LE_queue()) {
+            osx_d_ptr->controllerState = ClosingState;
+            emit stateChanged(ClosingState);
+            osx_d_ptr->invalidateServices();
+
+            QT_MANGLE_NAMESPACE(OSXBTCentralManager) *manager
+                = osx_d_ptr->centralManager.data();
+            dispatch_async(leQueue, ^{
+                [manager disconnectFromDevice];
+            });
+
+            if (oldState == ConnectingState) {
+                // With a pending connect attempt there is no
+                // guarantee we'll ever have didDisconnect callback,
+                // set the state here and now to make sure we still
+                // can connect.
+                osx_d_ptr->controllerState = UnconnectedState;
+                emit stateChanged(UnconnectedState);
+            }
+        } else {
+            qCCritical(QT_BT_OSX) << Q_FUNC_INFO << "qt LE queue is nil,"
+                                  << "can not dispatch 'disconnect'";
         }
     }
 }
@@ -996,3 +1126,5 @@ QString QLowEnergyController::errorString() const
 }
 
 QT_END_NAMESPACE
+
+#include "moc_qlowenergycontroller_osx_p.cpp"
diff --git a/src/bluetooth/qlowenergycontroller_osx_p.h b/src/bluetooth/qlowenergycontroller_osx_p.h
index 1c1cb1cded6e329c7b35098483f1cfebc6aeaf0f..2d1b2e9589ce3eddfa081ffc0112f225adf96883 100644
--- a/src/bluetooth/qlowenergycontroller_osx_p.h
+++ b/src/bluetooth/qlowenergycontroller_osx_p.h
@@ -49,6 +49,7 @@
 #include "osx/osxbtcentralmanager_p.h"
 #include "qlowenergycontroller_p.h"
 #include "qlowenergycontroller.h"
+#include "osx/osxbtnotifier_p.h"
 #include "osx/osxbtutility_p.h"
 #include "qbluetoothaddress.h"
 #include "qbluetoothuuid.h"
@@ -60,14 +61,22 @@
 
 QT_BEGIN_NAMESPACE
 
+namespace OSXBluetooth
+{
+
+class LECentralNotifier;
+
+}
+
 class QByteArray;
 
-// The suffix OSX is not the very right, it's also iOS.
-class QLowEnergyControllerPrivateOSX : public QLowEnergyControllerPrivate,
-                                       public OSXBluetooth::CentralManagerDelegate
+// While suffix 'OSX', it's also for iOS.
+class QLowEnergyControllerPrivateOSX : public QLowEnergyControllerPrivate
 {
     friend class QLowEnergyController;
     friend class QLowEnergyService;
+
+    Q_OBJECT
 public:
     QLowEnergyControllerPrivateOSX(QLowEnergyController *q);
     QLowEnergyControllerPrivateOSX(QLowEnergyController *q,
@@ -76,30 +85,25 @@ public:
 
     bool isValid() const;
 
-private:
-    // CentralManagerDelegate:
-    void LEnotSupported() Q_DECL_OVERRIDE;
-    void connectSuccess() Q_DECL_OVERRIDE;
-
-    void serviceDiscoveryFinished(LEServices services) Q_DECL_OVERRIDE;
-    void serviceDetailsDiscoveryFinished(LEService service) Q_DECL_OVERRIDE;
-    void characteristicReadNotification(QLowEnergyHandle charHandle,
-                                        const QByteArray &value) Q_DECL_OVERRIDE;
-    void characteristicWriteNotification(QLowEnergyHandle charHandle,
-                                         const QByteArray &newValue) Q_DECL_OVERRIDE;
-    void characteristicUpdateNotification(QLowEnergyHandle charHandle,
-                                          const QByteArray &value) Q_DECL_OVERRIDE;
-    void descriptorReadNotification(QLowEnergyHandle descHandle,
-                                    const QByteArray &value) Q_DECL_OVERRIDE;
-    void descriptorWriteNotification(QLowEnergyHandle descHandle,
-                                     const QByteArray &newValue) Q_DECL_OVERRIDE;
-    void disconnected() Q_DECL_OVERRIDE;
-    void error(QLowEnergyController::Error errorCode) Q_DECL_OVERRIDE;
-    void error(const QBluetoothUuid &serviceUuid,
-               QLowEnergyController::Error errorCode) Q_DECL_OVERRIDE;
-    void error(const QBluetoothUuid &serviceUuid,
-               QLowEnergyService::ServiceError error) Q_DECL_OVERRIDE;
+private Q_SLOTS:
+    void _q_connected();
+    void _q_disconnected();
+
+    void _q_serviceDiscoveryFinished();
+    void _q_serviceDetailsDiscoveryFinished(QSharedPointer<QLowEnergyServicePrivate> service);
+
+    void _q_characteristicRead(QLowEnergyHandle charHandle, const QByteArray &value);
+    void _q_characteristicWritten(QLowEnergyHandle charHandle, const QByteArray &value);
+    void _q_characteristicUpdated(QLowEnergyHandle charHandle, const QByteArray &value);
+    void _q_descriptorRead(QLowEnergyHandle descHandle, const QByteArray &value);
+    void _q_descriptorWritten(QLowEnergyHandle charHandle, const QByteArray &value);
 
+    void _q_LEnotSupported();
+    void _q_CBCentralManagerError(QLowEnergyController::Error error);
+    void _q_CBCentralManagerError(const QBluetoothUuid &serviceUuid, QLowEnergyController::Error error);
+    void _q_CBCentralManagerError(const QBluetoothUuid &serviceUuid, QLowEnergyService::ServiceError error);
+
+private:
     void connectToDevice();
     void discoverServices();
     void discoverServiceDetails(const QBluetoothUuid &serviceUuid);
@@ -139,6 +143,7 @@ private:
 
     void setErrorDescription(QLowEnergyController::Error errorCode);
     void invalidateServices();
+    bool connectSlots(OSXBluetooth::LECentralNotifier *notifier);
 
     QLowEnergyController *q_ptr;
     QBluetoothUuid deviceUuid;
@@ -159,6 +164,7 @@ private:
     QLowEnergyController::ControllerState controllerState;
     QLowEnergyController::RemoteAddressType addressType;
 
+    typedef QT_MANGLE_NAMESPACE(OSXBTCentralManager) ObjCCentralManager;
     typedef OSXBluetooth::ObjCScopedPointer<ObjCCentralManager> CentralManager;
     CentralManager centralManager;
 
diff --git a/src/bluetooth/qlowenergyservice.cpp b/src/bluetooth/qlowenergyservice.cpp
index 9cccbc930d242a648f16d02dae4effdca0866e5f..30a66db8cce7a27595f7dda0192ad89d42b02235 100644
--- a/src/bluetooth/qlowenergyservice.cpp
+++ b/src/bluetooth/qlowenergyservice.cpp
@@ -584,13 +584,13 @@ bool QLowEnergyService::contains(const QLowEnergyCharacteristic &characteristic)
     serialised. A queue is employed when issuing multiple requests at the same time.
     The queue does not eliminate duplicated read requests for the same characteristic.
 
-    A characteristic can only be read if the service is in the \l ServiceDiscovered state,
-    belongs to the service. If one of these conditions is
+    A characteristic can only be read if the service is in the \l ServiceDiscovered state
+    and belongs to the service. If one of these conditions is
     not true the \l QLowEnergyService::OperationError is set.
 
     \note Calling this function despite \l QLowEnergyCharacteristic::properties() reporting a non-readable property
     always attempts to read the characteristic's value on the hardware. If the hardware
-    returns with an error the \l CharacteristicWriteError is set.
+    returns with an error the \l CharacteristicReadError is set.
 
     \sa characteristicRead(), writeCharacteristic()
 
@@ -630,7 +630,7 @@ void QLowEnergyService::readCharacteristic(
     \note Currently, it is not possible to use signed or reliable writes as defined by the
     Bluetooth specification.
 
-    A characteristic can only be written if this service is in the \l ServiceDiscovered state,
+    A characteristic can only be written if this service is in the \l ServiceDiscovered state
     and belongs to the service. If one of these conditions is
     not true the \l QLowEnergyService::OperationError is set.
 
diff --git a/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp b/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp
index 65941fecac6c6a0743e8f0eb9916e79cf796ccdc..c95592968400c07f1ffdf5ba5ec3ea229543294a 100644
--- a/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp
+++ b/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp
@@ -314,7 +314,7 @@ void QDeclarativeBluetoothDiscoveryModel::serviceDiscovered(const QBluetoothServ
   \qmlsignal BluetoothDiscoveryModel::deviceDiscovered(string device)
 
   This signal is emitted when a new device is discovered. \a device contains
-  the Bluetooth address of the discovred device.
+  the Bluetooth address of the discovered device.
 
   The corresponding handler is \c onDeviceDiscovered.
   */
@@ -365,7 +365,7 @@ void QDeclarativeBluetoothDiscoveryModel::setDiscoveryMode(DiscoveryMode discove
   \qmlproperty bool BluetoothDiscoveryModel::running
 
   This property starts or stops discovery. A restart of the discovery process
-  requires setting this property to \c false and subsequemtly to \c true again.
+  requires setting this property to \c false and subsequently to \c true again.
 
 */
 
diff --git a/src/nfc/qqmlndefrecord.cpp b/src/nfc/qqmlndefrecord.cpp
index 278cc583c82a9a54f3bff56a43b8aa5cd7c2e10b..b204d4d0ec345288d4375705f28484ad3a899453 100644
--- a/src/nfc/qqmlndefrecord.cpp
+++ b/src/nfc/qqmlndefrecord.cpp
@@ -243,6 +243,11 @@ QQmlNdefRecord::QQmlNdefRecord(const QNdefRecord &record, QObject *parent)
     d_ptr->record = record;
 }
 
+QQmlNdefRecord::~QQmlNdefRecord()
+{
+    delete d_ptr;
+}
+
 /*!
     \enum QQmlNdefRecord::TypeNameFormat
 
diff --git a/src/nfc/qqmlndefrecord.h b/src/nfc/qqmlndefrecord.h
index dbd947eec457a7d0b6f309a7d9cfab6382546cd6..93a3106e190faa8720af6abe3ce0e460b1b06973 100644
--- a/src/nfc/qqmlndefrecord.h
+++ b/src/nfc/qqmlndefrecord.h
@@ -65,6 +65,7 @@ public:
 
     explicit QQmlNdefRecord(QObject *parent = 0);
     explicit QQmlNdefRecord(const QNdefRecord &record, QObject *parent = 0);
+    ~QQmlNdefRecord();
 
     QString type() const;
     void setType(const QString &t);