     }
 
     func refreshMessages(completionHandler: (() -> Void)? = nil) {
-        if let token = userAuthenticationToken {
-            refreshMessages(token: token, completionHandler: completionHandler)
-        } else {
-            notifyDidFailToLoadMessages()
-            completionHandler?()
-        }
-    }
-    
-    private func refreshMessages(token: String, completionHandler: (() -> Void)?) {
-        api.loadPrivateMessages(authorizationToken: token) { (messages) in
-            if let messages = messages {
-                self.updateEntities(from: messages)
-            } else {
-                self.notifyDidFailToLoadMessages()
-            }
-
-            completionHandler?()
-        }
+        state.refreshMessages(completionHandler: completionHandler)
     }
     
     private func updateEntities(from messages: [MessageCharacteristics]) {

    }

    func add(_ observer: PrivateMessagesObserver) {
        privateMessageObservers.append(observer)
        observer.privateMessagesServiceDidUpdateUnreadMessageCount(to: determineUnreadMessageCount())
        observer.privateMessagesServiceDidFinishRefreshingMessages(messages: localMessages)
    }

    }

    private func userLoggedIn(_ event: DomainEvent.LoggedIn) {
        state = AuthenticatedState(service: self, token: event.authenticationToken)
    }
    
    // MARK: State Machine
    
    private class State {
        
        unowned let service: ConcretePrivateMessagesService
        
        init(service: ConcretePrivateMessagesService) {
            self.service = service
        }
        
        func refreshMessages(completionHandler: (() -> Void)? = nil) { }
        func markMessageAsRead(_ message: Message) { }
        
    }
    
    private class UnauthenticatedState: State {
        
        override func refreshMessages(completionHandler: (() -> Void)?) {
            service.notifyDidFailToLoadMessages()
            completionHandler?()
        }
        
    }
    
    private class AuthenticatedState: State {
        
        private let token: String
        
        init(service: ConcretePrivateMessagesService, token: String) {
            self.token = token
            super.init(service: service)
        }
        
        override func refreshMessages(completionHandler: (() -> Void)?) {
            service.api.loadPrivateMessages(authorizationToken: token) { (messages) in
                if let messages = messages {
                    self.service.updateEntities(from: messages)
                } else {
                    self.service.notifyDidFailToLoadMessages()
                }
                
                completionHandler?()
            }
        }
        
        override func markMessageAsRead(_ message: Message) {
            service.api.markMessageWithIdentifierAsRead(message.identifier, authorizationToken: token)
            service.updateObserversWithUnreadMessageCount()
        }
        
    }

}
