     
     required public init(coder aDecoder: NSCoder) {
         fatalError("init(coder:) has not been implemented")
+    }
+    
+    // MARK: - Cache management
+    private func photoAtIndexPath(indexPath: NSIndexPath) -> UIImage {
+        if (self.photosCache.objectAtIndex(indexPath.section).isKindOfClass(NSNull)) {
+
+            // get photo representation
+            let representation = self.photos[indexPath.section]
+            
+            // get image from library
+            let orientation = UIImageOrientation(representation.orientation())
+            let photo = UIImage(CGImage: representation.fullScreenImage().takeUnretainedValue(), scale: CGFloat(representation.scale()), orientation: orientation)
+
+            // save photo for later use
+            self.photosCache.replaceObjectAtIndex(indexPath.section, withObject: photo!)
+            
+            return photo!
+        } else {
+            return self.photosCache.objectAtIndex(indexPath.section) as UIImage
+        }
+    }
+    
+    public func photoURLsForSelectedImages() -> [NSURL] {
+        var selectedPhotos = [NSURL]()
+        for index in self.selectedPhotoIndices {
+            let photo = self.photoAtIndexPath(NSIndexPath(index: index))
+            let url = self.saveImageOnDisk(photo)
+            if ((url) != nil) {
+                selectedPhotos.append(url!)
+            }
+        }
+        
+        return selectedPhotos
+    }
+    
+    public func saveImageOnDisk(image: UIImage) -> NSURL? {
+        let nsDocumentDirectory = NSSearchPathDirectory.DocumentDirectory
+        let nsUserDomainMask = NSSearchPathDomainMask.UserDomainMask
+        if let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true) {
+            if paths.count > 0 {
+                if let dirPath = paths[0] as? String {
+                    let writePath = dirPath.stringByAppendingPathComponent(NSProcessInfo.processInfo().globallyUniqueString)
+                    UIImagePNGRepresentation(image).writeToFile(writePath, atomically: true)
+                    
+                    return NSURL(string: writePath)
+                }
+            }
+        }
+        return nil
     }
     
     // MARK: - UITableViewDataSource

    // MARK: - UICollectionViewDelegateFlowLayout
    
    public func collectionView(collectionView: UICollectionView, layout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
        let photo = self.photos[indexPath.section]
        let height = self.tableView(self.tableView, heightForRowAtIndexPath: NSIndexPath(forRow: 0, inSection: 0)) - 2.0 * BRNImagePickerSheet.collectionViewInset
        let factor = height / photo.size.height
        
        return CGSizeMake(factor * photo.size.width, height)
    }
    
    public func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        let inset = 2.0 * BRNImagePickerSheet.collectionViewCheckmarkInset
        let size = self.collectionView(collectionView, layout: collectionViewLayout, sizeForItemAtIndexPath: NSIndexPath(forRow: 0, inSection: section))
        return CGSizeMake(BRNImageSupplementaryView.checkmarkImage.size.width + inset, size.height)
    }
    
    // MARK: - UICollectionViewDelegate

    
    public func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell: BRNImageCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as BRNImageCollectionViewCell
        cell.imageView.image = self.photoAtIndexPath(indexPath)
        
        return cell
    }
