 
 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
+    public typealias AnalyzerType = (DataRequestContext<DataLoadContext>, NSData) -> AsyncStream<Result, AnyObject, NSError>
 
     let loadDataIdentifier        : Identifier
-    let dataLoaderForIdentifier   : AsyncTypes2<Identifier, (DataLoadContext, NSData), NSError>.AsyncBinder
-    let analyzerForData           : JAsyncBinderForIdentifier
-    let cacheKeyForIdentifier     : JCacheKeyForIdentifier
+    let dataLoader                : AsyncStream<(DataLoadContext, NSData), AnyObject, NSError>
+    let analyzerForData           : AnalyzerType
+    let cacheKey                  : String
     let ignoreFreshDataLoadFail   : Bool
     let cache                     : AsyncRestKitCache
     let cacheDataLifeTimeInSeconds: NSTimeInterval
 
     public init(
         loadDataIdentifier        : Identifier,
-        dataLoaderForIdentifier   : AsyncTypes2<Identifier, (DataLoadContext, NSData), NSError>.AsyncBinder,
-        analyzerForData           : JAsyncBinderForIdentifier,
-        cacheKeyForIdentifier     : JCacheKeyForIdentifier,
+        dataLoader                : AsyncStream<(DataLoadContext, NSData), AnyObject, NSError>,
+        analyzerForData           : AnalyzerType,
+        cacheKey                  : String,
         ignoreFreshDataLoadFail   : Bool,
         cache                     : AsyncRestKitCache,
         cacheDataLifeTimeInSeconds: NSTimeInterval) {
 
         self.loadDataIdentifier         = loadDataIdentifier
-        self.dataLoaderForIdentifier    = dataLoaderForIdentifier
+        self.dataLoader                 = dataLoader
         self.analyzerForData            = analyzerForData
-        self.cacheKeyForIdentifier      = cacheKeyForIdentifier
+        self.cacheKey                   = cacheKey
         self.ignoreFreshDataLoadFail    = ignoreFreshDataLoadFail
         self.cache                      = cache
         self.cacheDataLifeTimeInSeconds = cacheDataLifeTimeInSeconds


private func dataLoaderWithCachedResultBinder<Identifier, DataLoadContext>(
    ignoreFreshDataLoadFail: Bool,
    dataLoaderForIdentifier: AsyncTypes2<Identifier, (DataLoadContext, NSData), NSError>.AsyncBinder,
    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

            switch result {
            case .Success(let value):
                let newResult = (DataRequestContext<DataLoadContext>.Outside(value.0), value.1)

                doneCallback?(result: .Success(newResult))
            case .Failure(let 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)

                        doneCallback?(result: .Success(newResult))
                        return
                    }
                }

                doneCallback?(result: .Failure(error))
            }
        }
        let dataLoader = dataLoaderForIdentifier(loadDataIdentifier)
        return asyncWithFinishHookBlock(dataLoader, finishCallbackHook: finishCallbackHook)
    }
}


import iAsync_utils
import iAsync_reactiveKit

import ReactiveKit

public enum DataRequestContext<DataLoadContext> {

    case Outside(DataLoadContext)
