 
 private func dataLoaderWithCachedResultBinder<Identifier, DataLoadContext>(
     ignoreFreshDataLoadFail: Bool,
-    dataLoaderForIdentifier: AsyncTypes2<Identifier, (DataLoadContext, NSData), NSError>.AsyncBinder,
+    dataLoader             : AsyncStream<(DataLoadContext, NSData), AnyObject, NSError>,
     loadDataIdentifier     : Identifier) -> AsyncTypes2<NSError, (DataRequestContext<DataLoadContext>, NSData), NSError>.AsyncBinder
 {
     return { (bindError: NSError) -> AsyncTypes<(DataRequestContext<DataLoadContext>, NSData), NSError>.Async in
 
-        let finishCallbackHook = { (result: AsyncResult<(DataLoadContext, NSData), NSError>, doneCallback: AsyncTypes<(DataRequestContext<DataLoadContext>, NSData), NSError>.DidFinishAsyncCallback?) -> () in
+        let dataLoader = dataLoader.map({ value -> (DataRequestContext<DataLoadContext>, NSData) in
 
-            switch result {
-            case .Success(let value):
-                let newResult = (DataRequestContext<DataLoadContext>.Outside(value.0), value.1)
+            let newResult = (DataRequestContext<DataLoadContext>.Outside(value.0), value.1)
+            return newResult
+        }).tryMapError({ error -> Result<(DataRequestContext<DataLoadContext>, NSData), NSError> in
 
-                doneCallback?(result: .Success(newResult))
-            case .Failure(let error):
+            if error is AsyncInterruptedError {
+                return .Failure(error)
+            }
 
-                if error is AsyncInterruptedError {
-                    doneCallback?(result: .Failure(error))
-                    return
+            //TODO test [bindError isKindOfClass:[JFFErrorNoFreshData class]] issue, here it can got - not data in cache error !!!
+            if ignoreFreshDataLoadFail {
+                if let noFreshDataError = bindError as? ErrorNoFreshData {
+
+                    let newResult = (DataRequestContext<DataLoadContext>.CacheUpdateDate(noFreshDataError.cachedData.0), noFreshDataError.cachedData.1)
+
+                    return .Success(newResult)
                 }
+            }
 
-                //TODO test [bindError isKindOfClass:[JFFErrorNoFreshData class]] issue, here it can got - not data in cache error !!!
-                if ignoreFreshDataLoadFail {
-                    if let noFreshDataError = bindError as? ErrorNoFreshData {
+            return .Failure(error)
+        })
 
-                        let newResult = (DataRequestContext<DataLoadContext>.CacheUpdateDate(noFreshDataError.cachedData.0), noFreshDataError.cachedData.1)
-
-                        doneCallback?(result: .Success(newResult))
-                        return
-                    }
-                }
-
-                doneCallback?(result: .Failure(error))
-            }
-        }
-        let dataLoader = dataLoaderForIdentifier(loadDataIdentifier)
-        return asyncWithFinishHookBlock(dataLoader, finishCallbackHook: finishCallbackHook)
+        return dataLoader.toAsync()
     }
 }
 


final public class SmartDataLoaderFields<Identifier, Result, DataLoadContext> {

    public typealias JAsyncBinderForIdentifier = (loadDataIdentifier: Identifier) -> AsyncTypes2<(DataRequestContext<DataLoadContext>, NSData), Result, NSError>.AsyncBinder
    public typealias JCacheKeyForIdentifier    = (loadDataIdentifier: Identifier) -> String

    let loadDataIdentifier        : Identifier
    let dataLoaderForIdentifier   : AsyncTypes2<Identifier, (DataLoadContext, NSData), NSError>.AsyncBinder
    let analyzerForData           : JAsyncBinderForIdentifier
    let cacheKeyForIdentifier     : JCacheKeyForIdentifier
    let ignoreFreshDataLoadFail   : Bool
    let cache                     : AsyncRestKitCache
    let cacheDataLifeTimeInSeconds: NSTimeInterval

    public init(
        loadDataIdentifier        : Identifier,
        dataLoaderForIdentifier   : AsyncTypes2<Identifier, (DataLoadContext, NSData), NSError>.AsyncBinder,
        analyzerForData           : JAsyncBinderForIdentifier,
        cacheKeyForIdentifier     : JCacheKeyForIdentifier,
        ignoreFreshDataLoadFail   : Bool,
        cache                     : AsyncRestKitCache,
        cacheDataLifeTimeInSeconds: NSTimeInterval) {

        self.loadDataIdentifier         = loadDataIdentifier
        self.dataLoaderForIdentifier    = dataLoaderForIdentifier
        self.analyzerForData            = analyzerForData
        self.cacheKeyForIdentifier      = cacheKeyForIdentifier
        self.ignoreFreshDataLoadFail    = ignoreFreshDataLoadFail
        self.cache                      = cache
        self.cacheDataLifeTimeInSeconds = cacheDataLifeTimeInSeconds

public func jSmartDataLoaderWithCache<Identifier, Result, DataLoadContext>(args: SmartDataLoaderFields<Identifier, Result, DataLoadContext>) -> AsyncTypes<Result, NSError>.Async {

    let loadDataIdentifier         = args.loadDataIdentifier
    let dataLoader                 = args.dataLoader
    let analyzerForData            = args.analyzerForData
    let cache                      = args.cache
    let cacheKey                   = args.cacheKey
    let cacheDataLifeTimeInSeconds = args.cacheDataLifeTimeInSeconds
    let ignoreFreshDataLoadFail    = args.ignoreFreshDataLoadFail

    let cachedDataLoader = { (progressCallback: AsyncProgressCallback?,
                              finishCallback  : AsyncTypes<(DataRequestContext<DataLoadContext>, NSData), NSError>.DidFinishAsyncCallback?) -> AsyncHandler in

        let loadCachedData: AsyncTypes<(DataRequestContext<DataLoadContext>, NSData), NSError>.Async = loadFreshCachedDataWithUpdateDate(
            cacheKey,
            cachedDataLoader          : cache.cachedDataLoaderForKey(cacheKey),
            cacheDataLifeTimeInSeconds: cacheDataLifeTimeInSeconds)

        let dataLoaderBinder = dataLoaderWithCachedResultBinder(
            ignoreFreshDataLoadFail,
            dataLoader        : dataLoader,
            loadDataIdentifier: loadDataIdentifier)

        let loader = bindTrySequenceOfAsyncs(loadCachedData, dataLoaderBinder)

