<commit_before>
import Foundation
import CoreData


public protocol DataSourceProvider {
    
    associatedtype DataSourceDelegate: DataSourceProviderDelegate
    
    associatedtype ItemType
    
    
    var delegate: DataSourceDelegate? { get set }

    
    func isEmpty() -> Bool
    
    func numberOfSections() -> Int
    
    func numberOfRowsInSection(section: Int) -> Int
    
    func itemAtIndexPath(indexPath: IndexPath) -> ItemType
    
    mutating func deleteItemAtIndexPath(indexPath: IndexPath)
    
    mutating func insertItem(item: ItemType, atIndexPath: IndexPath)
    
    mutating func updateItem(item: ItemType, atIndexPath: IndexPath)
 
    mutating func deleteAllInSection(section: Int)
    
    func titleForHeaderAtSection(section: Int) -> String?
    
}


public protocol DataSourceProviderDelegate {
    
    associatedtype ItemType
    
    
    mutating func providerWillChangeContent()
    
    mutating func providerDidEndChangeContent()
    
    
    mutating func providerDidInsertSectionAtIndex(index: Int)
    
    mutating func providerDidDeleteSectionAtIndex(index: Int)
    
    
    mutating func providerDidInsertItemsAtIndexPaths(items: [ItemType], atIndexPaths: [IndexPath])
    
    mutating func providerDidDeleteItemsAtIndexPaths(items: [ItemType], atIndexPaths: [IndexPath])
    
    mutating func providerDidUpdateItemsAtIndexPaths(items: [ItemType], atIndexPaths: [IndexPath])
    
    mutating func providerDidMoveItem(item: ItemType, atIndexPath: IndexPath, toIndexPath: IndexPath)
    
    mutating func providerDidDeleteAllItemsInSection(section: Int)
}


public class ArrayDataSourceProvider<T, Delegate: DataSourceProviderDelegate>: DataSourceProvider where Delegate.ItemType == T {
    
    public var delegate: Delegate?

    private var arrayItems: [T]

    private var objectChanges: Array<(DataSourceChangeType,[IndexPath], [T])>!
    private var sectionChanges: Array<(DataSourceChangeType,Int)>!
    
    public init() {
        
        self.objectChanges = Array()
        self.sectionChanges = Array()

        arrayItems = [T]()
    }
    
    public func isEmpty() -> Bool {
        
        return arrayItems.isEmpty
    }
    
    public func numberOfSections() -> Int {
        
        return 1
    }
    
    public func numberOfRowsInSection(section: Int) -> Int {
        
        return arrayItems.count
    }
    
    public func itemAtIndexPath(indexPath: IndexPath) -> T {
        
        return arrayItems[indexPath.row]
    }
    
    public func deleteItemAtIndexPath(indexPath: IndexPath) {
        
        let item = arrayItems[indexPath.row]
        
        arrayItems.remove(at: indexPath.row)
        
        delegate?.providerDidDeleteItemsAtIndexPaths(items: [item], atIndexPaths: [indexPath])
    }

    public func insertItem(item: T, atIndexPath indexPath: IndexPath) {
        
        arrayItems.insert(item, at: indexPath.row)
        
        delegate?.providerDidInsertItemsAtIndexPaths(items: [item], atIndexPaths: [indexPath])
    }
    
    public func updateItem(item: T, atIndexPath indexPath: IndexPath) {
        
        var newItems = [T](arrayItems)
    
        newItems.remove(at: indexPath.row)
        
        newItems.insert(item, at: indexPath.row)
        
        self.arrayItems = newItems
        
        delegate?.providerDidUpdateItemsAtIndexPaths(items: [item], atIndexPaths: [indexPath])
    }
    
    public func deleteAllInSection(section: Int) {

        arrayItems.removeAll()
        
        delegate?.providerDidDeleteAllItemsInSection(section: 0)
    }
    
    public func batchUpdates(updatesBlock: VoidCompletion) {
        
        objc_sync_enter(self)
        
        delegate?.providerWillChangeContent()
        
        updatesBlock()
        
        delegate?.providerDidEndChangeContent()

        objc_sync_exit(self)

    }
    
    public func titleForHeaderAtSection(section: Int) -> String? {
        return nil
    }
    
    public func itemsArray() -> [T] {
        
        return arrayItems
        
    }
}

public class FetchedResultsDataSourceProvider<ObjectType: NSManagedObject, Delegate: DataSourceProviderDelegate> : DataSourceProvider where Delegate.ItemType == ObjectType {
    
    public var delegate: Delegate? { didSet {
        
            fetchedResultsControllerDelegate = FetchedResultsControllerDelegate<ObjectType, Delegate>(delegate: delegate!)
        
            fetchedResultsController.delegate = fetchedResultsControllerDelegate
        }
    }
    
    public let fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>
    
    var fetchedResultsControllerDelegate: FetchedResultsControllerDelegate<ObjectType, Delegate>?
    
    public init(fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>) {
        
        self.fetchedResultsController = fetchedResultsController
    }
    <commit_msg>Allowing Array data source to include multiple sections<commit_after>
import Foundation
import CoreData


public protocol DataSourceProvider {
    
    associatedtype DataSourceDelegate: DataSourceProviderDelegate
    
    associatedtype ItemType
    
    
    var delegate: DataSourceDelegate? { get set }

    
    func isEmpty() -> Bool
    
    func numberOfSections() -> Int
    
