 
 
 
+
+/*
+switch change {
+case .AppendSection:
+  let x = 1
+case .AppendSections(let numberOfSections): // Number of sections
+  let x = 1
+case .InsertSection(let sectionIndex): // Section Index
+  let x = 1
+case .InsertSections(let indexSet):
+  let x = 1
+case .DeleteSection(let sectionIndex): // Section Index
+  let x = 1
+case .DeleteSections(let indexSet):
+  let x = 1
+case .DeleteLastSection:
+  let x = 1
+case .DeleteSectionsStartingAtIndex(let sectionIndex):
+  let x = 1
+case .MoveSection(let fromSectionIndex, let toSectionIndex):
+  // Item
+  let x = 1
+case .AppendItem(let item, let sectionIndex): // Item, Section Index
+  let x = 1
+case .AppendItems(let items, let sectionIndex): // Items, Section Index
+  let x = 1
+case .InsertItem(let item, let indexPath):
+  let x = 1
+case .InsertItems(let items, let indexPaths):
+  let x = 1
+case .DeleteItem(let indexPath):
+  let x = 1
+case .DeleteItems(let indexPaths):
+  let x = 1
+case .DeleteLastItem(let sectionIndex): // Section Index
+  let x = 1
+case .DeleteItemsStartingAtIndexPath(let indexPath): // Will delete all items from index path forward for section
+  let x = 1
+case .MoveItem(let fromIndexPath, let toIndexPath):
+  let x = 1
+}
+*/
+
+
+
 class ApplyDataSourceChangeOperation<T>: AsyncOperation {
   let safeDataSource: SafeDataSource<T>
   let collectionView: UICollectionView
-//  let workingQueue = dispatch_queue_create("com.rcach.safeDataSourceKit.applyDataSourceChangeOperation", DISPATCH_QUEUE_SERIAL)
 
   init(safeDataSource: SafeDataSource<T>, collectionView: UICollectionView) {
     self.safeDataSource = safeDataSource


}

let cellProvider = ColorCellProvider()

let flowLayout = UICollectionViewFlowLayout()
flowLayout.itemSize = CGSizeMake(10, 10)
let collectionView = UICollectionView(frame: CGRectZero, collectionViewLayout: flowLayout)
let safeDataSource = SafeDataSource<Color>(collectionView: collectionView, cellProvider: cellProvider)
collectionView.dataSource = safeDataSource
collectionView.frame = CGRectMake(0, 0, 500, 1000)
collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")


  }
}

private enum DataChange<T> {
  // Section
  case AppendSection
  case AppendSections(Int) // Number of sections
  case InsertSection(Int) // Section Index
  case InsertSections(NSIndexSet)
  case DeleteSection(Int) // Section Index
  case DeleteSections(NSIndexSet)
  case DeleteLastSection
  case DeleteSectionsStartingAtIndex(Int)
  case MoveSection(Int, Int)
  // Item
  case AppendItem(T, Int) // Item, Section Index
  case AppendItems([T], Int) // Items, Section Index
  case InsertItem(T, NSIndexPath)
  case InsertItems([T], [NSIndexPath])
  case DeleteItem(NSIndexPath)
  case DeleteItems([NSIndexPath])
  case DeleteLastItem(Int) // Section Index
  case DeleteItemsStartingAtIndexPath(NSIndexPath) // Will delete all items from index path forward for section
  case MoveItem(NSIndexPath, NSIndexPath)
}


public class SafeDataSource<T>: NSObject, UICollectionViewDataSource {
  public typealias CellForItemAtIndexPath = (UICollectionView, T, NSIndexPath) -> UICollectionViewCell

  let collectionView: UICollectionView
  var dataSourceItems: [[T]] = [] // Only change this on main thread an coordinate it with batch insertion completion.
  var items: [[T]] = []
  private var pendingChanges: [DataChange<T>] = []

  let cellForItemAtIndexPath: CellForItemAtIndexPath

  let mutateDisplayQueue = SerialOperationQueue()
  let dataMutationDispatchQueue = dispatch_queue_create("com.rcach.safeDataSourceKit.dataMutation", DISPATCH_QUEUE_SERIAL)

  public convenience init(items: [[T]], collectionView: UICollectionView, cellForItemAtIndexPath: CellForItemAtIndexPath) {
    self.init(collectionView: collectionView, cellForItemAtIndexPath: cellForItemAtIndexPath)
    self.dataSourceItems = items
    self.items = items
  }


  public init(collectionView: UICollectionView, cellForItemAtIndexPath: CellForItemAtIndexPath) {
    self.collectionView = collectionView
    self.cellForItemAtIndexPath = cellForItemAtIndexPath
    super.init()
    self.collectionView.dataSource = self
  }

  private func dequeuPendingChangesAndOnComplete(onComplete: [DataChange<T>] -> Void) { // TODO: Think about taking in the queue to call the on complete closure.
    dispatch_async(dataMutationDispatchQueue) {
      let pendingChangesToDequeue = self.pendingChanges
      self.pendingChanges.removeAll(keepCapacity: true)
