 extension String: Diffable {
     var diffIdentifier: AnyHashable {
         return self
+    }
+}
+
+class TestObject : Diffable, Equatable {
+    let diffIdentifier: AnyHashable
+    let value: Int
+    
+    init(diffIdentifier: AnyHashable, value: Int) {
+        self.diffIdentifier = diffIdentifier
+        self.value = value
+    }
+    
+    static func ==(lhs: TestObject, rhs: TestObject) -> Bool {
+        return (lhs === rhs) || (lhs.diffIdentifier == rhs.diffIdentifier && lhs.value == rhs.value)
+    }
+}
+
+class TestObjectRef : Diffable, Equatable {
+    let diffIdentifier: AnyHashable
+    let value: Int
+    
+    init(diffIdentifier: AnyHashable, value: Int) {
+        self.diffIdentifier = diffIdentifier
+        self.value = value
+    }
+    
+    static func ==(lhs: TestObjectRef, rhs: TestObjectRef) -> Bool {
+        return lhs === rhs
+    }
+}
+
+extension NSObject : Diffable {
+    var diffIdentifier: AnyHashable {
+        return self.hash
     }
 }
 

            ("test_whenSwappingObjects_thatResultHasMoves", test_whenSwappingObjects_thatResultHasMoves),
            ("test_whenMovingObjectsTogether_thatResultHasMoves", test_whenMovingObjectsTogether_thatResultHasMoves),
            ("test_whenSwappingObjects_thatResultHasMoves2", test_whenSwappingObjects_thatResultHasMoves2),
            ("test_whenDiffingWordsFromPaper_thatInsertsMatchPaper", test_whenDiffingWordsFromPaper_thatInsertsMatchPaper),
            ("test_whenDiffingWordsFromPaper_thatDeletesMatchPaper", test_whenDiffingWordsFromPaper_thatDeletesMatchPaper),
            ("test_whenDeletingItems_withInserts_withMoves_thatResultHasInsertsMovesAndDeletes", test_whenDeletingItems_withInserts_withMoves_thatResultHasInsertsMovesAndDeletes),
            ("test_whenDeletingObjects_withArrayOfEqualObjects_thatChangeCountMatches", test_whenDeletingObjects_withArrayOfEqualObjects_thatChangeCountMatches),
            ("test_whenInsertingObjects_withArrayOfEqualObjects_thatChangeCountMatches", test_whenInsertingObjects_withArrayOfEqualObjects_thatChangeCountMatches),
            ("test_whenMovingObjectShiftsOthers_thatMovesContainRequiredMoves", test_whenMovingObjectShiftsOthers_thatMovesContainRequiredMoves),
            ("test_whenDiffing_thatOldIndexesMatch", test_whenDiffing_thatOldIndexesMatch),
            ("test_whenDiffing_thatNewIndexesMatch", test_whenDiffing_thatNewIndexesMatch),

        XCTAssertEqual(result.moves, [List.MoveIndex(from: 3, to: 1), List.MoveIndex(from: 2, to: 3)])
    }
    
    func test_whenObjectEqualityChanges_thatResultHasUpdates() {
        let o = [
            TestObject(diffIdentifier: "0", value: 0),
            TestObject(diffIdentifier: "1", value: 1),
            TestObject(diffIdentifier: "2", value: 2),
        ]
        let n = [
            TestObject(diffIdentifier: "0", value: 0),
            TestObject(diffIdentifier: "1", value: 3), // value updated from 1 to 3
            TestObject(diffIdentifier: "2", value: 2),
        ]
        let result = List.diffing(oldArray: o, newArray: n)
        XCTAssertTrue(result.hasChanges)
        XCTAssertEqual(result.updates, IndexSet(integer: 1))
        XCTAssertEqual(result.changeCount, 1)
    }
    
    func test_whenDiffingWordsFromPaper_thatInsertsMatchPaper() {
        // http://dl.acm.org/citation.cfm?id=359467&dl=ACM&coll=DL&CFID=529464736&CFTOKEN=43088172
