 struct ManagerMode: OptionSetType {
     var rawValue: Int
     
-    static let Local = ManagerMode.init(rawValue: 1 << 0)
-    static let Remote = ManagerMode.init(rawValue: 1 << 1)
-    
-}
-
-enum DataManagerResponse<T, E> {
-    case Success(obj: T)
-    case Error(obj: E)
-}
-
-enum NewDataManagerError: ErrorType {
-    case JSONParseError, ServerError, NoDeckWithGivenId, ErrorWith(message: String)
-}
-
+    static let Local = ManagerMode(rawValue: 1 << 0)
+    static let Remote = ManagerMode(rawValue: 1 << 1)
+    
+}
+
+public enum DataManagerResponseType {
+    case Local, Remote
+}
+
+public enum DataManagerResponse<T> {
+    case Success(obj: T, responseType: DataManagerResponseType)
+    case Error(obj: NewDataManagerError, responseType: DataManagerResponseType)
+}
+
+public enum NewDataManagerError: ErrorType {
+    case JSONParseError, ServerError(err: ErrorType), NoDeckWithGivenId, ErrorWithMessage(text: String), DataManagerWasDeinitialized
+}
+private class ModeHandler<T> {
+    var local: (() -> DataManagerResponse<T>)?
+    
+    // wylaczenie ostrzezenia swift lint, aby moc przypisac wartosci poszczegolnym blokom bez ponownego pisania ich typu 
+    // force unwrap zamiast optional, poniewaz w przypadku odwolania do serwera powinny zostac obsluzone oba przypadki
+    var remote: (remoteSuccess: ((obj: JSON) -> DataManagerResponse<T>)!, //swiftlint:disable:this force_unwrapping
+                remoteError: ((obj: ErrorType) -> DataManagerResponse<T>)!)?     //swiftlint:disable:this force_unwrapping
+
+    var remoteRequest: (() -> ())?
+    var activeMode: ManagerMode
+    var callback: (DataManagerResponse<T>) -> ()
+    
+    init(withMode mode: ManagerMode, callback: (DataManagerResponse<T>) -> ()) {
+        self.activeMode = mode
+        self.callback = callback
+    }
+    
+    func start() {
+        if activeMode.contains(.Remote) {
+            remoteRequest?()
+        } else if activeMode == .Local {
+            local?()
+        }
+    }
+    
+}
 public class NewDataManager {
     
     let remoteDataManager = RemoteDataManager()
     let localDataManager = LocalDataManager()
     
-
-
-    func getDeck(withDeckId deckID: String, mode: ManagerMode, managerCompletion: (DataManagerResponse<Deck, NewDataManagerError>)-> ()) {
-       
-        var localBlock:(()-> (DataManagerResponse<Deck, NewDataManagerError>))?
-        
-        /// Obsluga roznych trybow - tylko lokalne dane, tylko dane z serwera, badz dane lokalne w przypadku braku dostepu do danych z serwera
-        if mode.contains(.Local) {
-            localBlock = {
-                if let deck: Deck = self.localDataManager.get(withId: deckID) {
-                    return .Success(obj: deck)
-                } else {
-                    return .Error(obj: .NoDeckWithGivenId)
+    var mode: ManagerMode = [.Local, .Remote]
+    
+    private func handlerCompletion<T>(handler: ModeHandler<T>) -> (response: ServerResultType<JSON>) -> () {
+    
+        return { response in
+            
+            switch response {
+            case .Success(let obj):
+                if let result = handler.remote?.remoteSuccess(obj: obj) {
+                    handler.callback(result)
                 }
-            }
-        }
-        
-        if mode.contains(.Remote) {
-            remoteDataManager.deck(deckID, completion: { (response) in
-                switch response {
-                case.Success(let obj):
-                    if let deck = Deck.withJSON(obj) {
-                        managerCompletion(.Success(obj: deck))
-                    } else {
-                        managerCompletion(.Error(obj: .JSONParseError))
-                    }
-                case .Error:
-                    if let localBlock = localBlock {
-                        managerCompletion(localBlock())
-                    } else {
-                        managerCompletion(.Error(obj: .ServerError))
-                    }
-                case .WrongRequest(let msg):
-                    managerCompletion(.Error(obj: .ErrorWith(message: msg)))
+            case .Error(let obj):
+                if handler.activeMode.contains(.Local), let local = handler.local {
+                    handler.callback(local())
+                } else if let result = handler.remote?.remoteError(obj: obj) {
+                    handler.callback(result)
                 }
                 
-            })
-        } else if let localBlock = localBlock {
-            managerCompletion(localBlock())
-        }
-    }
-}
+            }
+            handler.remoteRequest = nil
+        }
+    }
+    
+    func getDeck(withDeckId deckID: String, managerCompletion: (DataManagerResponse<Deck>)-> ()) {
+       
+        let modeBlocks = ModeHandler<Deck>(withMode: mode, callback: managerCompletion)
+       
+        modeBlocks.remoteRequest = {
+            self.remoteDataManager.deck(deckID, completion: self.handlerCompletion(modeBlocks))
+        }
+        modeBlocks.local = {
+            if let deck  = self.localDataManager.get(Deck.self, withId: deckID) {
+                return .Success(obj: deck, responseType: .Local)
+            } else {
+                return .Error(obj: .NoDeckWithGivenId, responseType: .Local)
+            }
+        }
+        
+        modeBlocks.remote = (nil, nil)
+        
+        modeBlocks.remote?.remoteSuccess = {  obj in
+            if let deck = Deck.withJSON(obj) {
+                self.localDataManager.update(deck)
+                return .Success(obj: deck, responseType: .Remote)
+            } else {
+                return .Error(obj: .JSONParseError, responseType: .Remote)
+            }
+            
+        }
+        
+        modeBlocks.remote?.remoteError = { obj in
+            return .Error(obj: .ServerError(err: obj), responseType: .Remote)
+        }
+        
+        modeBlocks.start()
+    }
+}

        let parameters: [String: AnyObject?] = ["includeOwn": includeOwn,
                                                "flashcardsCount": flashcardsCount,
                                                "name": name]
        request(.GET, url: url(fromRouter: Router.Deck(child: .Get(id: nil))), parameters: parameters).responseJSON {
            switch $0.result {
            case .Success(let value):
                let json = JSON(value).arrayValue
                completion(.Success(obj: json))
            case .Failure(let error):
                completion(.Error(error: error))
            }
            
        }


extension Deck {
    class func withJSON(json: JSON) -> Deck? {
        if let jsonDict = json.dictionary {
            if let id = jsonDict["id"]?.string, name = jsonDict["name"]?.string {
                return Deck(serverID: id, name: name)
            }
        }
        return nil
    }
    
    class func arrayWithJSON(json: JSON) -> [Deck] {
        var decks = [Deck]()
        if let jsonArray = json.array {
            jsonArray.forEach {
                if let deck = Deck.withJSON($0) {
                    decks.append(deck)
                }
            }
        }
        return decks
    }
}