    func numberOfRowsInSection(section: Int) -> Int
    
    func itemAtIndexPath(indexPath: IndexPath) -> ItemType
    
    mutating func deleteItemAtIndexPath(indexPath: IndexPath)
    
    mutating func insertItem(item: ItemType, atIndexPath: IndexPath)
    
    mutating func updateItem(item: ItemType, atIndexPath: IndexPath)
 
    mutating func deleteAllInSection(section: Int)
    
    func titleForHeaderAtSection(section: Int) -> String?
    
}


public protocol DataSourceProviderDelegate {
    
    associatedtype ItemType
    
    
    mutating func providerWillChangeContent()
    
    mutating func providerDidEndChangeContent()
    
    
    mutating func providerDidInsertSectionAtIndex(index: Int)
    
    mutating func providerDidDeleteSectionAtIndex(index: Int)
    
    
    mutating func providerDidInsertItemsAtIndexPaths(items: [ItemType], atIndexPaths: [IndexPath])
    
    mutating func providerDidDeleteItemsAtIndexPaths(items: [ItemType], atIndexPaths: [IndexPath])
    
    mutating func providerDidUpdateItemsAtIndexPaths(items: [ItemType], atIndexPaths: [IndexPath])
    
    mutating func providerDidMoveItem(item: ItemType, atIndexPath: IndexPath, toIndexPath: IndexPath)
    
    mutating func providerDidDeleteAllItemsInSection(section: Int)
}


public class ArrayDataSourceProvider<T, Delegate: DataSourceProviderDelegate>: DataSourceProvider where Delegate.ItemType == T {
    
    public var delegate: Delegate?

    private var arrayItems: [[T]?]

    private var objectChanges: Array<(DataSourceChangeType,[IndexPath], [T])>!
    private var sectionChanges: Array<(DataSourceChangeType,Int)>!
    
    public init() {
        
        self.objectChanges = Array()
        self.sectionChanges = Array()

        arrayItems = [[T]?]()
    }
    
    public func isEmpty() -> Bool {
        
        return arrayItems.isEmpty
    }
    
    public func numberOfSections() -> Int {
        
        return arrayItems.count
    }
    
    public func numberOfRowsInSection(section: Int) -> Int {

        var itemCount = 0

        if arrayItems.count > section, let array = arrayItems[section] {
            itemCount = array.count
        }

        return itemCount
    }
    
    public func itemAtIndexPath(indexPath: IndexPath) -> T {

        if let array = arrayItems[indexPath.section] {
            return array[indexPath.row]
        }
        preconditionFailure("There was no item at indexPath \(indexPath)")
    }
    
    public func deleteItemAtIndexPath(indexPath: IndexPath) {

        var items = [T]()
        if var array = arrayItems[indexPath.section] {

            let item = array[indexPath.row]
            items.append(item)
            array.remove(at: indexPath.row)
        }

        delegate?.providerDidDeleteItemsAtIndexPaths(items: items, atIndexPaths: [indexPath])
    }

    public func insertItem(item: T, atIndexPath indexPath: IndexPath) {

        if arrayItems.count > indexPath.section, var array = arrayItems[indexPath.section] {

            array.insert(item, at: indexPath.row)
        } else {

            var array = [T]()
            array.insert(item, at: 0)
            arrayItems.insert(array, at: indexPath.section)
        }

        delegate?.providerDidInsertItemsAtIndexPaths(items: [item], atIndexPaths: [indexPath])
    }
    
    public func updateItem(item: T, atIndexPath indexPath: IndexPath) {

        if var array = arrayItems[indexPath.section] {

            array[indexPath.row] = item
        }
        
        delegate?.providerDidUpdateItemsAtIndexPaths(items: [item], atIndexPaths: [indexPath])
    }
    
    public func deleteAllInSection(section: Int) {

        arrayItems.removeAll()
        
        delegate?.providerDidDeleteAllItemsInSection(section: 0)
    }
    
    public func batchUpdates(updatesBlock: VoidCompletion) {
        
        objc_sync_enter(self)
        
        delegate?.providerWillChangeContent()
        
        updatesBlock()
        
        delegate?.providerDidEndChangeContent()

        objc_sync_exit(self)

    }
    
    public func titleForHeaderAtSection(section: Int) -> String? {
        return nil
    }
    
    public func itemsArray(atSection section: Int) -> [T] {

        guard let itemsArray = arrayItems[section] else { return [T]() }

        return itemsArray
    }
}

public class FetchedResultsDataSourceProvider<ObjectType: NSManagedObject, Delegate: DataSourceProviderDelegate> : DataSourceProvider where Delegate.ItemType == ObjectType {
    
    public var delegate: Delegate? { didSet {
        
            fetchedResultsControllerDelegate = FetchedResultsControllerDelegate<ObjectType, Delegate>(delegate: delegate!)
        
            fetchedResultsController.delegate = fetchedResultsControllerDelegate
        }
    }
    
    public let fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>
    
    var fetchedResultsControllerDelegate: FetchedResultsControllerDelegate<ObjectType, Delegate>?
    
    public init(fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>) {
        
        self.fetchedResultsController = fetchedResultsController
    }
    
{'fraction_non_alphanumeric': 0.07488567073170732, 'fraction_numerical': 0.0004763719512195122, 'mean_word_length': 2.790899241603467, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2398845', 'n_tokens_mistral': 2875, 'n_tokens_neox': 2776, 'n_words': 610}