 
     /// A unique identifier that describes the purpose of the cells that the factory produces.
     /// The factory dequeues cells from the collection view with this reuse identifier.
+    /// Clients are responsible for registering a cell for this identifier with the collection view.
     public let reuseIdentifier: String
 
     private let cellConfigurator: ConfigurationHandler

}


public struct CollectionSupplementaryViewFactory <SupplementaryView: UICollectionReusableView, DataItem>: CollectionSupplementaryViewFactoryType {

    public typealias ConfigurationHandler = (SupplementaryView, DataItem, SupplementaryViewKind, UICollectionView, NSIndexPath) -> SupplementaryView

    public let reuseIdentifier: String

    private let supplementaryViewConfigurator: ConfigurationHandler

    public init(reuseIdentifier: String, supplementaryViewConfigurator: ConfigurationHandler) {
        self.reuseIdentifier = reuseIdentifier
        self.supplementaryViewConfigurator = supplementaryViewConfigurator
    }

    public func supplementaryViewForItem(item: DataItem, kind: SupplementaryViewKind,
                                         inCollectionView collectionView: UICollectionView, atIndexPath indexPath: NSIndexPath) -> SupplementaryView {
        return collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: reuseIdentifier, forIndexPath: indexPath) as! SupplementaryView
    }

    public func configureSupplementaryView(view: SupplementaryView, forItem item: DataItem, kind: SupplementaryViewKind,
                                           inCollectionView collectionView: UICollectionView, atIndexPath indexPath: NSIndexPath) -> SupplementaryView {
        return supplementaryViewConfigurator(view, item, kind, collectionView, indexPath)

    /// The type of `UICollectionViewCell` that the factory produces.
    typealias Cell: UICollectionViewCell

    ///  Creates and returns a new `Cell` instance, or dequeues an existing cell for reuse.
    ///
    ///  :param: item           The model instance (data object) at `indexPath`.
    ///  :param: collectionView The collection view requesting this information.
