         var layoutAttributes = [UICollectionViewLayoutAttributes]()
         
         if let collectionView = self.collectionView {
+            // can be further optimized
             for (var section = 0; section < collectionView.numberOfSections();section++) {
                 var sectionIndexPath = NSIndexPath(forItem: 0, inSection: section)
                 let headerAttributes = layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: sectionIndexPath)


class ZLBalancedFlowLayout: UICollectionViewFlowLayout {
    /// The ideal row height of items in the grid
    var rowHeight = CGFloat(120)
    
    private var headerFrames = [CGRect](), footerFrames = [CGRect]()
    private var itemFrames = [[CGRect]](), itemOriginYs = [[CGFloat]]()
    private var contentSize = CGSizeZero
    
    // TODO: scalesItemToFill, shouldInvalidateLayoutForBoundsChange

    // MARK: - UICollectionViewLayout
    override func prepareLayout() {

                Float(inset.left+inset.right) :
                Float(inset.top+inset.bottom),
            contentWidth = maxWidth - outterMargin - innerMargin,
            widthRatio = CGFloat(contentWidth/row.reduce(0, combine: { (acc, width) -> Float in acc+width })),
            heightRatio = enforcesRowHeight ? 1 : widthRatio
            for width in row {
                let size = scrollDirection == .Vertical ?
                    CGSize(width: CGFloat(width)*widthRatio, height: rowHeight*heightRatio) :
                    CGSize(width: rowHeight*heightRatio, height: CGFloat(width)*widthRatio)
                let frame = CGRect(origin: origin, size: size)
                framesInSection.append(frame)
                if scrollDirection == .Vertical {
