             // remove old cache
             while let index = characteristics.values.index(where: {
                 $0.value.handle.declaration > service.handle &&
-                $0.value.handle.declaration < service.end }) {
+                $0.value.handle.declaration <= service.end }) {
                 
                 characteristics.values.remove(at: index)
             }
             
+            // insert new values
             newValues.forEach {
-                let identifier = characteristics.newIdentifier()
+                let identifier = UInt($0.handle.declaration)
                 characteristics.values[identifier] = $0
+            }
+            
+            // remove old notifications
+            while let key = characteristics.notifications.keys
+                .first(where: { characteristics.values.keys.contains($0) == false }) {
+                characteristics.notifications[key] = nil
             }
         }
     }

            
            fileprivate(set) var values: [UInt: GATTClient.Characteristic] = [:]
            
            private var lastIdentifier: UInt = 0
            
            fileprivate mutating func newIdentifier() -> UInt {
                
                lastIdentifier += 1
                
                return lastIdentifier
            }
        }
        
        mutating func insert(_ newValues: [GATTClient.Characteristic],

        self.log?("Did discover \(self.scanData.count) peripherals")
    }
    
    public func connect(to peripheral: Peripheral, timeout: TimeInterval = .gattDefaultTimeout) throws {
        
        guard let advertisementData = scanData[peripheral]
            else { throw CentralError.unknownPeripheral }
