     }
     
     /// These are pre-calucated for the visible items in `prepareLayout` and then after that they are loaded as needed.
-    public override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes! {
+    public override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
         return loadLayoutAttributesForItem(indexPath)
     }
     
-    public override func layoutAttributesForSupplementaryViewOfKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes! {
+    public override func layoutAttributesForSupplementaryViewOfKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
         
         func resolveInfo() -> (key: Int, lookup: [Int : UICollectionViewLayoutAttributes]) {
             switch elementKind {

        }
        
        // Add items for all visible rows
        if let collectionView = collectionView, visibleRows = visibleRows, visibleColumns = visibleColumns {
            
//            println("Currently visible rows: \(visibleRows)")
//            println("Currently visible columns: \(visibleColumns)")
            
            // Add column headers if the rect maxY is less than the header height or its frozen
            let columnsHeadersNeedAdding = frozenColumnHeaders || (rect.maxY <= columnHeaderHeight)
            
            for col in visibleColumns {
                if let attr = columnHeaderAttributes[col] {

    }
    
    public override func collectionViewContentSize() -> CGSize {
        // Look at the footer as thats below the rows
        if let lastXOffset = columnXOffsets[numberOfColumns], lastYOffset = rowFooterYOffsets[numberOfRows] {
            return CGSize(width: lastXOffset, height: lastYOffset)
