public static function getCachedImage($location, $returnLocation=false, $callback=null) {
    $location = rawurldecode($location);

    // strip the cache base from the location
    $cacheLocation = substr($location, strlen(self::IMAGE_CACHE_SECTION.'/'));

    // determine the width and source file from the location
    // the location is supposed to follow the pattern directory/{width}-basename
    $width = null;
    $basename = FileUtil::basename($cacheLocation);
    if (preg_match('/^([0-9]+)-/', $basename, $matches)) {
      // get required width from location and remove it from location
      $width = $matches[1];
      $basename = preg_replace('/^'.$width.'-/', '', $basename);
    }
    $sourceFile = self::getSourceDir($cacheLocation).$basename;

    // create the resized image file, if not existing
    $resizedFile = self::getCacheRoot().$cacheLocation;
    if (FileUtil::fileExists($sourceFile) && !FileUtil::fileExists($resizedFile)) {
      FileUtil::mkdirRec(pathinfo($resizedFile, PATHINFO_DIRNAME));
      $fixedFile = FileUtil::fixFilename($sourceFile);
      if ($width !== null) {
        self::resizeImage($fixedFile, $resizedFile, $width);
      }
      else {
        // just copy in case of undefined width
        copy($fixedFile, $resizedFile);
      }
      if (is_callable($callback)) {
        $callback($fixedFile, $resizedFile);
      }
    }

    // return the image file
    $file = FileUtil::fileExists($resizedFile) ? $resizedFile : (FileUtil::fileExists($sourceFile) ? $sourceFile : null);
    if ($returnLocation) {
      return $file;
    }
    $imageInfo = getimagesize($file);
    $image = file_get_contents($file);
    header('Content-type: '.$imageInfo['mime'].';');
    header("Content-Length: ".strlen($image));
    echo $image;
  }