 
 // MARK: -
 
-open class PersistentContainer<Context: NSManagedObjectContext> {
-    
-    // MARK: -
-    
-    fileprivate let rawValue: NSPersistentContainer
+open class PersistentContainer: NSPersistentContainer {
+    
+    // MARK: -
+    
     fileprivate let enableUbiquity: Bool
-
+    
     // MARK: -
     
     public init(bundle: Bundle = Bundle.main, storageType: StorageType = .disk, name: String? = nil, managedObjectModel: NSManagedObjectModel? = nil, managedObjectModelURL: URL? = nil, persistentStoreURL: URL? = nil, ubiquitousContainerIdentifier: String? = nil, ubiquitousContentRelativePath: String? = nil, ubiquitousContentName: String? = nil) throws {
         //
         guard let name = name ?? bundle.bundleIdentifier else {
-            throw Error.invalidName
+            throw PersistentContainerError.invalidName
         }
         
         guard let managedObjectModelURL = managedObjectModelURL ?? bundle.managedObjectModelURL(forManagedObjectModelName: name) else {
-            throw Error.invalidManagedObjectModelURL
+            throw PersistentContainerError.invalidManagedObjectModelURL
         }
         
         guard let managedObjectModel = managedObjectModel ?? NSManagedObjectModel(contentsOf: managedObjectModelURL) ?? NSManagedObjectModel.mergedModel(from: [bundle]) else {
-            throw Error.managedObjectModelNotFound
-        }
-
+            throw PersistentContainerError.managedObjectModelNotFound
+        }
+        
         guard let persistentStoreURL = persistentStoreURL ?? bundle.persistentStoreURL(forManagedObjectModelName: name, applicationName: name) else {
-            throw Error.invalidPersistentStoreURL
-        }
-        
-        //
-        self.rawValue = HelperPersistentContainer(name: name, managedObjectModel: managedObjectModel)
+            throw PersistentContainerError.invalidPersistentStoreURL
+        }
+        
+        //
         self.enableUbiquity = (ubiquitousContainerIdentifier != nil)
+        super.init(name: name, managedObjectModel: managedObjectModel)
         
         //
         if storageType == .disk {

    
}

// MARK: -

fileprivate final class HelperPersistentContainer<Context: NSManagedObjectContext>: NSPersistentContainer {
    
    fileprivate override lazy var viewContext: NSManagedObjectContext = {
        let context = Context(concurrencyType: .mainQueueConcurrencyType)

        context.persistentStoreCoordinator = self.persistentStoreCoordinator
        
        context.automaticallyMergesChangesFromParent = true
        context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
        
        

        return context
    }()
    
    fileprivate override func newBackgroundContext() -> NSManagedObjectContext {
        let context = Context(concurrencyType: .privateQueueConcurrencyType)
        
        context.persistentStoreCoordinator = self.persistentStoreCoordinator
        
        context.automaticallyMergesChangesFromParent = true
        context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
        
        return context
    }
    
}


// MARK: -

extension PersistentContainer {

    public enum StorageType {
        case disk
        case memory
    }

}

// MARK: -

extension PersistentContainer {

    public enum Error: Swift.Error {
        case invalidName
        case invalidManagedObjectModelURL
        case managedObjectModelNotFound
        case invalidPersistentStoreURL
    }

}

// MARK: -


    
}

// MARK: -

open class GenericPersistentContainer<Context: NSManagedObjectContext> {
    
    // MARK: -
    
    fileprivate final class HelperPersistentContainer<Context: NSManagedObjectContext>: PersistentContainer {
        
        fileprivate override lazy var viewContext: NSManagedObjectContext = {
            let context = Context(concurrencyType: .mainQueueConcurrencyType)
            
            context.persistentStoreCoordinator = self.persistentStoreCoordinator
            
            context.automaticallyMergesChangesFromParent = true
            context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
            
            return context
        }()
        
        fileprivate override func newBackgroundContext() -> NSManagedObjectContext {
            let context = Context(concurrencyType: .privateQueueConcurrencyType)
            
            context.persistentStoreCoordinator = self.persistentStoreCoordinator
            
            context.automaticallyMergesChangesFromParent = true
            context.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
            
            return context
        }
        
    }

    
    // MARK: -
    
    fileprivate let rawValue: NSPersistentContainer

    // MARK: -
    
    public init(bundle: Bundle = Bundle.main, storageType: StorageType = .disk, name: String? = nil, managedObjectModel: NSManagedObjectModel? = nil, managedObjectModelURL: URL? = nil, persistentStoreURL: URL? = nil, ubiquitousContainerIdentifier: String? = nil, ubiquitousContentRelativePath: String? = nil, ubiquitousContentName: String? = nil) throws {
        self.rawValue = try HelperPersistentContainer(bundle: bundle, storageType: storageType, name: name, managedObjectModel: managedObjectModel, managedObjectModelURL: managedObjectModelURL, persistentStoreURL: persistentStoreURL, ubiquitousContainerIdentifier: ubiquitousContainerIdentifier, ubiquitousContentRelativePath: ubiquitousContentRelativePath, ubiquitousContentName: ubiquitousContentName)
    }

    // MARK: -

    public final var viewContext: Context {
        return unsafeDowncast(self.rawValue.viewContext, to: Context.self)
    }
