         XCTAssertEqual(o.count + result.inserts.count - result.deletes.count, 4)
     }
     
-    // test_whenDuplicateObjects_thatMovesAreUnique
+    func test_whenInsertingObject_withOldArrayHavingMultiples_thatChangeCountMatches() {
+        let o: [NSObject] = [
+            NSObject(),
+            NSObject(),
+            NSObject(),
+            NSNumber(integerLiteral: 49),
+            NSNumber(integerLiteral: 33),
+            NSString(string: "cat"),
+            NSString(string: "cat"),
+            NSNumber(integerLiteral: 0),
+            NSNumber(integerLiteral: 14),
+        ]
+        var n = o
+        n.insert(NSString(string: "cat"), at: 5)
+        let result = List.diffing(oldArray: o, newArray: n)
+        XCTAssertTrue(result.hasChanges)
+        XCTAssertEqual(o.count + result.inserts.count - result.deletes.count, n.count)
+    }
+    
+    func test_whenMovingDuplicateObjects_thatChangeCountMatches() {
+        let o: [NSObject] = [
+            NSNumber(integerLiteral: 1),
+            NSNumber(integerLiteral: 20),
+            NSNumber(integerLiteral: 14),
+            NSObject(),
+            NSString(string: "cat"),
+            NSObject(),
+            NSNumber(integerLiteral: 4),
+            NSString(string: "dog"),
+            NSString(string: "cat"),
+            NSString(string: "cat"),
+            NSString(string: "fish"),
+            NSObject(),
+            NSString(string: "fish"),
+            NSObject(),
+        ]
+        let n: [NSObject] = [
+            NSNumber(integerLiteral: 1),
+            NSNumber(integerLiteral: 28),
+            NSNumber(integerLiteral: 14),
+            NSString(string: "cat"),
+            NSString(string: "cat"),
+            NSNumber(integerLiteral: 4),
+            NSString(string: "dog"),
+            o[3],
+            NSString(string: "cat"),
+            NSString(string: "fish"),
+            o[11],
+            NSString(string: "fish"),
+            o[13],
+        ]
+        let result = List.diffing(oldArray: o, newArray: n)
+        XCTAssertTrue(result.hasChanges)
+        XCTAssertEqual(o.count + result.inserts.count - result.deletes.count, n.count)
+    }
+    
+    func test_whenDiffingDuplicatesAtTail_withDuplicateAtHead_thatResultHasNoChanges() {
+        let o: [NSObject] = [
+            NSString(string: "cat"),
+            NSNumber(integerLiteral: 1),
+            NSNumber(integerLiteral: 2),
+            NSNumber(integerLiteral: 3),
+            NSString(string: "cat"),
+        ]
+        let n: [NSObject] = [
+            NSString(string: "cat"),
+            NSNumber(integerLiteral: 1),
+            NSNumber(integerLiteral: 2),
+            NSNumber(integerLiteral: 3),
+            NSString(string: "cat"),
+        ]
+        let result = List.diffing(oldArray: o, newArray: n)
+        XCTAssertFalse(result.hasChanges)
+    }
+    
+    func test_whenDuplicateObjects_thatMovesAreUnique() {
+        let o: [NSObject] = [
+            NSString(string: "cat"),
+            NSObject(),
+            NSString(string: "dog"),
+            NSString(string: "dog"),
+            NSObject(),
+            NSObject(),
+            NSString(string: "cat"),
+            NSNumber(integerLiteral: 65),
+        ]
+        let n: [NSObject] = [
+            NSString(string: "cat"),
+            o[1],
+            NSString(string: "dog"),
+            o[4],
+            NSString(string: "dog"),
+            o[5],
+            NSString(string: "cat"),
+            NSString(string: "cat"),
+            NSString(string: "fish"),
+            NSNumber(integerLiteral: 65),
+        ]
+        let result = List.diffing(oldArray: o, newArray: n)
+        XCTAssertTrue(result.hasChanges)
+        XCTAssertEqual(Set(result.moves.map { $0.from }).count, result.moves.count)
+    }
     
     func test_whenMovingObjectShiftsOthers_thatMovesContainRequiredMoves() {
         let o = Array<Int>(arrayLiteral: 1, 2, 3, 4, 5, 6, 7)

        XCTAssertEqual(result.moves, [List.MoveIndex(from: 7, to: 4), List.MoveIndex(from: 5, to: 7)])
    }
    
    func test_whenDeletingObjects_withArrayOfEqualObjects_thatChangeCountMatches() {
        let o = Array<String>(arrayLiteral: "dog", "dog", "dog", "dog")
        let n = Array<String>(arrayLiteral: "dog", "dog")

        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
