         connection.addObserver(self, forKeyPath: "state", options: [.Initial, .New], context: nil)
     }
 
+    /**
+     Disconnect the socket.
+
+     The socket will disconnect elegantly after any queued writing data are successfully sent.
+     */
     func disconnect() {
         closeAfterWriting = true
         checkStatus()
     }
 
+    /**
+     Disconnect the socket immediately.
+     */
     func forceDisconnect() {
         cancel()
     }
 
+    /**
+     Send data to remote.
+
+     - parameter data: Data to send.
+     - parameter tag:  The tag identifying the data in the callback delegate method.
+     - warning: This should only be called after the last write is finished, i.e., `delegate?.didWriteData()` is called.
+     */
     func writeData(data: NSData, withTag tag: Int) {
         sendData(data, withTag: tag)
     }
 
+    /**
+     Read data from the socket.
+
+     - parameter tag: The tag identifying the data in the callback delegate method.
+     - warning: This should only be called after the last read is finished, i.e., `delegate?.didReadData()` is called.
+     */
     func readDataWithTag(tag: Int) {
         connection.readMinimumLength(1, maximumLength: Opt.MAXNWTCPSocketReadDataSize) { data, error in
             guard error == nil else {


        switch connection.state {
        case .Connected:
            delegateCall() {
                self.delegate?.didConnect(self)
            }
        case .Disconnected:

            cancel()
        case .Cancelled:
            DDLogVerbose("Cancelled")
            queueCall {
                self.delegate?.didDisconnect(self)
                self.delegate = nil
            }
        default:
            DDLogVerbose("SNWTunnel state is \(connection.state.rawValue).")
