 		}
 	}
 	
+	private struct Update {
+		var insertSection: [Int: TreeNode] = [:]
+		var deleteSection = IndexSet()
+		var insertObject: [IndexPath: TreeNode] = [:]
+		var deleteObject = [IndexPath]()
+		var moveObject: [IndexPath: IndexPath] = [:]
+		var update: [IndexPath: Any] = [:]
+	}
+	private var update: Update?
+	
 	func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
+		guard sectionNode != nil else {return}
+		self.update = Update()
 		treeController?.beginUpdates()
 	}
 	
 	func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
+		guard update != nil else {return}
 		guard let sectionNode = self.sectionNode else {return}
 		switch type {
 		case .insert:
-			children.insert(sectionNode.init(section: sectionInfo, objectNode: self.objectNode), at: sectionIndex)
+			update?.insertSection[sectionIndex] = sectionNode.init(section: sectionInfo, objectNode: self.objectNode)
+//			children.insert(sectionNode.init(section: sectionInfo, objectNode: self.objectNode), at: sectionIndex)
 		case .delete:
-			children.remove(at: sectionIndex)
+			update?.deleteSection.insert(sectionIndex)
+//			children.remove(at: sectionIndex)
 		default:
 			break
 		}
 	}
 	
 	func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
-		guard self.sectionNode == nil else {return}
+		guard update != nil else {return}
+//		guard self.sectionNode == nil else {return}
 		switch type {
 		case .insert:
-			children.insert(objectNode.init(object: anObject as! ResultType), at: newIndexPath!.row)
+			update?.insertObject[newIndexPath!] = objectNode.init(object: anObject as! ResultType)
+//			children.insert(objectNode.init(object: anObject as! ResultType), at: newIndexPath!.row)
 		case .delete:
-			children.remove(at: indexPath!.row)
+			update?.deleteObject.append(indexPath!)
+//			children.remove(at: indexPath!.row)
 		case .move:
-			children.remove(at: indexPath!.row)
-			children.insert(objectNode.init(object: anObject as! ResultType), at: newIndexPath!.row)
+			update?.deleteObject.append(indexPath!)
+			update?.insertObject[newIndexPath!] = objectNode.init(object: anObject as! ResultType)
+//			update?.moveObject[indexPath]
+//			children.remove(at: indexPath!.row)
+//			children.insert(objectNode.init(object: anObject as! ResultType), at: newIndexPath!.row)
 		case .update:
-			children[newIndexPath!.row] = objectNode.init(object: anObject as! ResultType)
+			update?.update[newIndexPath!] = anObject
+//			children[newIndexPath!.row] = objectNode.init(object: anObject as! ResultType)
 		}
 	}
 	
 	
 	func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
+		guard let update = update else {return}
+		
+		if !update.deleteSection.isEmpty {
+			children.remove(at: update.deleteSection)
+		}
+		for i in update.insertSection.sorted(by: {$0.key < $1.key}) {
+			children.insert(i.value, at: i.key)
+		}
+		for i in update.deleteObject.sorted(by: > ) {
+			children[i.section].children.remove(at: i.row)
+		}
+		for (i, value) in update.insertObject.sorted(by: {$0.key < $1.key}) {
+//			children.insert(i.value, at: i.key)
+			children[i.section].children.insert(value, at: i.row)
+		}
+		
 		treeController?.endUpdates()
+		self.update = nil
 	}
 }
 

		node.estimatedHeight = cell.bounds.size.height
	}
	
	
	
	//MARK - Private
	
	fileprivate func removeNodes(at range: CountableRange<Int>) {
		for node in flattened[range] {

		let start = range.lowerBound
		var selections = [IndexPath]()
		
		let animation = UIView.areAnimationsEnabled ? UITableViewRowAnimation.fade : .none
		
		nodes.changes(from: from) { (old, new, type) in
			switch type {
			case .insert:
