 				
 				let frame: CGRect
 				let cells: [CellFrameNode]
-				init(cells: [CellFrameNode]) {
+				let headerFrame: CGRect?
+				let footerFrame: CGRect?
+				init(cells: [CellFrameNode], headerFrame: CGRect? = nil, footerFrame: CGRect? = nil) {
+					//TODO: change headerFrame and footerFrame to size only to remove amiibuity of how its used
 					self.cells = cells
-					let rect =  MosaicLayoutFrameTree.computeContainerFrame(cells.map({$0 as MosaicFrameNode}))
+					
+					// compute frame of all cells
+					var rect = MosaicLayoutFrameTree.computeContainerFrame(cells.map({$0 as MosaicFrameNode}))
+					
+					if let header = headerFrame {
+						// expand rect to include header
+						rect = MosaicLayoutFrameTree.expandRect(rect, toContainChild: header)
+						self.headerFrame = header
+					} else {
+						self.headerFrame = nil
+					}
+					
+					if let footer = footerFrame {
+						// expand rect to include footer
+						rect = MosaicLayoutFrameTree.expandRect(rect, toContainChild: footer)
+						self.footerFrame = footer
+					} else {
+						self.footerFrame = nil
+					}
+					
 					self.frame = rect
 				}
 			}

		var sections = [SectionLayoutViewModel]()
		/// used for fast lookup of layoutAttributesForElementsInRect
		var itemFrameForIndexPath = [(indexPath:NSIndexPath, frame:CGRect)]()
		//TODO: refactor this to reflect sections and cells
		var layoutFrameTree = MosaicLayoutFrameTree(sections: [])
		
		/*

			// compute each section height
			for (sectionIndex, section) in sections.enumerate() {
				//TODO: support horizontal scroll direction
				
				let sectionInset = insetForSection(sectionIndex)
				let interitemSpacing = interitemSpacingForSection(sectionIndex)
				let lineSpacing = lineSpacingForSection(sectionIndex)
				// scale factor converts 1x1 grid into pixel frames.  Subtract 1 from width to ensure fit
				// sum all interitem spacing
				let summedIteritemSpacing = CGFloat(section.constrainedSideGridLength - 1) * interitemSpacing
				let unitPixelScaleFactor = (contentSize.width - sectionInset.left - sectionInset.right - summedIteritemSpacing) / CGFloat(section.constrainedSideGridLength)
				
				// section origin starts horizontally at the content and section insets and vertically at the vertical extent of contentSize + the section and content insets
				let sectionOrigin = CGPoint(x: sectionInset.left + contentInset.left, y:contentSize.height + sectionInset.top + contentInset.top)
				
				// get the header and footer sizes to use in frame calculations
				var headerFrame = frameForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, inSection:sectionIndex)
				headerFrame?.origin.y = sectionOrigin.y
				
				let headerSize = headerFrame?.size ?? CGSizeZero
				var sectionVerticalExtent: CGFloat = 0.0
				
				// the frames coresponding to the cells, calculated from their grid frames
				var cellFrames: [MosaicLayoutFrameTree.SectionFrameNode.CellFrameNode] = []
