 import iAsync_utils
 
 public enum DataRequestContext<DataLoadContext> {
-    
+
     case Outside(DataLoadContext)
     case CacheUpdateDate(NSDate)
 }
 
 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

}

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

    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):
                //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))
            case .Interrupted:
                doneCallback?(result: .Interrupted)
