       DDLogDebug("Found decoded image in memory cache \(URLString) key=\(key)")
 			DispatchQueue.main.async(execute: {() -> Void in
 				autoreleasepool {
-					completion(ImageResult(URLString: URLString, ticket: ticket, image: cachedImage))
+					completion(ImageResponse(URLString: URLString, ticket: ticket, image: cachedImage))
 				}
 			})
     } else {

    }
  }
  
  // return CGRectZero if image does not need resizing, otherwise a new size with same aspect
	func maxSizeForImage(withSize imageSize: CGSize, maxWidthHeight: CGFloat) -> CGSize? {

		var maxSize: CGSize?
		if imageSize.width > maxWidthHeight || imageSize.height > maxWidthHeight {
			if imageSize.width > imageSize.height {
				maxSize = CGSize(
					width: maxWidthHeight,
					height: (maxWidthHeight * imageSize.height / imageSize.width).rounded()
				)
			}
			else {
				maxSize = CGSize(
					width: (maxWidthHeight * imageSize.width / imageSize.height).rounded(),
					height: maxWidthHeight
				)
			}
		}
		return maxSize
	}

	func filteredImage(forImage image: UIImage, resizedTo size: CGSize? = nil, filters: [YapImageFilter]? = nil) -> UIImage? {
		
		var filteredImage: UIImage?

		if let size = size {
			// resize image to size specified
			filteredImage = self.filteredImage(forImage: image, size: size, filters: filters)
		}	else {
			// otherwise, decode up to a max size
			if let maxSize = self.maxSizeForImage(withSize: image.size, maxWidthHeight: CGFloat(YapImageManagerMaxDecodeWidthHeight)) {
				filteredImage = self.filteredImage(forImage: image, size: maxSize, filters: filters)
			} else {
				filteredImage = self.filteredImage(forImage: image, size: image.size, filters: filters)
			}
		}
		return filteredImage
	}
	
	func filteredImage(forImage image: UIImage?, size: CGSize, filters: [YapImageFilter]? = nil) -> UIImage? {

    var aspectFillImage: UIImage?
		UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
		let imageRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
		guard let context = UIGraphicsGetCurrentContext() else { return nil }
		context.translateBy(x: 0.0, y: size.height)
		context.scaleBy(x: 1.0, y: -1.0)
		context.setBlendMode(.normal)
		context.interpolationQuality = .default
		
    if let filters = filters, !filters.isEmpty {
      for filter in filters {
        filter.draw(inContext: context, image: image, rect: imageRect, imageRect: imageRect)
      }
    } else {
      // if no filters were specifed, just render the image aspect fill
      let filter = AspectFillFilter()
      filter.draw(inContext: context, image: image, rect: imageRect, imageRect: imageRect)
    }
		
		// capture the image
		aspectFillImage = UIGraphicsGetImageFromCurrentImageContext()
		UIGraphicsEndImageContext()
		return aspectFillImage
	}
	
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  // MARK: - Image Session Manager
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//  func imageSessionManager(_ sessionManager: YapImageSessionManager, imageAttributesFound imageAttributes: [AnyHashable: Any], forURLString URLString: String) {
//    // save to database
//    // TODO: enable image attributes
//    //setImageAttributes(imageAttributes, forURLString: URLString)
//  }
  
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  // MARK: - Cleanup
  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  func removeExpiredImages() {
    DispatchQueue.main.async(execute: {() -> Void in
      autoreleasepool {

  }
}

class ImageResponseHandler {
  
  var ticket: ImageRequestTicket
  var completion: ImageRequestCompletion
