         clientState = MQTTClientState.ConnectionClosed
     }
 
+    // MARK: - Keep alive timer
+
+    private func startKeepAliveTimer() {
+        keepAliveTimer?.invalidate()
+        keepAliveTimer = NSTimer.scheduledTimerWithTimeInterval(
+            Double(keepAliveInterval) / 2.0,
+            target: self,
+            selector: #selector(self.mqttPing),
+            userInfo: nil,
+            repeats: true)
+    }
+
+    private func endKeepAliveTimer() {
+        keepAliveTimer?.invalidate()
+        keepAliveTimer = nil
+    }
+
+    // MARK: - Socket connection
+
+    private func connectSocket(host: String, port: Int) -> Bool {
+        NSStream.getStreamsToHostWithName(host, port: port, inputStream: &inputStream, outputStream: &outputStream)
+
+        if inputStream == nil || outputStream == nil { return false }
+
+        inputStream?.delegate = self
+        outputStream?.delegate = self
+
+        inputStream?.open()
+        outputStream?.open()
+
+        inputStream?.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
+        outputStream?.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
+
+        return true
+    }
+
+    private func disconnectSocket() {
+        inputStream?.removeFromRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
+        outputStream?.removeFromRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
+
+        inputStream?.close()
+        outputStream?.close()
+
+        inputStream?.delegate = nil
+        outputStream?.delegate = nil
+
+        inputStream = nil;
+        outputStream = nil;
+    }
+
     // MARK: - Stream delegate
 
-    func stream(stream: NSStream, handleEvent eventCode: NSStreamEvent) {
+    dynamic internal func stream(stream: NSStream, handleEvent eventCode: NSStreamEvent) {
         switch stream {
         case inputStream!:
             switch (eventCode) {

            break
        }
    }

    // MARK: - Message parsing

    private func parseMessage() {
        let topicLengthMSB = messageBuffer[0]
        let topicLengthLSB = messageBuffer[1]

        let topicLength = Int(topicLengthMSB) * 256 + Int(topicLengthLSB)

        let topic = String(bytes: messageBuffer[2 ..< topicLength + 2], encoding: NSUTF8StringEncoding)
        let message = String(bytes: messageBuffer[topicLength + 2 ..< messageBuffer.count], encoding: NSUTF8StringEncoding)

        if let topic = topic, let message = message {
            delegate?.didReceiveMessage(topic, message: message)
        }
    }
}

enum MQTTClientState {
    case ConnectionClosed
    case Initializing
    case Connected
    case DecodingHeader
    case DecodingLength
    case DecodingData
    case ConnectionError
}

protocol LightMQTTDelegate: class {
    func didReceiveMessage(topic: String, message: String)
}

let MQTT_BUFFER_SIZE: Int = 4096

final class LightMQTT: NSObject, NSStreamDelegate {

    private var clientState = MQTTClientState.ConnectionClosed

