     }
     
     private func registerCell(with identifier: String) {
-        switch cell(forIdentifier: identifier) {
+        guard let delegate = delegate else {
+            return
+        }
+        switch delegate.cell(forIdentifier: identifier) {
         case .empty:
             collectionView?.register(CollectionCellEmpty.self, forCellWithReuseIdentifier: identifier)
         case .customClass(let cellClass):

    open override func viewDidLoad() {
        super.viewDidLoad()
        
        registerCells()
    }
    
    // MARK: Abstract
    
    open func cell(forIdentifier identifier: String) -> CollectionCell {
        return .empty
    }
    
    open func update(_ cell: UICollectionViewCell & CollectionViewModelCell, at indexPath: IndexPath) {
        let item = dataSource.item(at: indexPath)
        cell.update(with: item)
    }
    
    // MARK: Helpers
    
    private func reload() {
        if Thread.isMainThread {
            registerCellsAndReloadDataIfNeeded()
        } else {
            DispatchQueue.main.async { [weak self] in
                self?.registerCellsAndReloadDataIfNeeded()
            }
        }
    }
    
    private func registerCellsAndReloadDataIfNeeded() {
        registerCells()
        collectionView?.reloadData()
    }
    
    private func registerCells() {


import UIKit

public protocol CollectionViewModelControllerDelegate: class {
    func cell(forIdentifier identifier: String) -> CollectionCell
    func update(_ cell: UICollectionViewCell & CollectionViewModelCell, at indexPath: IndexPath)
}

public extension CollectionViewModelControllerDelegate where Self: CollectionViewModelController {
    func cell(forIdentifier identifier: String) -> CollectionCell {
        return .empty
    }
    func update(_ cell: UICollectionViewCell & CollectionViewModelCell, at indexPath: IndexPath) {
        let item = dataSource.item(at: indexPath)
        cell.update(with: item)
    }
}

open class CollectionViewModelController: UICollectionViewController {
    
    // MARK: Properties

    public weak var delegate: CollectionViewModelControllerDelegate?

    open var isAutomaticReloadEnabled = true

