         j -= 1
       }
     }
-
+    
     // Reverse the result
     return backtrack.reversed()
   }
 }
 
+extension MutableObservableArray {
+  
+  func replace(with array: [Item]) {
+    lock.atomic {
+      self.array = array
+      subject.next(ObservableArrayEvent(change: .replace, source: self))
+    }
+  }
+  
+}
+
 extension MutableObservableArray where Item: Equatable {
-
+  
   public func replace(with array: [Item], performDiff: Bool) {
-    lock.atomic {
-      if performDiff {
+    if performDiff {
+      lock.atomic {
         let diff = Array.diff(self.array, array)
-
+        
         var deletes: [Int] = []
         var inserts: [Int] = []
         deletes.reserveCapacity(diff.count)
         inserts.reserveCapacity(diff.count)
-
+        
         for diffStep in diff {
           switch diffStep {
           case .insert(_, let index):

            deletes.append(index)
          }
        }

        subject.next(ObservableArrayEvent(change: .beginBatchEditing, source: self))
        self.array = array
        subject.next(ObservableArrayEvent(change: .deletes(deletes), source: self))
        subject.next(ObservableArrayEvent(change: .inserts(inserts), source: self))
        subject.next(ObservableArrayEvent(change: .endBatchEditing, source: self))
      } else {
        self.array = array
        subject.next(ObservableArrayEvent(change: .replace, source: self))
      }
    }
  }
}

// MARK: DataSourceProtocol conformation

extension ObservableArrayEvent: DataSourceEventProtocol {
  
  public var kind: DataSourceEventKind {
    switch change {
    case .initial, .replace:
