         guard !self.isCancelled else {
             return
         }
-
+        
         self.proxySocket.openSocket()
         self._status = .readingRequest
         self.observer?.signal(.opened(self))
     }
-
+    
     /**
      Close the tunnel elegantly.
      */
     func close() {
         observer?.signal(.closeCalled(self))
-
+        
         guard !self.isCancelled else {
             return
         }
-
+        
         self._cancelled = true
         self._status = .closing
-
+        
         if !self.proxySocket.isDisconnected {
             self.proxySocket.disconnect()
         }

            }
        } else if let socket = socket as? AdapterSocket {
            observer?.signal(.adapterSocketWroteData(data, by: socket, on: self))

            guard !isCancelled else {
                return
            }

            QueueFactory.getQueue().asyncAfter(deadline: DispatchTime.now() + DispatchTimeInterval.microseconds(Opt.forwardReadInterval)) { [weak self] in
                self?.proxySocket.readData()
            }
        }
    }

    public func didConnectWith(adapterSocket: AdapterSocket) {
        guard !isCancelled else {
            return
        }

        observer?.signal(.connectedToRemote(adapterSocket, on: self))
    }

    public func updateAdapterWith(newAdapter: AdapterSocket) {
        guard !isCancelled else {
            return
        }

        observer?.signal(.updatingAdapterSocket(from: adapterSocket!, to: newAdapter, on: self))

        adapterSocket = newAdapter
        adapterSocket?.delegate = self
    }

    fileprivate func checkStatus() {
        if isClosed {
            _status = .closed


/// The tunnel forwards data between local and remote.
public class Tunnel: NSObject, SocketDelegate {
    
    /// The status of `Tunnel`.
    public enum TunnelStatus: CustomStringConvertible {
        
        case invalid, readingRequest, waitingToBeReady, forwarding, closing, closed
        
        public var description: String {
            switch self {
            case .invalid:
