     }
     
     /// Finds using all files matching this ObjectID
+    ///
     /// - parameter byID: The ID to look for
+    ///
+    /// - throws: When we can't send the request/receive the response, you don't have sufficient permissions or an error occurred
+    ///
     /// - returns: A cursor pointing to all resulting files
     public func find(byID id: ObjectId) throws -> Cursor<File> {
-        return try self.find(matching: ["_id": .objectId(id)])
+        return try self.find(matching: ["_id": .objectId(id)] as Document)
     }
     
     /// Finds using all files file matching this filename
+    ///
     /// - parameter filter: The filename to look for
+    ///
+    /// - throws: When we can't send the request/receive the response, you don't have sufficient permissions or an error occurred
+    ///
     /// - returns: A cursor pointing to all resulting files
     public func find(byName filename: String) throws -> Cursor<File> {
-        return try self.find(matching: ["filename": .string(filename)])
+        return try self.find(matching: ["filename": .string(filename)] as Document)
     }
     
     /// Finds using all files matching this MD5 hash
+    ///
     /// - parameter filter: The hash to look for
+    ///
+    /// - throws: When we can't send the request/receive the response, you don't have sufficient permissions or an error occurred
+    ///
     /// - returns: A cursor pointing to all resulting files
     public func find(byHash hash: String) throws -> Cursor<File> {
-        return try self.find(matching: ["md5": .string(hash)])
+        return try self.find(matching: ["md5": .string(hash)] as Document)
     }
     
     /// Finds the first file matching this ObjectID
+    ///
     /// - parameter byID: The hash to look for
+    ///
+    /// - throws: When we can't send the request/receive the response, you don't have sufficient permissions or an error occurred
+    ///
     /// - returns: The resulting file
     public func findOne(byID id: ObjectId) throws -> File? {
-        return try self.find(matching: ["_id": .objectId(id)]).makeIterator().next()
+        return try self.find(matching: ["_id": .objectId(id)] as Document).makeIterator().next()
     }
     
     /// Finds the first file matching this filename
+    ///
     /// - parameter byName: The filename to look for
+    ///
+    /// - throws: When we can't send the request/receive the response, you don't have sufficient permissions or an error occurred
+    ///
     /// - returns: The resulting file
     public func findOne(byName filename: String) throws -> File? {
-        return try self.find(matching: ["filename": .string(filename)]).makeIterator().next()
+        return try self.find(matching: ["filename": .string(filename)] as Document).makeIterator().next()
     }
     
     /// Finds the first file matching this MD5 hash
+    ///
     /// - parameter byHash: The hash to look for
+    ///
+    /// - throws: When we can't send the request/receive the response, you don't have sufficient permissions or an error occurred
+    ///
     /// - returns: The resulting file
     public func findOne(byHash hash: String) throws -> File? {
-        return try self.find(matching: ["md5": .string(hash)]).makeIterator().next()
+        return try self.find(matching: ["md5": .string(hash)] as Document).makeIterator().next()
     }
     
     /// Finds using a matching filter
+    ///
     /// - parameter filter: The filter to use
+    ///
+    /// - throws: When we can't send the request/receive the response, you don't have sufficient permissions or an error occurred
+    ///
     /// - returns: A cursor pointing to all resulting files
-    public func find(matching filter: Document) throws -> Cursor<File> {
+    public func find(matching filter: QueryProtocol) throws -> Cursor<File> {
         let cursor = try files.find(matching: filter)
         
         let gridFSCursor: Cursor<File> = Cursor(base: cursor, transform: { File(document: $0, chunksCollection: self.chunks, filesCollection: self.files) })

        }
        
        /// Finds all or specific chunks
        public func read(from start: Int = 0, to end: Int? = nil) throws -> [Byte] {
            let remainderValue = start % Int(self.chunkSize)
            let skipChunks = (start - remainderValue) / Int(self.chunkSize)

            /// The ID of the file that this chunk is a part of
            let filesID: ObjectId
            
            /// Which chunk this is
            let n: Int32
            
            /// The data for our chunk
            let data: [Byte]
            
            /// The chunk `Collection` which this chunk is stored in
            let chunksCollection: Collection
            
            /// The files `Collection` where our file is stored
            let filesCollection: Collection
            
            /// Initializes with a `Document` found when looking for chunks
            init?(document: Document, chunksCollection: Collection, filesCollection: Collection) {
                guard let id = document["_id"].objectIdValue,
                    filesID = document["files_id"].objectIdValue,
