         return try autoreleasepool { () -> Data? in
             do {
                 let data = try Data(contentsOf: fileURL)
-                return try removePassword(input: data, password: password)
-            } catch {
-                return nil
-            }
-        }
-    }
-    
-    class open func removePassword(input: Data, password: String) throws -> Data? {
+                return try removePassword(data: data, password: password)
+            } catch {
+                return nil
+            }
+        }
+    }
+    
+    class open func removePassword(data: Data, password: String) throws -> Data? {
         return try autoreleasepool { () -> Data? in
-            let dataProvider = CGDataProvider(data: input as CFData)
-            if let provider = dataProvider {
-                if let pdf = CGPDFDocument(provider) {
-                    // Try a blank password first, per Apple's Quartz PDF example
-                    if pdf.isEncrypted == true &&
-                        pdf.unlockWithPassword("") == false {
-                        // Nope, now let's try the provided password to unlock the PDF
-                        if let cPasswordString = password.cString(using: String.Encoding.utf8) {
-                            if pdf.unlockWithPassword(cPasswordString) == false {
-                                print("Unable to unlock")
-                                return nil
-                            }
-                        }
-                    }
-                    
-                    return try convertPdfToData(pdf: pdf)
-                }
-            }
-            return nil
-        }
-    }
-    
-    class open func imageToPDF(image: UIImage, password: String? = nil, scaleFactor: CGFloat = 1) throws -> Data? {
+            let pdf = unlock(data: data, password: password)
+            if pdf != nil { return nil }
+            return try convertPdfToData(pdf: pdf!)
+        }
+    }
+    
+    class open func convertPDFToImages(fileURL: URL, password: String? = nil) throws -> [UIImage]? {
+        return try autoreleasepool { () -> [UIImage]? in
+            do {
+                let data = try Data(contentsOf: fileURL)
+                return try convertPDFToImages(data: data, password: password)
+            } catch {
+                return nil
+            }
+        }
+    }
+    
+    class open func convertPDFToImages(data: Data, password: String? = nil) throws -> [UIImage]? {
+        return try autoreleasepool { () -> [UIImage]? in
+            do {
+                let dataProvider = CGDataProvider(data: data as CFData)
+                if let provider = dataProvider {
+                    if let pdf = CGPDFDocument(provider) {
+                        return convertPDFToImages(pdf: pdf, password: password)
+                    }
+                }
+                return nil
+            } catch {
+                return nil
+            }
+        }
+    }
+    
+    class open func convertPDFToImages(pdf: CGPDFDocument, password: String? = nil) -> [UIImage]? {
+        var output = [UIImage]()
+        let pdf = (password != nil) ? unlock(pdf: pdf, password: password) : pdf
+        
+        autoreleasepool {
+            let pageCount = pdf?.numberOfPages ?? 0
+            for index in 1...pageCount {
+                if let page = pdf?.page(at: index) {
+                    output.append(convertPageToImage(page: page))
+                }
+            }
+        }
+        
+        return output
+    }
+    
+    class open func convertImagesToPDF(images: [UIImage], password: String? = nil, scaleFactor: CGFloat = 1) throws -> Data? {
         
         guard scaleFactor > 0.0 else {
             return nil

        return try autoreleasepool { () -> Data? in
            do {
                let data = try Data(contentsOf: fileURL)
                return try addPassword(input: data, password: password)
            } catch {
                return nil
            }
        }
    }
    
    class open func addPassword(input: Data, password: String) throws -> Data? {
        return try autoreleasepool { () -> Data? in
            let dataProvider = CGDataProvider(data: input as CFData)
            if let provider = dataProvider {
                if let pdf = CGPDFDocument(provider) {
                    return try convertPdfToData(pdf: pdf, password: password)

        return autoreleasepool { () -> Bool in
            do {
                let data = try Data(contentsOf: fileURL)
                return hasPassword(data: data)
            } catch {
                return false
            }
        }
    }
    
    class open func hasPassword(data: Data) -> Bool {
        return autoreleasepool { () -> Bool in
            let dataProvider = CGDataProvider(data: data as CFData)
            if let provider = dataProvider {
                if let pdf = CGPDFDocument(provider) {
                    if pdf.isUnlocked || pdf.isEncrypted {
