       sections = list.sections
       subject.next(Observable2DArrayEvent(change: .deleteSections(IndexSet(sectionDeletes)), source: self))
       subject.next(Observable2DArrayEvent(change: .deleteItems(deletesIndexPaths), source: self))
+      
+      for entry in sectionMoves {
+        subject.next(Observable2DArrayEvent(change: .moveSection(entry.from, entry.to), source: self))
+      }
+      
+      for entry in movesIndexPaths {
+        subject.next(Observable2DArrayEvent(change: .moveItem(entry.from, entry.to), source: self))
+      }
+      
+      
       subject.next(Observable2DArrayEvent(change: .insertSections(IndexSet(sectionInserts)), source: self))
       subject.next(Observable2DArrayEvent(change: .insertItems(insertsIndexPaths), source: self))
       subject.next(Observable2DArrayEvent(change: .endBatchEditing, source: self))
       lock.unlock()
     } else {
-      replace(with: list)
-    }
-  }
-  
-}
-
-
+      replace2D(with: list)
+    }
+  }
+  
+}
+
+

        
        // insertions should alwyas happen to the new section's place
        insertsIndexPaths.append(contentsOf: inserts.map { IndexPath(item: $0, section: entry.new) })
      }
      
      

      let newSectionsMeta = list.sections.map({$0.metadata})
      
      // perform diff on metadata to figure out inserted sections and deleted sections
      let metaDiff = oldSectionsMeta.extendedDiff(newSectionsMeta)
      let metaPatch = metaDiff.patch(from: newSectionsMeta, to: newSectionsMeta)
      
      //let metaDiff = Array.diff(oldSectionsMeta, newSectionsMeta)
      
      var sectionDeletes: [Int] = []
      var sectionInserts: [Int] = []
      var sectionMoves: [(from: Int, to: Int)] = []
      sectionDeletes.reserveCapacity(metaPatch.count)
      sectionInserts.reserveCapacity(metaPatch.count)
      sectionMoves.reserveCapacity(metaPatch.count)
      
      for diffStep in metaPatch {
        switch diffStep {
        case .insertion(let index, _):
          sectionInserts.append(index)
        case .deletion(let index):
          sectionDeletes.append(index)
        case .move(let from, let to):
          sectionMoves.append((from,to))
          //subject.next(ObservableArrayEvent(change: .move(from, to), source: self))
        }
      }
      
      // get sections that stayed there a.k.a neither deleted nor inserted
      var sectionsSame: [(new: Int, old: Int)] = []
      for (i, entry) in newSectionsMeta.enumerated() {
        if let oldIndex = oldSectionsMeta.index(of: entry) {
          sectionsSame.append((new: i, old: oldIndex))
          
        }
