   }
 }
 
-private final class DefaultTableViewConfiguration: TableViewConfigurationProtocol {
-	init(animated: Bool, createCell: @escaping (Any, Int, NSTableView) -> NSView?) {
-		self.animated = animated
-		self.createCell = createCell
-	}
-	
-	let animated: Bool
-	let insertAnimation: NSTableViewAnimationOptions = []
-	let deleteAnimation: NSTableViewAnimationOptions = []
-	let measureCell: ((Any, Int, NSTableView) -> CGFloat)? = nil
-	let createCell: (Any, Int, NSTableView) -> NSView?
+public protocol TableViewBond {
+	
+	associatedtype DataSource: DataSourceProtocol
+	
+	var insertAnimation: NSTableViewAnimationOptions? { get }
+	var deleteAnimation: NSTableViewAnimationOptions? { get }
+	
+	func apply(event: DataSourceEvent<DataSource>, to tableView: NSTableView)
+	func heightForRow(at index: Int, tableView: NSTableView, dataSource: DataSource) -> CGFloat?
+	func cellForRow(at index: Int, tableView: NSTableView, dataSource: DataSource) -> NSView?
+}
+
+extension TableViewBond {
+	
+	var insertAnimation: NSTableViewAnimationOptions? {
+		return nil
+	}
+	
+	var deleteAnimation: NSTableViewAnimationOptions? {
+		return nil
+	}
+	
+	public func heightForRow(at index: Int, tableView: NSTableView, dataSource: DataSource) -> CGFloat? {
+		return nil
+	}
+	
+	public func apply(event: DataSourceEvent<DataSource>, to tableView: NSTableView) {
+		switch event.kind {
+		case .reload:
+			tableView.reloadData()
+		case .insertItems(let indexPaths):
+			if !tableView.updating && indexPaths.count > 1 {
+				tableView.beginUpdates()
+				defer { tableView.endUpdates() }
+			}
+			indexPaths.forEach { indexPath in
+				tableView.insertRows(at: IndexSet(integer: indexPath.item), withAnimation: insertAnimation ?? [])
+			}
+		case .deleteItems(let indexPaths):
+			if !tableView.updating && indexPaths.count > 1 {
+				tableView.beginUpdates()
+				defer { tableView.endUpdates() }
+			}
+			indexPaths.forEach { indexPath in
+				tableView.removeRows(at: IndexSet(integer: indexPath.item), withAnimation: deleteAnimation ?? [])
+			}
+		case .reloadItems(let indexPaths):
+			if !tableView.updating && indexPaths.count > 1 {
+				tableView.beginUpdates()
+				defer { tableView.endUpdates() }
+			}
+			indexPaths.forEach { indexPath in
+				tableView.removeRows(at: IndexSet(integer: indexPath.item), withAnimation: deleteAnimation ?? [])
+				tableView.insertRows(at: IndexSet(integer: indexPath.item), withAnimation: insertAnimation ?? [])
+			}
+		case .moveItem(let indexPath, let newIndexPath):
+			tableView.moveRow(at: indexPath.item, to: newIndexPath.item)
+		case .insertSections:
+			fatalError("NSTableView binding does not support sections.")
+		case .deleteSections:
+			fatalError("NSTableView binding does not support sections.")
+		case .reloadSections:
+			fatalError("NSTableView binding does not support sections.")
+		case .moveSection:
+			fatalError("NSTableView binding does not support sections.")
+		case .beginUpdates:
+			tableView.beginUpdates()
+			tableView.updating = true
+		case .endUpdates:
+			tableView.updating = false
+			tableView.endUpdates()
+		}
+	}
+}
+
+extension NSTableView {
+	
+	fileprivate var updating: Bool {
+		get {
+			return objc_getAssociatedObject(self, &NSTableViewUpdatingKey) as? Bool ?? false
+		}
+		set {
+			objc_setAssociatedObject(self, &NSTableViewUpdatingKey, newValue, .OBJC_ASSOCIATION_RETAIN)
+		}
+	}
+}
+
+private var NSTableViewUpdatingKey: UInt8 = 0
+
+private struct DefaultTableViewBond<DataSource: DataSourceProtocol>: TableViewBond {
+	
+	let createCell: (DataSource, Int, NSTableView) -> NSView?
+	
+	func cellForRow(at index: Int, tableView: NSTableView, dataSource: DataSource) -> NSView? {
+		return createCell(dataSource, index, tableView)
+	}
+}
+
+private struct ReloadingTableViewBond<DataSource: DataSourceProtocol>: TableViewBond {
+	
+	let createCell: (DataSource, Int, NSTableView) -> NSView?
+	
+	func cellForRow(at index: Int, tableView: NSTableView, dataSource: DataSource) -> NSView? {
+		return createCell(dataSource, index, tableView)
+	}
+	
+	func apply(event: DataSourceEvent<DataSource>, to tableView: NSTableView) {
+		tableView.reloadData()
+	}
 }
 
 public extension SignalProtocol where Element: DataSourceEventProtocol, Element.DataSource: QueryableDataSourceProtocol, Element.DataSource.Item: Any, Element.DataSource.Index == Int, Error == NoError {

        return
      }

      dataSource.value = event.dataSource

      guard configurator.animated else {
        tableView.reloadData()
        return
      }

      switch event.kind {
      case .reload:
        tableView.reloadData()
      case .insertItems(let indexPaths):
        if !updating && indexPaths.count > 1 {
          tableView.beginUpdates()
          defer { tableView.endUpdates() }
        }
        indexPaths.forEach { indexPath in
          tableView.insertRows(at: IndexSet(integer: indexPath.item), withAnimation: configurator.insertAnimation)
        }
      case .deleteItems(let indexPaths):
        if !updating && indexPaths.count > 1 {
          tableView.beginUpdates()
          defer { tableView.endUpdates() }
        }
        indexPaths.forEach { indexPath in
          tableView.removeRows(at: IndexSet(integer: indexPath.item), withAnimation: configurator.deleteAnimation)
        }
      case .reloadItems(let indexPaths):
        if !updating && indexPaths.count > 1 {
          tableView.beginUpdates()
          defer { tableView.endUpdates() }
        }
        indexPaths.forEach { indexPath in
          tableView.removeRows(at: IndexSet(integer: indexPath.item), withAnimation: configurator.deleteAnimation)
          tableView.insertRows(at: IndexSet(integer: indexPath.item), withAnimation: configurator.insertAnimation)
        }
      case .moveItem(let indexPath, let newIndexPath):
        tableView.moveRow(at: indexPath.item, to: newIndexPath.item)
      case .insertSections:
        fatalError("NSTableView binding does not support sections.")
      case .deleteSections:
        fatalError("NSTableView binding does not support sections.")
      case .reloadSections:
        fatalError("NSTableView binding does not support sections.")
      case .moveSection:
        fatalError("NSTableView binding does not support sections.")
      case .beginUpdates:
        tableView.beginUpdates()
        updating = true
      case .endUpdates:
        updating = false
        tableView.endUpdates()
      }
    }
    
    return serialDisposable
  }
}

    )

    let serialDisposable = SerialDisposable(otherDisposable: nil)

    serialDisposable.otherDisposable = observeIn(ImmediateOnMainExecutionContext).observeNext { [weak tableView] event in
      guard let tableView = tableView else {
