 public let YapImageManagerImageAttributesKey: String = "image_attributes"
 public let YapImageManagerImageCollection: String = "images"
 public let YapImageManagerImageAttributesCollection: String = "image_attributes"
-public let YapImageManagerMaxDecodeWidthHeight = 1024.0
-public let YapImageManagerMaxDatabaseWidthHeight = 4096.0
-public let YapImageManagerWidthHeightToResizeIfDatabaseMaxWidthHeightExceeded = 1024.0
-public let YapImageManagerMaxSimultaneousImageRequests = 5
-public let YapImageManagerAcceptableContentTypes = ["image/tiff", "image/jpeg", "image/jpg", "image/gif", "image/png", "image/ico", "image/x-icon", "image/bmp", "image/x-bmp", "image/x-xbitmap", "image/x-win-bitmap"]
-
-public typealias ImageRequestCompletion = (_ result: ImageResult) -> Void
+
+public struct YapImageManagerConfiguration {
+  
+  var databaseName: String
+  var attributesDatabaseName: String
+  var expireImagesAfter: TimeInterval
+  var expireImageAttributesAfter: TimeInterval
+  var maxDecodeWidthHeight: Float
+  var maxSaveToDatabaseWidthHeight: Float
+  var widthToResizeIfDatabaseMaxWidthHeightExceeded: Float
+  var maxSimultaneousImageRequests: Int
+  var timeoutIntervalForRequest: TimeInterval
+  var acceptableContentTypes: [String]
+}
+
 public typealias ImageRequestTicket = String
 
-public enum YapImageManagerError: Error {
-  
-  /// Unable to decode image
-  case imageDecodeFailure
-}
-
-public class ImageResult {
+public typealias ImageRequestCompletion = (_ result: ImageResponse) -> Void
+
+public class ImageResponse {
   
   public var URLString: String
   public var ticket: ImageRequestTicket


  fileprivate static let _sharedInstance = YapImageManager()
  
  /// Set to draw
  public var overlayImage: UIImage?
  
  public static func sharedInstance() -> YapImageManager {
    return _sharedInstance
  }
	
  override init() {
		
		func databasePath() -> String {
      let paths: [Any] = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)
      let databaseDir: String? = (paths.count > 0) ? (paths[0] as? String) : NSTemporaryDirectory()
      let databaseName: String = "YapImageManager.sqlite"
      return URL(fileURLWithPath: databaseDir!).appendingPathComponent(databaseName).absoluteString
    }
    
    func attributesDatabasePath() -> String {
      let paths: [Any] = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)
      let databaseDir: String? = (paths.count > 0) ? (paths[0] as? String) : NSTemporaryDirectory()
      let databaseName: String = "YapURLImageAttributes.sqlite"
      return URL(fileURLWithPath: databaseDir!).appendingPathComponent(databaseName).absoluteString
    }

    // Create a session configuration with no cache
    let config = URLSessionConfiguration.ephemeral
    // Note: this is not the same a max concurrent operations
    config.httpMaximumConnectionsPerHost = YapImageManagerMaxSimultaneousImageRequests
    config.timeoutIntervalForRequest = 30.0 // 30 second timeout
    sessionManager = SessionManager(configuration: config)

    // Initialize database and connections
    let options = YapDatabaseOptions()
    options.pragmaPageSize = 32768
    options.aggressiveWALTruncationSize = 1024 * 1024 * 100
    database = YapDatabase(path: databasePath(), objectSerializer: nil, objectDeserializer: nil, metadataSerializer: nil, metadataDeserializer: nil, objectPreSanitizer: nil, objectPostSanitizer: nil, metadataPreSanitizer: nil, metadataPostSanitizer: nil, options: options)
    
    databaseConnection = database.newConnection()
    databaseConnection.objectCacheEnabled = false

    }
    return imageSize
  }

  func postImageAttributesNotification(_ imageAttributes: NSDictionary, forURLString URLString: String) {
    let block: () -> Void = { () -> Void in
      let attributes: [AnyHashable: Any] = [YapImageManagerURLKey: URLString, YapImageManagerImageAttributesKey: imageAttributes]
