     }
   }
 
-
-  // External Interface
-  func appendItem(item: T) {
-    dispatch_async(dataMutationDispatchQueue) {
-      if self.items.count == 0 {
-        self.items.append([])
-      }
-      self.pendingChanges.append(DataChange.Insert(item, NSIndexPath(forItem: self.items[0].count, inSection: 0))) // This must happen before items array is mutated
-      self.items[0].append(item)
-      if let lastOperation = self.mutateDisplayQueue.operations.last {
-        if lastOperation.executing {
-          let applyChangeOp = ApplyDataSourceChangeOperation(safeDataSource: self, collectionView: self.collectionView)
-          self.mutateDisplayQueue.addOperation(applyChangeOp)
-        }
-      } else {
+  func addApplyOperationIfNeeded() {
+    if let lastOperation = self.mutateDisplayQueue.operations.last {
+      if lastOperation.executing {
         let applyChangeOp = ApplyDataSourceChangeOperation(safeDataSource: self, collectionView: self.collectionView)
         self.mutateDisplayQueue.addOperation(applyChangeOp)
       }
-    }
-  }
-
-  // Instead allow consumer to give you a closure that we call and provide current 
+    } else {
+      let applyChangeOp = ApplyDataSourceChangeOperation(safeDataSource: self, collectionView: self.collectionView)
+      self.mutateDisplayQueue.addOperation(applyChangeOp)
+    }
+  }
+
+
+  // External Interface
+  public func appendItem(item: T) {
+    dispatch_async(dataMutationDispatchQueue) {
+      // Automatically creates section 0 if it does not exist already.
+      if self.items.count == 0 {
+        self.unsafeAppendSectionWithItem(item)
+      } else {
+//        self.unsafeAppendItem(item, toSection: 0) // TODO: Remove ObjC msg_send overhead
+
+        let section = 0
+        guard section < self.items.count else { return } // TODO: Add more of these validations
+        let startingIndex = self.items[section].count
+        self.pendingChanges.append(.InsertItem(item, NSIndexPath(forItem: startingIndex, inSection: section)))
+        self.items[section].append(item)
+        self.addApplyOperationIfNeeded()
+      }
+    }
+  }
+
+  public func appendItem(item: T, toSection section: Int) {
+    dispatch_async(dataMutationDispatchQueue) {
+      self.unsafeAppendItem(item, toSection: section)
+    }
+  }
+
+  @nonobjc @inline(__always)
+  func unsafeAppendItem(item: T, toSection section: Int) {
+    guard section < self.items.count else { return } // TODO: Add more of these validations
+    let startingIndex = self.items[section].count
+    self.pendingChanges.append(.InsertItem(item, NSIndexPath(forItem: startingIndex, inSection: section)))
+    self.items[section].append(item)
+    self.addApplyOperationIfNeeded()
+  }
+
+  public func appendSectionWithItems(items: [T]) {
+    dispatch_async(dataMutationDispatchQueue) {
+      self.unsafeAppendSectionWithItems(items)
+    }
+  }
+
+  @nonobjc @inline(__always)
+  func unsafeAppendSectionWithItems(items: [T]) {
+    let newSectionIndex = self.items.count // This must happen first.
+    self.pendingChanges.append(.AppendSection)
+    self.items.append([])
+    let indexPaths = items.enumerate().map { (index, item) -> NSIndexPath in
+      return NSIndexPath(forItem: index, inSection: newSectionIndex)
+    }
+    self.pendingChanges.append(.InsertItems(items, indexPaths))
+    self.items[newSectionIndex] = items
+    self.addApplyOperationIfNeeded()
+  }
+
+  @nonobjc @inline(__always)
+  func unsafeAppendSectionWithItem(item: T) {
+    let newSectionIndex = self.items.count // This must happen first.
+    self.pendingChanges.append(.AppendSection)
+    self.items.append([])
+    let indexPath = NSIndexPath(forItem: 0, inSection: newSectionIndex)
+    self.pendingChanges.append(.InsertItem(item, indexPath))
+    self.items[newSectionIndex].append(item)
+    self.addApplyOperationIfNeeded()
+  }
+
+  // Instead allow consumer to give you a closure that we call and provide current
   //   data state and they can use that state to apply mutations
-  func insertItem(item: T, atIndex: Int) {
+  public func insertItemWithClosure(getInsertionIndexPath: ([[T]]) -> (item: T, indexPath: NSIndexPath)?) {
     dispatch_async(dataMutationDispatchQueue) {
-
-    }
-  }
-
-  func removeItemAtIndex(index: Int) {
+      guard let insertion = getInsertionIndexPath(self.items) else { return }
+      insertion.indexPath.item
+      self.pendingChanges.append(.InsertItem(insertion.item, insertion.indexPath))
+      self.items[insertion.indexPath.section].insert(insertion.item, atIndex: insertion.indexPath.item)
+      self.addApplyOperationIfNeeded()
+    }
+  }
+
+  public func deleteItemWithClosure(getDeletionIndexPath: ([[T]]) -> NSIndexPath?) {
     dispatch_async(dataMutationDispatchQueue) {
-
-    }
-  }
-
-
-
-  func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+      self.items[0].count
+      guard let indexPath = getDeletionIndexPath(self.items) else { return }
+      self.pendingChanges.append(.DeleteItem(indexPath))
+      self.items[indexPath.section].removeAtIndex(indexPath.item)
+      self.addApplyOperationIfNeeded()
+      self.items[0].count
+    }
+  }
+
+  public func deleteLastItemInSection(sectionIndex: Int) {
+    dispatch_async(dataMutationDispatchQueue) {
+      if self.items[sectionIndex].count > 0 {
+        self.items[sectionIndex].removeLast()
+        self.pendingChanges.append(.DeleteLastItem(sectionIndex))
+        self.addApplyOperationIfNeeded()
+      }
+    }
+  }
+
+
+
+  public func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
     return dataSourceItems[section].count
   }
 
