/**
  * Returns a thumbnail of the given asset
  *
  * If the maximum width / height is not specified or exceeds the original asset's dimensions, the width / height of
  * the original asset is used.
  *
  * @param AssetInterface $asset The asset to render a thumbnail for
  * @param ThumbnailConfiguration $configuration
  * @return ImageInterface
  * @throws \Exception
  */
 public function getThumbnail(AssetInterface $asset, ThumbnailConfiguration $configuration)
 {
     // Calculates the dimensions of the thumbnail to be generated and returns the thumbnail image if the new
     // dimensions differ from the specified image dimensions, otherwise the original image is returned.
     if ($asset instanceof ImageInterface) {
         if ($asset->getWidth() === null && $asset->getHeight() === null) {
             return $asset;
         }
         $maximumWidth = $configuration->getMaximumWidth() > $asset->getWidth() ? $asset->getWidth() : $configuration->getMaximumWidth();
         $maximumHeight = $configuration->getMaximumHeight() > $asset->getHeight() ? $asset->getHeight() : $configuration->getMaximumHeight();
         if ($configuration->isUpScalingAllowed() === false && $maximumWidth === $asset->getWidth() && $maximumHeight === $asset->getHeight()) {
             return $asset;
         }
     }
     $assetIdentifier = $this->persistenceManager->getIdentifierByObject($asset);
     $configurationHash = $configuration->getHash();
     if (!isset($this->thumbnailCache[$assetIdentifier])) {
         $this->thumbnailCache[$assetIdentifier] = [];
     }
     if (isset($this->thumbnailCache[$assetIdentifier][$configurationHash])) {
         $thumbnail = $this->thumbnailCache[$assetIdentifier][$configurationHash];
     } else {
         $thumbnail = $this->thumbnailRepository->findOneByAssetAndThumbnailConfiguration($asset, $configuration);
         $this->thumbnailCache[$assetIdentifier][$configurationHash] = $thumbnail;
     }
     $async = $configuration->isAsync();
     if ($thumbnail === null) {
         try {
             $thumbnail = new Thumbnail($asset, $configuration, $async);
             $this->emitThumbnailCreated($thumbnail);
             // If the thumbnail strategy failed to generate a valid thumbnail
             if ($async === false && $thumbnail->getResource() === null && $thumbnail->getStaticResource() === null) {
                 $this->thumbnailRepository->remove($thumbnail);
                 return null;
             }
             if (!$this->persistenceManager->isNewObject($asset)) {
                 $this->thumbnailRepository->add($thumbnail);
             }
             $asset->addThumbnail($thumbnail);
             // Allow thumbnails to be persisted even if this is a "safe" HTTP request:
             $this->persistenceManager->whiteListObject($thumbnail);
             $this->thumbnailCache[$assetIdentifier][$configurationHash] = $thumbnail;
         } catch (NoThumbnailAvailableException $exception) {
             $this->systemLogger->logException($exception);
             return null;
         }
         $this->persistenceManager->whiteListObject($thumbnail);
         $this->thumbnailCache[$assetIdentifier][$configurationHash] = $thumbnail;
     } elseif ($thumbnail->getResource() === null && $async === false) {
         $this->refreshThumbnail($thumbnail);
     }
     return $thumbnail;
 }