     public var description: String {
         switch self {
         case .Insertion(let item, let at):
-            return "Inserted \(item) at indexpath \(at)"
+            return "INSERTED \(item) AT index \(at.row)"
             
         case .Deletion(let item, let at):
-            return "Deleted \(item) from indexpath \(at)"
+            return "DELETED \(item) FROM index \(at.row)"
             
         case .Move(let item, let from, let to):
-            return "Moved \(item) from indexpath \(from) to indexpath \(to)"
+            return "MOVED \(item) FROM index \(from.row) TO index \(to.row)"
             
         case .Update(let item, let at, let changes):
-            return "Updated \(changes) of \(item) at indexpath \(at)"
-        }
-    }
-}
-
-func ==<T>(lhs: Change<T>, rhs: Change<T>) -> Bool {
+            return "UPDATES \(changes) OF \(item) AT index \(at.row)"
+        }
+    }
+}
+
+public func ==<T>(lhs: Change<T>, rhs: Change<T>) -> Bool {
     switch (lhs, rhs) {
     case (.Insertion(let lhsResult, let lhsIndexPath), .Insertion(let rhsResult, let rhsIndexPath)) where lhsResult == rhsResult && lhsIndexPath == rhsIndexPath : return true
     case (.Deletion(let lhsResult, let lhsIndexPath), .Deletion(let rhsResult, let rhsIndexPath)) where lhsResult == rhsResult && lhsIndexPath == rhsIndexPath : return true

    public func databaseWillCommit() throws { }
    public func databaseDidRollback(db: Database) { }
    public func databaseDidCommit(db: Database) {
        let newRecords = T.fetchAll(db, self.sql)
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
            let oldRecords = self.fetchedResults
            
            // horrible diff computation
            dispatch_async(dispatch_get_main_queue()) {
                self.delegate?.controllerWillUpdate(self)
                
                // after controllerWillChangeContent
                self.fetchedResults = newRecords
                
                // notify horrible diff computation
                for update in self.diff(fromRows: oldRecords!, toRows: newRecords) {
                    self.delegate?.controllerUpdate(self, update: update)
                }
                


    
    /// Returns the fetched object at a given indexPath.
    public func resultAtIndexPath(indexPath: NSIndexPath) -> T? {
        if let result = fetchedResults?[indexPath.indexAtPosition(1)] {
            return result
        } else {
            return nil
        }
    }
    
    /// Returns the indexPath of a given object.
    public func indexPathForResult(result: T) -> NSIndexPath? {
        return nil
    }

    public func changesAreEquivalent(change: Change<T>, otherChange: Change<T>) -> Bool {
        switch (change, otherChange) {
        case (.Move(let item1, let from1, let to1), .Move(let item2, let from2, let to2)):
            return (from1 == to2 && to1 == from2 && item1 == resultAtIndexPath(from2) && item2 == resultAtIndexPath(from1))
        default:
            return false
        }
    }

    // MARK: - Not public
    
    func fetchResults() -> [T] {
        return databaseQueue.inDatabase { db in
            T.fetchAll(db, self.sql)
        }
    }
    
    static func diff(fromRows s: [T], toRows t: [T]) -> [Change<T>] {
        
        let sourceCount = s.count
        let targetCount = t.count
