 	
 	@discardableResult
 	public func bind(to tableView: NSTableView, animated: Bool = true, createCell: @escaping (DataSource, Int, NSTableView) -> NSView?) -> Disposable {
-		let configurator = DefaultTableViewConfiguration(animated: animated) { (source, index, tableView) -> NSView? in
-			return createCell(source as! DataSource, index, tableView)
-		}
-		return bind(to: tableView, configurator: configurator)
-	}
-	
-  @discardableResult
-	public func bind(to tableView: NSTableView, configurator: TableViewConfigurationProtocol) -> Disposable {
-		
+		if animated {
+			return bind(to: tableView, using: DefaultTableViewBond<DataSource>(createCell: createCell))
+		} else {
+			return bind(to: tableView, using: ReloadingTableViewBond<DataSource>(createCell: createCell))
+		}
+	}
+	
+	@discardableResult
+	public func bind<B: TableViewBond>(to tableView: NSTableView, using bond: B) -> Disposable where B.DataSource == DataSource {
+	
     let dataSource = Property<DataSource?>(nil)
 
-		if let measureCell = configurator.measureCell {
-      tableView.reactive.delegate.feed(
-				property: dataSource,
-				to: #selector(NSTableViewDelegate.tableView(_:heightOfRow:)),
-				map: { (dataSource: DataSource?, tableView: NSTableView, row: Int) -> CGFloat in measureCell(dataSource!, row, tableView) }
-      )
-		}
-		
+		tableView.reactive.delegate.feed(
+			property: dataSource,
+			to: #selector(NSTableViewDelegate.tableView(_:heightOfRow:)),
+			map: { (dataSource: DataSource?, tableView: NSTableView, row: Int) -> CGFloat in
+				guard let dataSource = dataSource else { return tableView.rowHeight }
+				return bond.heightForRow(at: row, tableView: tableView, dataSource: dataSource) ?? tableView.rowHeight
+		})
+	
     tableView.reactive.delegate.feed(
       property: dataSource,
       to: #selector(NSTableViewDelegate.tableView(_:viewFor:row:)),
       map: { (dataSource: DataSource?, tableView: NSTableView, _: NSTableColumn, row: Int) -> NSView? in
-        return configurator.createCell(dataSource!, row, tableView)
+				guard let dataSource = dataSource else { return nil }
+        return bond.cellForRow(at: row, tableView: tableView, dataSource: dataSource)
       }
     )
 

//  Copyright © 2016 Swift Bond. All rights reserved.
//

import AppKit
import ReactiveKit

public protocol TableViewConfigurationProtocol {
	var animated: Bool { get }
	var insertAnimation: NSTableViewAnimationOptions { get }
	var deleteAnimation: NSTableViewAnimationOptions { get }
	var measureCell: ((Any, Int, NSTableView) -> CGFloat)? { get }
	var createCell: (Any, Int, NSTableView) -> NSView? { get }
}

public extension ReactiveExtensions where Base: NSTableView {

  public var delegate: ProtocolProxy {

        return
      }

			let event = event._unbox
      dataSource.value = event.dataSource
			bond.apply(event: event, to: tableView)
		}
		
    return serialDisposable
  }
}
