 
 // MARK: - GATT operations
 extension Device {
+    
     // TODO: Make CBUUID into strings
     open func discoverServices(with uuids: [CBUUID]? = nil, complete: ServiceDiscovery?) {
-        guard isConnected == true else {
-            Log(v: "Not connected - cannot discoverServices", tag: tag)
-            return
-        }
-        
-        serviceDiscoveryHandler = complete
-        Log(v: "discoverServices: \(self.peripheral) \n \(String(describing: self.peripheral.delegate))", tag: tag)
-        self.peripheral.discoverServices(uuids)
+        let item = QueueItem<[CBService]>(
+            name: "discoverServices", // TODO: Need better than a hardcoded string
+            execution: { (cb) in
+                guard self.isConnected == true else {
+                    Log(v: "Not connected - cannot discoverServices", tag: self.tag)
+                    cb(.failure(ConnectionError.disconnected))
+                    return
+                }
+                Log(v: "discoverServices: \(self.peripheral) \n \(String(describing: self.peripheral.delegate))", tag: self.tag)
+                self.peripheral.discoverServices(uuids)
+        },
+            callback: { (result, done) in
+                complete?(result)
+                done()
+        })
+        
+        queue.pushBack(item)
     }
     
     // TODO: Make CBUUID into strings
     // TODO: Make service a UUID?
     open func discoverCharacteristics(with uuids: [CBUUID]? = nil, for service: CBService, complete: CharacteristicDiscovery?) {
-        guard isConnected == true else {
-            Log(v: "Not connected - cannot discoverCharacteristics", tag: tag)
-            return
-        }
-        
-        characteristicDiscoveryHandler = complete
-        Log(v: "discoverCharacteristics", tag: tag)
-        peripheral.discoverCharacteristics(uuids, for: service)
+        let item = QueueItem<DiscoveredCharacteristic>(
+            name: service.uuid.uuidString,
+            execution: { (cb) in
+                guard self.isConnected == true else {
+                    Log(v: "Not connected - cannot discoverCharacteristics", tag: self.tag)
+                    cb(.failure(ConnectionError.disconnected))
+                    return
+                }
+                Log(v: "discoverCharacteristics", tag: self.tag)
+                self.peripheral.discoverCharacteristics(uuids, for: service)
+        },
+            callback: { (result, done) in
+                complete?(result)
+                done()
+        })
+        
+        queue.pushBack(item)
     }
     
     open func read(from characteristic: String, in service: String, complete: ReadHandler?) {

            result = .failure(e)
        }
        
        serviceDiscoveryHandler?(result)
    }
    
    func didDiscoverIncludedServicesFor(service: CBService, error: Error?) {

        if let e = error {
            result = .failure(e)
        }
        
        for operation in queue.items {
            guard operation.name == service.uuid.uuidString,
                operation.isExecuting == true else {
                    continue
            }
            // TODO: Exit loop, or run through everything just in case? Probably exit
            // TODO: If queue.items can be mapped as QueueItem<Data> - cast unnecessary
            (operation as? QueueItem<DiscoveredCharacteristic>)?.notify(result)
        }
    }
    
    func didUpdateValueFor(characteristic: CBCharacteristic, error: Error?) {
