     public func unregisterAll() {
         
         notifyList.removeAll()
+        
         disconnectList.removeAll()
     }
     
     /// Adds a PDU to the queue to send.
     ///
     /// - Returns: Identifier of queued send operation or `nil` if the PDU cannot be sent.
-    public func send<T: ATTProtocolDataUnit>(PDU: T, response: ATTResponseCallback? = nil) -> UInt? {
+    public func send<T: ATTProtocolDataUnit>(PDU: T, response: T -> ()) -> UInt? {
         
         let attributeOpcode = T.attributeOpcode
         
         let type = attributeOpcode.type
-        
-        /* If the opcode corresponds to an operation type that does not elicit a
-        * response from the remote end, then no callback should have been
-        * provided, since it will never be called.
-        */
-        guard (response != nil && type != .Request && type != .Response) == false
-            else { return nil }
-        
-        /* Similarly, if the operation does elicit a response then a callback
-        * must be provided.
-        */
-        guard (response == nil && (type == .Request || type == .Indication)) == false
-            else { return nil }
         
         guard let encodedPDU = encodePDU(PDU)
             else { return nil }
         
         let identifier = nextSendOpcodeID
         
-        let sendOpcode = ATTSendOpcode(identifier: identifier, opcode: attributeOpcode, PDU: encodedPDU, response: response)
+        let sendOpcode = ATTSendOpcode(identifier: identifier, opcode: attributeOpcode, data: encodedPDU, response: response)
         
         // increment ID
         nextSendOpcodeID += 1

        
        return nil
    }
    
    private func log(string: String) {
        
        if self.logEnabled { print(string) }
    }
}

// MARK: - Supporting Types

public typealias ATTResponseCallback = ATTProtocolDataUnit -> ()

public typealias ATTNotifyCallback = ATTProtocolDataUnit -> ()

// MARK: - Private Supporting Types

private struct ATTSendOpcode {
    
    let identifier: UInt
    
    let opcode: ATT.Opcode
    
    let PDU: [UInt8]
    
    let response: ATTResponseCallback
    
    init(identifier: UInt, opcode: ATT.Opcode, PDU: [UInt8], response: ATTResponseCallback) {
        
        self.identifier = identifier
        self.opcode = opcode
        self.PDU = PDU
        self.response = response
    }
}

private struct ATTNotify<PDU: ATTProtocolDataUnit> {
    
    let identifier: UInt
    
    let opcode: ATT.Opcode
    
    let notify: PDU -> ()
    
    init(identifier: UInt, opcode: ATT.Opcode, notify: PDU -> ()) {
        
        self.identifier = identifier
        self.opcode = opcode
        self.notify = notify
    }
}

    }
    
    /// Performs the actual IO for sending data.
    public func write() throws {
        
        guard let sendOpcode = pickNextSendOpcode()
            else { return } // throw error?
        
        //try socket.send(Data(byteValue: []))
        
        
    }
