         return messagesLayoutDelegate
     }
 
+    /// The width of an item in the `MessagesCollectionViewCell`.
     fileprivate var itemWidth: CGFloat {
         guard let collectionView = collectionView else { return 0 }
         return collectionView.frame.width - sectionInset.left - sectionInset.right
     }
 
-    open override class var layoutAttributesClass: AnyClass {
-        return MessagesCollectionViewLayoutAttributes.self
-    }
-
-    // MARK: - Initializers
+    // MARK: - Initializers [Public]
 
     public override init() {
 

        return messagesCollectionView
    }

    fileprivate var messagesDataSource: MessagesDataSource {
        guard let messagesDataSource = messagesCollectionView.messagesDataSource else {
            fatalError("MessagesDataSource has not been set.")

import UIKit
import AVFoundation

/// The layout object used by `MessagesCollectionView` to determine the size of all
/// framework provided `MessagesCollectionViewCell` subclasses.
open class MessagesCollectionViewFlowLayout: UICollectionViewFlowLayout {

    // MARK: - Properties [Public]

    /// Font to be used by `TextMessageCell` for `MessageData.text(String)` case.
    ///
    /// The default value of this property is `UIFont.preferredFont(forTextStyle: .body)`
    open var messageLabelFont: UIFont {
        didSet {
            emojiLabelFont = messageLabelFont.withSize(2 * messageLabelFont.pointSize)
        }
    }

    /// A Boolean value that determines if the `AvatarView` is always on the leading
    /// side of a MessageCollectionViewCell.
    ///
    /// Setting this property to `true` causes `avatarAlwaysTrailing` to be set to `false`.
    ///
    /// The default value of this property is `false`.
    open var avatarAlwaysLeading: Bool {
        willSet {
            if newValue {
