               // write the image attributes, if necessary
               if shouldUpdateImageAttributes {
                 DDLogVerbose("Update image attributes \(imageRequest.URLString)")
-                self.updateImageAttributes(with: imageSize, forURLString: imageRequest.URLString)
+                self.updateImageAttributes(with: imageSize, forURLString: imageRequest.URLString, expiresAfter: self.configuration.expireImageAttributesAfter)
               }
               
               // decode all images and save to cache

      return nil
    }
  }
  
  // MARK: Image queue

  private func queueImage(forURLString URLString: String, response: ImageResponseHandler) {

  
  private func removeExpiredImages() {
    DispatchQueue.main.async(execute: {() -> Void in
      
      // fetch the expired images
      var imageDeleteKeys = [String]()
      self.databaseConnection.read({ transaction in
        transaction.enumerateKeysAndMetadata(inCollection: YapImageManagerImageCollection, using: { (key: String, metadata: Any?, stop: UnsafeMutablePointer<ObjCBool>) in
          if let imageMetadata = metadata as? ImageMetadata, let expires = imageMetadata.expires {
            let timeSince = -expires.timeIntervalSinceNow
            if timeSince > 0 {
              DDLogVerbose("Remove expired image \(key)")
              imageDeleteKeys.append(key)
            }
          }
        })
      })
      
      // fetch the expired image attributes
      var imageAttributeDeleteKeys = [String]()
      self.attributesDatabaseConnection.read({ transaction in
        transaction.enumerateKeysAndMetadata(inCollection: YapImageManagerImageAttributesCollection, using: { (key: String, metadata: Any?, stop: UnsafeMutablePointer<ObjCBool>) in
          if let attributesMetadata = metadata as? ImageMetadata, let expires = attributesMetadata.expires {
            let timeSince = -expires.timeIntervalSinceNow
            if timeSince > 0 {
              DDLogVerbose("Remove expired image attributes \(key)")
              imageAttributeDeleteKeys.append(key)
            }
          }
        })
      })
      
      // remove expired images and attributes, images first so you never end up with images without attributes
      self.backgroundDatabaseConnection.asyncReadWrite({ transaction  in
        // remove images
        transaction.removeObjects(forKeys: imageDeleteKeys, inCollection: YapImageManagerImageCollection)
      }, completionBlock: {() -> Void in
        // remove image attributes after removing images has completed
        self.backgroundAttributesDatabaseConnection.asyncReadWrite( { transaction in
          transaction.removeObjects(forKeys: imageAttributeDeleteKeys, inCollection: YapImageManagerImageAttributesCollection)
        }, completionBlock: {() -> Void in
          // DEBUG
          //[self validateDatabaseIntegrity];
        })
      })
      // DEBUG
      //[self validateDatabaseIntegrity];
    })
  }
  