-  func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
-    return cellProvider.collectionView(collectionView, cellForItem: items[indexPath.section][indexPath.row], atIndexPath: indexPath)
-  }
-
-  func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
+  public func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
+    let cell = cellForItemAtIndexPath(collectionView, dataSourceItems[indexPath.section][indexPath.row], indexPath)
+    return cell
+  }
+
+  public func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
     return dataSourceItems.count
   }
 

    super.init()
  }

  override func run() {

    safeDataSource.dequeuPendingChangesAndOnComplete { changes in
      dispatch_async(dispatch_get_main_queue()) {
        // Got changes, now head on over to collection view
        self.collectionView.performBatchUpdates({
          if self.collectionView.numberOfSections() == 0 {
            self.safeDataSource.dataSourceItems.append([])
            self.collectionView.insertSections(NSIndexSet(index: 0))
          }


          // Perform changes
          var indexPaths: [NSIndexPath] = []
          for change in changes {
            if case .Insert(let item, let indexPath) = change {
              indexPaths.append(indexPath)
              // TODO: Validate that item's index path matches index in array below:
              self.safeDataSource.dataSourceItems[0].append(item)
            }
          }

          indexPaths
          self.collectionView.insertItemsAtIndexPaths(indexPaths)
//          self.collectionView.deleteItemsAtIndexPaths([])
          // Plus reload operations
          // Plus move operations

        }) { completed in
          self.finishedExecutingOperation()
        }
      }
    }

  }


}

class ColorCellProvider: NSObject, SafeCollectionViewDataSource {

  func collectionView<T>(collectionView: UICollectionView, cellForItem item: T, atIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath)
    if let color = item as? Color {
      cell.backgroundColor = UIColor(color: color)
    }
    return cell
  }

}







/*
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

  init(safeDataSource: SafeDataSource<T>, collectionView: UICollectionView) {
    self.safeDataSource = safeDataSource
