         
         // 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 = Array.diff(oldSectionsMeta, newSectionsMeta)
      
      var sectionDeletes: [Int] = []
      var sectionInserts: [Int] = []
      sectionDeletes.reserveCapacity(metaDiff.count)
      sectionInserts.reserveCapacity(metaDiff.count)
      
      for diffStep in metaDiff {
        switch diffStep {
        case .insert(_, let index):
          sectionInserts.append(index)
        case .delete(_, let index):
          sectionDeletes.append(index)
        }
      }
      
      // get sections that stayed 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) {
          // TODO: make sure this section is not in sectionDeletes or sectionInserts
          sectionsSame.append((new: i, old: oldIndex))
          
        }

      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 {
      replace2D(with: list)
    }
  }
  
}


