diff --git a/Classes/Backend/Ajax.php b/Classes/Backend/Ajax.php
index a2f37d92dddd032def2235f18696cd4dbd974622..7c261191a36ab9a3231cab7e4b5a1b9b2d4e3a6c 100644
--- a/Classes/Backend/Ajax.php
+++ b/Classes/Backend/Ajax.php
@@ -1,7 +1,5 @@
 <?php
 
-namespace SGalinski\SgVimeo\Backend;
-
 /***************************************************************
  *  Copyright notice
  *
@@ -26,39 +24,39 @@ namespace SGalinski\SgVimeo\Backend;
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
-use Exception;
+namespace SGalinski\SgVimeo\Backend;
+
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
 use SGalinski\SgVimeo\Service\LicenceCheckService;
 use TYPO3\CMS\Core\Http\Response;
-use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
 
 /**
  * Class Ajax
  *
  * @package SGalinski\SgVimeo\Backend
  */
-class Ajax {
-	/**
-	 * Checks whether the license is valid
-	 *
-	 * @param ServerRequestInterface $request
-	 * @param ResponseInterface $response
-	 * @return ResponseInterface
-	 * @throws \InvalidArgumentException
-	 * @throws Exception
-	 */
-	public function checkLicense(
-		ServerRequestInterface $request,
-		ResponseInterface $response = NULL
-	) {
-		if ($response === NULL) {
-			$response = new Response();
-		}
+class Ajax
+{
+    /**
+     * Checks whether the license is valid
+     *
+     * @param ServerRequestInterface $request
+     * @param \Psr\Http\Message\ResponseInterface|null $response
+     * @return ResponseInterface
+     */
+    public function checkLicense(
+        ServerRequestInterface $request,
+        ResponseInterface      $response = NULL
+    )
+    {
+        if ($response === NULL) {
+            $response = new Response();
+        }
 
-		LicenceCheckService::setLastAjaxNotificationCheckTimestamp();
-		$responseData = LicenceCheckService::getLicenseCheckResponseData(TRUE);
-		$response->getBody()->write(json_encode($responseData));
-		return $response;
-	}
+        LicenceCheckService::setLastAjaxNotificationCheckTimestamp();
+        $responseData = LicenceCheckService::getLicenseCheckResponseData(TRUE);
+        $response->getBody()->write(json_encode($responseData));
+        return $response;
+    }
 }
diff --git a/Classes/Controller/VimeoController.php b/Classes/Controller/VimeoController.php
index 329cfc96b02e4a6ea9b0fe821ae219606dfd014d..a4314d339e8cf518fc3c0f104bc08061748aa568 100644
--- a/Classes/Controller/VimeoController.php
+++ b/Classes/Controller/VimeoController.php
@@ -26,6 +26,7 @@ use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection;
 use TYPO3\CMS\Core\Resource\FileReference;
 use TYPO3\CMS\Core\Resource\FileRepository;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\VersionNumberUtility;
 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
 use TYPO3\CMS\Extbase\Service\ImageService;
 
@@ -124,7 +125,7 @@ class VimeoController extends ActionController {
 			]
 		);
 
-        if (version_compare(\TYPO3\CMS\Core\Utility\VersionNumberUtility::getCurrentTypo3Version(), '12.0.0', '>=')) {
+        if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '12.0.0', '>=')) {
             return $this->jsonResponse();
         }
 	}
diff --git a/Classes/Form/Element/LicenceStatus.php b/Classes/Form/Element/LicenceStatus.php
index f2cc4b53271687ddfbdfb98880e01c268ea0b3e5..c39c2de9f758996fb0594c9f9a7d1017c2a09589 100644
--- a/Classes/Form/Element/LicenceStatus.php
+++ b/Classes/Form/Element/LicenceStatus.php
@@ -17,6 +17,7 @@
  *  GNU General Public License for more details.
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
+
 namespace SGalinski\SgVimeo\Form\Element;
 
 use SGalinski\SgVimeo\Service\LicenceCheckService;
@@ -35,20 +36,20 @@ class LicenceStatus extends AbstractFormElement
             return [];
         }
 
-		switch ($responseData['error']) {
-			case 1:
-				$errorOrWarning = 'danger';
-				break;
-			case 2:
-				$errorOrWarning = 'warning';
-				break;
-			default:
-				$errorOrWarning = 'success';
-		}
+        switch ($responseData['error']) {
+            case 1:
+                $errorOrWarning = 'danger';
+                break;
+            case 2:
+                $errorOrWarning = 'warning';
+                break;
+            default:
+                $errorOrWarning = 'success';
+        }
 
-        $message = '<div class="alert alert-'. $errorOrWarning .'" role="'
+        $message = '<div class="alert alert-' . $errorOrWarning . '" role="'
             . $errorOrWarning
-            .  '">' . $responseData['message'] . '</div>';
+            . '">' . $responseData['message'] . '</div>';
         $resultArray['html'] = $message;
         return $resultArray;
     }
diff --git a/Classes/Hooks/LicenceCheckHook.php b/Classes/Hooks/LicenceCheckHook.php
index 5e2c989e95475309eb55afba5b04d86c3ae287ff..223aa4e873a9fb83a03a640a5aef07c18abb16cd 100644
--- a/Classes/Hooks/LicenceCheckHook.php
+++ b/Classes/Hooks/LicenceCheckHook.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  *
  * Copyright notice
@@ -38,22 +39,25 @@ use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
  * @package SGalinski\ProjectBase\Hook
  * @author Georgi Mateev <georgi.mateev@sgalinski.de>
  */
-class LicenceCheckHook {
-	/**
-	 * Add JavaScript to display the expiring license warning
-	 */
-	protected function addAjaxLicenseCheck() {
-		$pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
-		$pageRenderer->loadRequireJsModule('TYPO3/CMS/SgVimeo/Backend/LicenseNotification');
-	}
+class LicenceCheckHook
+{
+    /**
+     * Add JavaScript to display the expiring license warning
+     */
+    protected function addAjaxLicenseCheck()
+    {
+        $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
+        $pageRenderer->loadRequireJsModule('TYPO3/CMS/SgVimeo/Backend/LicenseNotification');
+    }
 
-	/**
-	 * Checks if the license key is OK
-	 *
-	 * @param array $configuration
-	 * @param BackendController $parentBackendController
-	 */
-	public function performLicenseCheck(array $configuration, BackendController $parentBackendController) {
+    /**
+     * Checks if the license key is OK
+     *
+     * @param array $configuration
+     * @param BackendController $parentBackendController
+     */
+    public function performLicenseCheck(array $configuration, BackendController $parentBackendController)
+    {
         if (!LicenceCheckService::isTYPO3VersionSupported()
             || !LicenceCheckService::isTimeForNextCheck()
             || LicenceCheckService::isInDevelopmentContext()
@@ -61,6 +65,6 @@ class LicenceCheckHook {
             return;
         }
 
-		$this->addAjaxLicenseCheck();
-	}
+        $this->addAjaxLicenseCheck();
+    }
 }
diff --git a/Classes/Hooks/PageLayoutView/PluginRenderer.php b/Classes/Hooks/PageLayoutView/PluginRenderer.php
index bb41fbad9b458c58d37b291fbe3ef627f83f16da..62ed516029c798888975d699eff3b42d56fffc53 100644
--- a/Classes/Hooks/PageLayoutView/PluginRenderer.php
+++ b/Classes/Hooks/PageLayoutView/PluginRenderer.php
@@ -1,7 +1,5 @@
 <?php
 
-namespace SGalinski\SgVimeo\Hooks\PageLayoutView;
-
 /***************************************************************
  *  Copyright notice
  *  (c) sgalinski Internet Services (https://www.sgalinski.de)
@@ -20,6 +18,8 @@ namespace SGalinski\SgVimeo\Hooks\PageLayoutView;
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+namespace SGalinski\SgVimeo\Hooks\PageLayoutView;
+
 use SGalinski\SgVimeo\Preview\PreviewService;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Backend\View\PageLayoutView;
@@ -124,7 +124,8 @@ if (interface_exists('TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface
         }
     }
 } else {
-    class PluginRenderer {
+    class PluginRenderer
+    {
 
     }
 }
diff --git a/Classes/Preview/PreviewRenderer.php b/Classes/Preview/PreviewRenderer.php
index 55290a9996acbe25a1d866918a0a1d69adc3dbe9..34e3ab9375b9667a94b5a5847bbe49a65cf8a8e5 100644
--- a/Classes/Preview/PreviewRenderer.php
+++ b/Classes/Preview/PreviewRenderer.php
@@ -58,8 +58,7 @@ class PreviewRenderer implements PreviewRendererInterface {
 	 * @return string
 	 */
 	public function renderPageModulePreviewContent(GridColumnItem $item): string {
-		$view = $this->previewService->getPluginView($item->getRecord());
-		return $view->render();
+        return $this->previewService->getPluginView($item->getRecord())->render();
 	}
 
 	/**
diff --git a/Classes/Preview/PreviewService.php b/Classes/Preview/PreviewService.php
index 79dd15006b075c21c61c4ead73efab5d06f63851..b567bb0c173a0c45d24ea1dc021a86da282874e5 100644
--- a/Classes/Preview/PreviewService.php
+++ b/Classes/Preview/PreviewService.php
@@ -17,6 +17,7 @@
  *  GNU General Public License for more details.
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
+
 namespace SGalinski\SgVimeo\Preview;
 
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -25,58 +26,61 @@ use TYPO3\CMS\Fluid\View\StandaloneView;
 /**
  * PreviewService, to get Views while we have to duplicate previewCode
  */
-class PreviewService {
-	public const RETURNTYPE_ARR = 'array';
+class PreviewService
+{
+    public const RETURNTYPE_ARR = 'array';
 
-	public function getPluginView(array $row): StandaloneView {
-		/** @var StandaloneView $view */
-		$view = GeneralUtility::makeInstance(StandaloneView::class);
-		$view->setPartialRootPaths(['EXT:sg_vimeo/Resources/Private/Partials/Backend']);
-		$view->setTemplateRootPaths(['EXT:sg_vimeo/Resources/Private/Templates/Vimeo']);
-		$view->setTemplate('Backend.html');
-		$view->assign('uid', $row['uid']);
+    public function getPluginView(array $row): StandaloneView
+    {
+        /** @var StandaloneView $view */
+        $view = GeneralUtility::makeInstance(StandaloneView::class);
+        $view->setPartialRootPaths(['EXT:sg_vimeo/Resources/Private/Partials/Backend']);
+        $view->setTemplateRootPaths(['EXT:sg_vimeo/Resources/Private/Templates/Vimeo']);
+        $view->setTemplate('Backend.html');
+        $view->assign('uid', $row['uid']);
 
-		// Get available plugin settings and their values from flexform
-		$pluginConfiguration = GeneralUtility::xml2array(
-			$row['pi_flexform'],
-			'T3DataStructure'
-		)['data']['sDEF']['lDEF'];
+        // Get available plugin settings and their values from flexform
+        $pluginConfiguration = GeneralUtility::xml2array(
+            $row['pi_flexform'],
+            'T3DataStructure'
+        )['data']['sDEF']['lDEF'];
 
-		$templateData = [
-			'vimeoId' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.id'),
-			'maxResults' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.maxResults'),
-			'showTitle' => (int) ($this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.showTitle') ?? 1),
-			'showDescription' => (int) ($this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.showDescription') ?? 1),
-			'disableLightbox' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.disableLightbox'),
-			'disableLightboxMobile' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.disableLightboxMobile'),
-			'aspectRatio' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.aspectRatio'),
-			'thumbnailType' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.thumbnailType'),
-			'thumbnailImagesCount' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.thumbnailImages'),
-			'showApiResult' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.showApiResult'),
-			'urlParameters' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.urlParameters'),
-		];
+        $templateData = [
+            'vimeoId' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.id'),
+            'maxResults' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.maxResults'),
+            'showTitle' => (int)($this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.showTitle') ?? 1),
+            'showDescription' => (int)($this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.showDescription') ?? 1),
+            'disableLightbox' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.disableLightbox'),
+            'disableLightboxMobile' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.disableLightboxMobile'),
+            'aspectRatio' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.aspectRatio'),
+            'thumbnailType' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.thumbnailType'),
+            'thumbnailImagesCount' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.thumbnailImages'),
+            'showApiResult' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.showApiResult'),
+            'urlParameters' => $this->passVDefOnKeyToTemplate($pluginConfiguration, 'settings.urlParameters'),
+        ];
 
-		$view->assign('data', $templateData);
-		return $view;
-	}
+        $view->assign('data', $templateData);
+        return $view;
+    }
 
 
-	/**
-	 * @param array $conf
-	 * @param string $key
-	 * @param string $returnType
-	 * @return array|mixed|string
-	 */
-	private function passVDefOnKeyToTemplate(array $conf, string $key, string $returnType = '') {
-		if (isset($conf[$key])) {
-			return $conf[$key]['vDEF'];
-		}
+    /**
+     * @param array $conf
+     * @param string $key
+     * @param string $returnType
+     * @return array|mixed|string
+     */
+    private function passVDefOnKeyToTemplate(array $conf, string $key, string $returnType = '')
+    {
+        if (isset($conf[$key])) {
+            return $conf[$key]['vDEF'];
+        }
 
-		// check if we got a possible returntype:
-		if ($returnType === self::RETURNTYPE_ARR) {
-			return [];
-		}
+        // check if we got a possible returntype:
+        if ($returnType === self::RETURNTYPE_ARR) {
+            return [];
+        }
 
-		return '';
-	}
+        return '';
+    }
 }
diff --git a/Classes/Service/ExtensionSettingsService.php b/Classes/Service/ExtensionSettingsService.php
index 3c30c12081bfca6697394185c555fae00384bb4d..9dbb217f5e5fdbd37da374a2093205727c0ace2d 100644
--- a/Classes/Service/ExtensionSettingsService.php
+++ b/Classes/Service/ExtensionSettingsService.php
@@ -1,7 +1,5 @@
 <?php
 
-namespace SGalinski\SgVimeo\Service;
-
 /***************************************************************
  *  Copyright notice
  *
@@ -26,73 +24,78 @@ namespace SGalinski\SgVimeo\Service;
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+namespace SGalinski\SgVimeo\Service;
+
 use TYPO3\CMS\Core\Utility\VersionNumberUtility;
 
 /**
  * Class SGalinski\SgVimeo\Service\ExtensionSettingsService
  */
-class ExtensionSettingsService {
-	const SETTING_LICENSE = 'key';
-	const SETTING_FOLDER = 'folder';
-	const SETTING_HIDE_MODULE_IN_PRODUCTION_CONTEXT = 'hideModuleInProductionContext';
+class ExtensionSettingsService
+{
+    const SETTING_LICENSE = 'key';
+    const SETTING_FOLDER = 'folder';
+    const SETTING_HIDE_MODULE_IN_PRODUCTION_CONTEXT = 'hideModuleInProductionContext';
 
-	/**
-	 * @var array Default settings mapped to constants.
-	 */
-	protected static $defaultValueMap = [
-		self::SETTING_FOLDER => 'fileadmin/sg_vimeo/',
-		self::SETTING_HIDE_MODULE_IN_PRODUCTION_CONTEXT => FALSE,
-	];
+    /**
+     * @var array Default settings mapped to constants.
+     */
+    protected static $defaultValueMap = [
+        self::SETTING_FOLDER => 'fileadmin/sg_vimeo/',
+        self::SETTING_HIDE_MODULE_IN_PRODUCTION_CONTEXT => FALSE,
+    ];
 
-	/**
-	 * Returns the setting of one of the constants of this class.
-	 *
-	 * @param string $settingKey
-	 * @return mixed
-	 */
-	public static function getSetting($settingKey) {
-		if (VersionNumberUtility::convertVersionNumberToInteger(VersionNumberUtility::getCurrentTypo3Version()) < 9000000) {
-			// the "options" parameter of unserialize exists since PHP 7.0.0
-			if (version_compare(phpversion(), '7.0.0', '>=')) {
-				$configuration = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['sg_vimeo'], [FALSE]);
-			} else {
-				$configuration = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['sg_vimeo']);
-			}
-		} else {
-			$configuration = $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['sg_vimeo'] ?? [];
-		}
+    /**
+     * Returns the setting of one of the constants of this class.
+     *
+     * @param string $settingKey
+     * @return mixed
+     */
+    public static function getSetting($settingKey)
+    {
+        if (VersionNumberUtility::convertVersionNumberToInteger(VersionNumberUtility::getCurrentTypo3Version()) < 9000000) {
+            // the "options" parameter of unserialize exists since PHP 7.0.0
+            if (version_compare(phpversion(), '7.0.0', '>=')) {
+                $configuration = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['sg_vimeo'], [FALSE]);
+            } else {
+                $configuration = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['sg_vimeo']);
+            }
+        } else {
+            $configuration = $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['sg_vimeo'] ?? [];
+        }
 
-		$setting = '';
-		if (isset(self::$defaultValueMap[$settingKey])) {
-			$setting = self::$defaultValueMap[$settingKey];
-		}
+        $setting = '';
+        if (isset(self::$defaultValueMap[$settingKey])) {
+            $setting = self::$defaultValueMap[$settingKey];
+        }
 
-		if (isset($configuration[$settingKey])) {
-			$setting = self::postProcessSetting($configuration[$settingKey], $settingKey);
-		}
+        if (isset($configuration[$settingKey])) {
+            $setting = self::postProcessSetting($configuration[$settingKey], $settingKey);
+        }
 
-		return $setting;
-	}
+        return $setting;
+    }
 
-	/**
-	 * Post process of the given setting, by the given setting key.
-	 *
-	 * @param mixed $value
-	 * @param string $settingKey
-	 * @return mixed
-	 */
-	protected static function postProcessSetting($value, $settingKey) {
-		if ($settingKey === self::SETTING_FOLDER) {
-			$value = trim($value, " \t\n\r\0\x0B\/") . '/';
+    /**
+     * Post process of the given setting, by the given setting key.
+     *
+     * @param mixed $value
+     * @param string $settingKey
+     * @return mixed
+     */
+    protected static function postProcessSetting($value, $settingKey)
+    {
+        if ($settingKey === self::SETTING_FOLDER) {
+            $value = trim($value, " \t\n\r\0\x0B\/") . '/';
 
-			if (strpos($value, 'EXT:') === 0) {
-				$value = 'typo3conf/ext/' . substr($value, 4);
-			}
-		}
+            if (strpos($value, 'EXT:') === 0) {
+                $value = 'typo3conf/ext/' . substr($value, 4);
+            }
+        }
 
-		// TYPO3 6 stores all settings as strings, some are expected to be booleans, though.
-		$value = ($value === 'FALSE') ? FALSE : $value;
+        // TYPO3 6 stores all settings as strings, some are expected to be booleans, though.
+        $value = ($value === 'FALSE') ? FALSE : $value;
 
-		return $value;
-	}
+        return $value;
+    }
 }
diff --git a/Classes/Service/LicenceCheckService.php b/Classes/Service/LicenceCheckService.php
index 66198121c53a2d51da783194fa2437246d060413..bf2d146458683d643846495010ef4e728aa37301 100644
--- a/Classes/Service/LicenceCheckService.php
+++ b/Classes/Service/LicenceCheckService.php
@@ -1,7 +1,5 @@
 <?php
 
-namespace SGalinski\SgVimeo\Service;
-
 /***************************************************************
  *  Copyright notice
  *
@@ -26,6 +24,8 @@ namespace SGalinski\SgVimeo\Service;
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+namespace SGalinski\SgVimeo\Service;
+
 use TYPO3\CMS\Core\Http\RequestFactory;
 use TYPO3\CMS\Core\Registry;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -37,680 +37,714 @@ use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
  *
  * @package SGalinski\SgVimeo\Service
  */
-class LicenceCheckService {
-	const STATE_LICENSE_VALID = 2;
-	const STATE_LICENSE_INVALID = 1;
-	const STATE_LICENSE_NOT_SET = 0;
-
-	const DEMO_MODE_KEY = 'demo_mode';
-	const DEMO_MODE_LIFETIME = 86400;
-	const DEMO_MODE_MAX_AMOUNT = 3;
-
-	/**
-	 * The product key from ShopWare
-	 */
-	const PRODUCT_KEY = 'sg_vimeo';
-
-	/**
-	 * Namespace for the sys registry
-	 */
-	const REGISTRY_NAMESPACE = 'tx_sgvimeo';
-
-	/**
-	 * Keys for the sys registry
-	 */
-	const IS_KEY_VALID_KEY = 'isKeyValid';
-	const LAST_WARNING_TIMESTAMP_KEY = 'lastWarningTimestamp';
-	const HAS_VALID_LICENSE_UNTIL_TIMESTAMP_KEY = 'hasValidLicenseUntilTimestamp';
-	const LICENSE_CHECKED_IN_VERSION_KEY = 'licenceCheckedInVersion';
-	const LAST_CHECKED_TIMESTAMP_KEY = 'lastCheckedTimestamp';
-	const LAST_AJAX_TIMESTAMP_KEY = 'lastAjaxTimestamp';
-	const LAST_LICENSE_KEY_CHECKED_KEY = 'lastLicenseKeyChecked';
-
-	/**
-	 * Error codes
-	 */
-	const ERROR_INVALID_RESPONSE_CODE = -1;
-	const ERROR_INVALID_RESPONSE_DATA = -2;
-	const ERROR_INVALID_LICENSE_KEY = -3;
-	const ERROR_INVALID_LICENSE_STRUCTURE = -4;
-	const ERROR_TIMESTAMP_INVALID = -5;
-	const ERROR_LICENSE_CHECK_EXCEPTION = -6;
-
-	/**
-	 * Earliest TYPO3 Version that we support
-	 */
-	const EARLIEST_SUPPORTED_VERSION = 8000000;
-
-	/**
-	 * Last response code from server
-	 *
-	 * @var int
-	 */
-	protected static $lastHttpResponseCode = 0;
-
-	/**
-	 * The last exception from the server
-	 *
-	 * @var string
-	 */
-	protected static $lastException = '';
-
-	/**
-	 * The validUntil timestamp
-	 *
-	 * @var null|int
-	 */
-	protected static $validUntil;
-
-	/**
-	 * Check the license key once per how many days
-	 */
-	const AMOUNT_OF_DAYS_UNTIL_NEXT_CHECK = 1;
-
-	/**
-	 * Show a warning if the license has expired but we are still in the same version once per how many days
-	 */
-	const AMOUNT_OF_DAYS_UNTIL_WARNING = 30;
-
-	/**
-	 * License server credentials
-	 */
-	const API_USER = 'license_check';
-	const API_PASSWORD = 'lGKLiHc5We6gBqsggVlwdLNoWv9CEKnWiy7cgMUO';
-	const API_URL = 'https://shop.sgalinski.de/api/license';
-
-	/**
-	 * @var array
-	 */
-	private static $versionToReleaseTimestamp = [
-		'2.5.0' => 1688468637, // Tue, 04 Jul 2023 14:11:50 GMT
-	];
-
-	/**
-	 * The current extension version
-	 */
-	const CURRENT_VERSION = '2.5.0';
-
-	/**
-	 * @param mixed $validUntil A timestamp, which says the lifetime of this key.
-	 * @return boolean True, if the timestamp is invalid.
-	 */
-	public static function isTimestampInvalid($validUntil) {
-		if ($validUntil < 0) {
-			return TRUE;
-		}
-		$releaseTimestampOfCurrentVersion = self::$versionToReleaseTimestamp[self::CURRENT_VERSION];
-		if ($releaseTimestampOfCurrentVersion === NULL || $validUntil < $releaseTimestampOfCurrentVersion) {
-			return TRUE;
-		}
-
-		self::$validUntil = $validUntil;
-		return FALSE;
-	}
-
-	/**
-	 * Should we perform the license check for this key and in this version at this point of time
-	 *
-	 * @param string $licenseKey
-	 * @return bool
-	 */
-	public static function shouldCheckKey($licenseKey) {
-		if ($licenseKey !== self::getLastKey()) {
-			return TRUE;
-		}
-
-		if (self::getLicenseCheckedInVersion() !== self::CURRENT_VERSION) {
-			return TRUE;
-		}
-
-		// the license was valid last time we checked, but it has expired and we haven't done another check since it expired
-		// let's make sure we don't have the wrong state in this case
-		$licenseExpirationDate = self::getValidLicenseUntilTimestamp();
-		/** @noinspection NotOptimalIfConditionsInspection */
-		return self::getValidLicense() && $licenseExpirationDate < $GLOBALS['EXEC_TIME']
-			&& $licenseExpirationDate >= self::getLastLicenseCheckTimestamp();
-	}
-
-	/**
-	 * Returns the license key that has been set
-	 *
-	 * @return string
-	 */
-	public static function getLicenseKey() {
-		return (string) ExtensionSettingsService::getSetting(ExtensionSettingsService::SETTING_LICENSE);
-	}
-
-	/**
-	 * Checks whether the system has a valid license
-	 *
-	 * @return bool
-	 */
-	public static function hasValidLicense() {
-		$licenseKey = self::getLicenseKey();
-		if (!self::shouldCheckKey($licenseKey)) {
-			return self::getValidLicense();
-		}
-		self::clearRegistryValues();
-
-		if (!self::isLicenseServerReachable()) {
-			return TRUE;
-		}
-
-		if (!self::isLicenseValid($licenseKey)) {
-			self::setLastKey($licenseKey);
-			self::setValidLicense(FALSE);
-			self::setLicenseCheckedInVersion(self::CURRENT_VERSION);
-			self::setValidLicenseUntilTimestamp(0);
-			self::setLastLicenseCheckTimestamp();
-		} else {
-			self::setValidLicenseUntilTimestamp(self::getValidUntil());
-			self::setValidLicense(TRUE);
-			self::setLastKey($licenseKey);
-			self::setLicenseCheckedInVersion(self::CURRENT_VERSION);
-			self::setLastLicenseCheckTimestamp();
-			return TRUE;
-		}
-
-		return FALSE;
-	}
-
-	/**
-	 * Sets the last key checked for from the registry
-	 *
-	 * @param string $licenseKey
-	 */
-	protected static function setLastKey($licenseKey) {
-		$registry = GeneralUtility::makeInstance(Registry::class);
-		$registry->set(self::REGISTRY_NAMESPACE, self::LAST_LICENSE_KEY_CHECKED_KEY, $licenseKey);
-	}
-
-	/**
-	 * Gets the last key checked for from the registry
-	 *
-	 * @return mixed|null
-	 */
-	public static function getLastKey() {
-		$registry = GeneralUtility::makeInstance(Registry::class);
-		return $registry->get(self::REGISTRY_NAMESPACE, self::LAST_LICENSE_KEY_CHECKED_KEY);
-	}
-
-	/**
-	 * Sets if the license is valid in the registry
-	 *
-	 * @param bool $isValid
-	 */
-	protected static function setValidLicense($isValid) {
-		$isValid = (bool) $isValid;
-		$registry = GeneralUtility::makeInstance(Registry::class);
-		$registry->set(self::REGISTRY_NAMESPACE, self::IS_KEY_VALID_KEY, $isValid);
-	}
-
-	/**
-	 * Gets the isValid from the registry
-	 *
-	 * @return bool
-	 */
-	protected static function getValidLicense() {
-		$registry = GeneralUtility::makeInstance(Registry::class);
-		return (bool) $registry->get(self::REGISTRY_NAMESPACE, self::IS_KEY_VALID_KEY);
-	}
-
-	/**
-	 * Stores the last warning timestamp
-	 *
-	 * @param int $timestamp
-	 */
-	protected static function setLastWarningTimestamp($timestamp) {
-		$registry = GeneralUtility::makeInstance(Registry::class);
-		$registry->set(self::REGISTRY_NAMESPACE, self::LAST_WARNING_TIMESTAMP_KEY, $timestamp);
-	}
-
-	/**
-	 * Gets the last warning timestamp
-	 *
-	 * @return mixed|null
-	 */
-	protected static function getLastWarningTimestamp() {
-		$registry = GeneralUtility::makeInstance(Registry::class);
-		return $registry->get(self::REGISTRY_NAMESPACE, self::LAST_WARNING_TIMESTAMP_KEY);
-	}
-
-	/**
-	 * Stores the valid until timestamp in the registry
-	 *
-	 * @param mixed $validUntil
-	 */
-	protected static function setValidLicenseUntilTimestamp($validUntil) {
-		$registry = GeneralUtility::makeInstance(Registry::class);
-		$registry->set(self::REGISTRY_NAMESPACE, self::HAS_VALID_LICENSE_UNTIL_TIMESTAMP_KEY, $validUntil);
-	}
-
-	/**
-	 * Gets the valid until timestamp from the registry
-	 *
-	 * @return mixed|null
-	 */
-	protected static function getValidLicenseUntilTimestamp() {
-		$registry = GeneralUtility::makeInstance(Registry::class);
-		return $registry->get(self::REGISTRY_NAMESPACE, self::HAS_VALID_LICENSE_UNTIL_TIMESTAMP_KEY);
-	}
-
-	/**
-	 * Sets the version that the license was last valid for
-	 *
-	 * @param string $version
-	 */
-	protected static function setLicenseCheckedInVersion($version) {
-		$registry = GeneralUtility::makeInstance(Registry::class);
-		$registry->set(self::REGISTRY_NAMESPACE, self::LICENSE_CHECKED_IN_VERSION_KEY, $version);
-	}
-
-	/**
-	 * Gets the version that the license was last valid for
-	 *
-	 * @return mixed|null
-	 */
-	protected static function getLicenseCheckedInVersion() {
-		$registry = GeneralUtility::makeInstance(Registry::class);
-		return $registry->get(self::REGISTRY_NAMESPACE, self::LICENSE_CHECKED_IN_VERSION_KEY);
-	}
-
-	/**
-	 * Sets the timestamp of the last check in the registry
-	 */
-	protected static function setLastLicenseCheckTimestamp() {
-		$registry = GeneralUtility::makeInstance(Registry::class);
-		$registry->set(self::REGISTRY_NAMESPACE, self::LAST_CHECKED_TIMESTAMP_KEY, $GLOBALS['EXEC_TIME']);
-	}
-
-	/**
-	 * Gets the timestamp of the last check from the registry
-	 *
-	 * @return mixed|null
-	 */
-	public static function getLastLicenseCheckTimestamp() {
-		$registry = GeneralUtility::makeInstance(Registry::class);
-		return $registry->get(self::REGISTRY_NAMESPACE, self::LAST_CHECKED_TIMESTAMP_KEY);
-	}
-
-	/**
-	 * Sets the timestamp of the last AJAX Notification check in the registry
-	 */
-	public static function setLastAjaxNotificationCheckTimestamp() {
-		$registry = GeneralUtility::makeInstance(Registry::class);
-		$registry->set(self::REGISTRY_NAMESPACE, self::LAST_AJAX_TIMESTAMP_KEY, $GLOBALS['EXEC_TIME']);
-	}
-
-	/**
-	 * Gets the timestamp of the last AJAX Notification check from the registry
-	 *
-	 * @return mixed|null
-	 */
-	protected static function getLastAjaxNotificationCheckTimestamp() {
-		$registry = GeneralUtility::makeInstance(Registry::class);
-		return $registry->get(self::REGISTRY_NAMESPACE, self::LAST_AJAX_TIMESTAMP_KEY);
-	}
-
-	/**
-	 * Clears the registry values
-	 */
-	protected static function clearRegistryValues() {
-		$registry = GeneralUtility::makeInstance(Registry::class);
-		$registry->remove(self::REGISTRY_NAMESPACE, self::LAST_CHECKED_TIMESTAMP_KEY);
-		$registry->remove(self::REGISTRY_NAMESPACE, self::HAS_VALID_LICENSE_UNTIL_TIMESTAMP_KEY);
-		$registry->remove(self::REGISTRY_NAMESPACE, self::LICENSE_CHECKED_IN_VERSION_KEY);
-		$registry->remove(self::REGISTRY_NAMESPACE, self::IS_KEY_VALID_KEY);
-		$registry->remove(self::REGISTRY_NAMESPACE, self::LAST_LICENSE_KEY_CHECKED_KEY);
-		$registry->remove(self::REGISTRY_NAMESPACE, self::LAST_WARNING_TIMESTAMP_KEY);
-		$registry->remove(self::REGISTRY_NAMESPACE, self::LAST_AJAX_TIMESTAMP_KEY);
-	}
-
-	/**
-	 * Gets the validUntil date from this current check
-	 *
-	 * @return mixed
-	 */
-	public static function getValidUntil() {
-		if (self::$validUntil === NULL) {
-			self::$validUntil = self::getValidLicenseUntilTimestamp();
-		}
-		return self::$validUntil;
-	}
-
-	/**
-	 * The timestamp of the key lifetime, if the given license key is valid, or -1 if invalid.
-	 *
-	 * @param string $licenseKey A license key, which should be validated.
-	 * @return bool
-	 */
-	public static function isLicenseValid($licenseKey) {
-		if (!self::checkLicenseKeyStructure($licenseKey)) {
-			return FALSE;
-		}
-
-		$validUntil = self::getValidUntilTimestampByLicenseKey($licenseKey);
-		return !self::isTimestampInvalid($validUntil);
-	}
-
-	/**
-	 * Check if the given license key is valid.
-	 *
-	 * @param string $licenseKey A license key, which should be validated.
-	 * @return boolean
-	 */
-	public static function checkLicenseKeyStructure($licenseKey) {
-		// Structure: XXXXXX-XXXXXX-XXXXXX-XXXXXX | All upper case
-		if (substr_count($licenseKey, '-') !== 3) {
-			return FALSE;
-		}
-
-		$caseControl = strtoupper($licenseKey);
-		return $licenseKey === $caseControl && strlen($licenseKey) === 27;
-	}
-
-	/**
-	 * True, if the license server is reachable.
-	 *
-	 * @return boolean
-	 */
-	public static function isLicenseServerReachable() {
-		try {
-			$requestFactory = GeneralUtility::makeInstance(RequestFactory::class);
-			$response = $requestFactory->request(
-				self::API_URL,
-				'GET',
-				[
-					'auth' => [self::API_USER, self::API_PASSWORD],
-					'timeout' => 1,
-					'connect_timeout' => 1,
-				]
-			);
-
-			self::$lastHttpResponseCode = (int) $response->getStatusCode();
-
-			if (self::$lastHttpResponseCode !== 200 && self::$lastHttpResponseCode !== 201) {
-				return FALSE;
-			}
-		} catch (\Exception $exception) {
-			return FALSE;
-		}
-
-		return TRUE;
-	}
-
-	/**
-	 * Returns The timestamp of the key lifetime, if the given license key is valid, on the server, or -1 if invalid.
-	 *
-	 * @param string $licenseKey
-	 * @return int
-	 */
-	private static function getValidUntilTimestampByLicenseKey($licenseKey) {
-		try {
-			$url = self::API_URL . '/' . urldecode($licenseKey) . '?product='
-				. self::PRODUCT_KEY;
-			$requestFactory = GeneralUtility::makeInstance(RequestFactory::class);
-			$response = $requestFactory->request(
-				$url,
-				'GET',
-				[
-					'auth' => [self::API_USER, self::API_PASSWORD],
-					'timeout' => 1,
-					'connect_timeout' => 1,
-				]
-			);
-
-			self::$lastHttpResponseCode = (int) $response->getStatusCode();
-
-			if (self::$lastHttpResponseCode !== 200 && self::$lastHttpResponseCode !== 201) {
-				return self::ERROR_INVALID_RESPONSE_CODE;
-			}
-
-			if (!$response->getBody()) {
-				return self::ERROR_INVALID_RESPONSE_DATA;
-			}
-
-			$jsonData = json_decode($response->getBody(), TRUE);
-			if (!$jsonData['serial']['valid']) {
-				return self::ERROR_INVALID_LICENSE_KEY;
-			}
-
-			return (int) $jsonData['serial']['validUntil'];
-		} catch (\Exception $exception) {
-			self::$lastException = $exception->getMessage();
-		}
-
-		return self::ERROR_LICENSE_CHECK_EXCEPTION;
-	}
-
-	/**
-	 * Checks whether we are in development context
-	 *
-	 * @return bool
-	 */
-	public static function isInDevelopmentContext() {
-		$versionNumber = VersionNumberUtility::convertVersionNumberToInteger(VersionNumberUtility::getCurrentTypo3Version());
-		if ($versionNumber >= 9000000) {
-			// Since TYPO3 9LTS
-			$context = \TYPO3\CMS\Core\Core\Environment::getContext();
-		} else {
-			// Prior to TYPO3 9LTS
-			$context = \TYPO3\CMS\Core\Utility\GeneralUtility::getApplicationContext();
-		}
-		return $context->isDevelopment();
-	}
-
-	/**
-	 * Checks if the current TYPO3 version is supported for the license check
-	 *
-	 * @return bool
-	 */
-	public static function isTYPO3VersionSupported() {
-		$versionNumber = VersionNumberUtility::convertVersionNumberToInteger(VersionNumberUtility::getCurrentTypo3Version());
-		return $versionNumber >= self::EARLIEST_SUPPORTED_VERSION;
-	}
-
-	/**
-	 * Checks if the time for the next check has expired.
-	 * error = 0 means no error
-	 * error = 1 is an error
-	 * error = 2 is a warning
-	 *
-	 * @return bool
-	 */
-	public static function isTimeForNextCheck() {
-		return self::getLastAjaxNotificationCheckTimestamp()
-			+ self::AMOUNT_OF_DAYS_UNTIL_NEXT_CHECK * 24 * 60 * 60 < $GLOBALS['EXEC_TIME'];
-	}
-
-	/**
-	 * Performs the license check and returns the output data to the frontend
-	 *
-	 * @param bool $isAjaxCheck
-	 * @return array
-	 */
-	public static function getLicenseCheckResponseData($isAjaxCheck = FALSE) {
-		// if the key is empty - error
-		if (!self::getLicenseKey()) {
-			return [
-				'error' => 1,
-				'title' => LocalizationUtility::translate('backend.licenceCheck.error.title', 'sg_vimeo'),
-				'message' => LocalizationUtility::translate(
-					'backend.licenceCheck.noLicenseKey',
-					'sg_vimeo',
-					[
-						LocalizationUtility::translate('backend.licenceCheck.shopLink', 'sg_vimeo')
-					]
-				)
-			];
-		}
-
-		// if not valid - error
-		if (!self::hasValidLicense()) {
-			return [
-				'error' => 1,
-				'title' => LocalizationUtility::translate('backend.licenceCheck.error.title', 'sg_vimeo'),
-				'message' => LocalizationUtility::translate(
-					'backend.licenceCheck.expiredError.message',
-					'sg_vimeo',
-					[
-						LocalizationUtility::translate('backend.licenceCheck.shopLink', 'sg_vimeo')
-					]
-				)
-			];
-		}
-
-		// if it's valid - check validUntil and throw a warning if the license has expired but you are still
-		// on the valid version
-		if (self::getValidUntil() < $GLOBALS['EXEC_TIME']) {
-			$date = date('d.m.Y', self::getValidUntil());
-
-			if ($isAjaxCheck) {
-				$lastWarningTimestamp = (int) self::getLastWarningTimestamp(
-				); // relevant only for the AJAX notifications
-			}
-
-			if (!$isAjaxCheck || ($lastWarningTimestamp + self::AMOUNT_OF_DAYS_UNTIL_WARNING * 24 * 60 * 60 < $GLOBALS['EXEC_TIME'])) {
-				if ($isAjaxCheck) {
-					self::setLastWarningTimestamp($GLOBALS['EXEC_TIME']);
-				}
-
-				return [
-					'error' => 2,
-					'title' => LocalizationUtility::translate('backend.licenceCheck.warning.title', 'sg_vimeo'),
-					'message' => LocalizationUtility::translate(
-						'backend.licenceCheck.expiringWarning.message',
-						'sg_vimeo',
-						[
-							$date, LocalizationUtility::translate('backend.licenceCheck.shopLink', 'sg_vimeo')
-						]
-					)
-				];
-			}
-		}
-
-		/** @noinspection SuspiciousAssignmentsInspection */
-		$date = date('d.m.Y', self::getValidUntil());
-		// 19.01.2038 == lifetime license
-		if ($date === '19.01.2038') {
-			$date = LocalizationUtility::translate(
-				'backend.licenceCheck.status.lifetime',
-				'sg_vimeo'
-			);
-		}
-
-		return [
-			'error' => 0,
-			'title' => LocalizationUtility::translate('backend.licenceCheck.status.title', 'sg_vimeo'),
-			'message' => LocalizationUtility::translate(
-				'backend.licenceCheck.status.okMessage',
-				'sg_vimeo',
-				[
-					$date
-				]
-			)
-		];
-	}
-
-	/**
-	 * Returns one of the state constants of this class.
-	 *
-	 * @return int
-	 */
-	public static function checkKey() {
-		$key = ExtensionSettingsService::getSetting(ExtensionSettingsService::SETTING_LICENSE);
-		if (empty($key)) {
-			return self::STATE_LICENSE_NOT_SET;
-		}
-
-		if ((bool) preg_match('/^([A-Z\d]{6}-?){4}$/', $key)) {
-			return self::STATE_LICENSE_VALID;
-		}
-
-		return self::STATE_LICENSE_INVALID;
-	}
-
-	/**
-	 * Checks if this instance is in the demo mode.
-	 *
-	 * @return bool
-	 */
-	public static function isInDemoMode() {
-		$demoData = self::getDemoModeData();
-		if (!$demoData) {
-			return FALSE;
-		}
-
-		if (self::getRemainingTimeInDemoMode() <= 0) {
-			return FALSE;
-		}
-
-		if ((int) $demoData['amount'] > self::DEMO_MODE_MAX_AMOUNT) {
-			return FALSE;
-		}
-
-		return TRUE;
-	}
-
-	/**
-	 * Returns the remaining time in seconds for the demo mode.
-	 *
-	 * @return int
-	 */
-	public static function getRemainingTimeInDemoMode() {
-		$demoData = self::getDemoModeData();
-		if (!$demoData) {
-			return 0;
-		}
-
-		return $demoData['lastActivation'] + self::DEMO_MODE_LIFETIME - $GLOBALS['EXEC_TIME'];
-	}
-
-	/**
-	 * Activates the demo mode for this instance.
-	 *
-	 * @return void
-	 */
-	public static function activateDemoMode() {
-		$amount = 1;
-		$demoData = self::getDemoModeData();
-		if ($demoData && isset($demoData['amount'])) {
-			$amount += (int) $demoData['amount'];
-		}
-
-		$registry = GeneralUtility::makeInstance(Registry::class);
-		$registry->set(self::REGISTRY_NAMESPACE, self::DEMO_MODE_KEY, [
-			'lastActivation' => $GLOBALS['EXEC_TIME'],
-			'amount' => $amount,
-		]);
-	}
-
-	/**
-	 * Returns true, if this instance can use the demo mode.
-	 *
-	 * @return bool
-	 */
-	public static function isDemoModeAcceptable() {
-		$demoData = self::getDemoModeData();
-		if (!$demoData) {
-			return TRUE;
-		}
-
-		return (int) $demoData['amount'] < self::DEMO_MODE_MAX_AMOUNT;
-	}
-
-	/**
-	 * Returns the demo mode data, or an empty FALSE on error.
-	 *
-	 * @return array|FALSE
-	 */
-	protected static function getDemoModeData() {
-		$registry = GeneralUtility::makeInstance(Registry::class);
-		$demoData = $registry->get(self::REGISTRY_NAMESPACE, self::DEMO_MODE_KEY);
-		if (!isset($demoData['lastActivation'], $demoData['amount'])) {
-			return FALSE;
-		}
-
-		return $demoData;
-	}
+class LicenceCheckService
+{
+    const STATE_LICENSE_VALID = 2;
+    const STATE_LICENSE_INVALID = 1;
+    const STATE_LICENSE_NOT_SET = 0;
+
+    const DEMO_MODE_KEY = 'demo_mode';
+    const DEMO_MODE_LIFETIME = 86400;
+    const DEMO_MODE_MAX_AMOUNT = 3;
+
+    /**
+     * The product key from ShopWare
+     */
+    const PRODUCT_KEY = 'sg_vimeo';
+
+    /**
+     * Namespace for the sys registry
+     */
+    const REGISTRY_NAMESPACE = 'tx_sgvimeo';
+
+    /**
+     * Keys for the sys registry
+     */
+    const IS_KEY_VALID_KEY = 'isKeyValid';
+    const LAST_WARNING_TIMESTAMP_KEY = 'lastWarningTimestamp';
+    const HAS_VALID_LICENSE_UNTIL_TIMESTAMP_KEY = 'hasValidLicenseUntilTimestamp';
+    const LICENSE_CHECKED_IN_VERSION_KEY = 'licenceCheckedInVersion';
+    const LAST_CHECKED_TIMESTAMP_KEY = 'lastCheckedTimestamp';
+    const LAST_AJAX_TIMESTAMP_KEY = 'lastAjaxTimestamp';
+    const LAST_LICENSE_KEY_CHECKED_KEY = 'lastLicenseKeyChecked';
+
+    /**
+     * Error codes
+     */
+    const ERROR_INVALID_RESPONSE_CODE = -1;
+    const ERROR_INVALID_RESPONSE_DATA = -2;
+    const ERROR_INVALID_LICENSE_KEY = -3;
+    const ERROR_INVALID_LICENSE_STRUCTURE = -4;
+    const ERROR_TIMESTAMP_INVALID = -5;
+    const ERROR_LICENSE_CHECK_EXCEPTION = -6;
+
+    /**
+     * Earliest TYPO3 Version that we support
+     */
+    const EARLIEST_SUPPORTED_VERSION = 8000000;
+
+    /**
+     * Last response code from server
+     *
+     * @var int
+     */
+    protected static $lastHttpResponseCode = 0;
+
+    /**
+     * The last exception from the server
+     *
+     * @var string
+     */
+    protected static $lastException = '';
+
+    /**
+     * The validUntil timestamp
+     *
+     * @var null|int
+     */
+    protected static $validUntil;
+
+    /**
+     * Check the license key once per how many days
+     */
+    const AMOUNT_OF_DAYS_UNTIL_NEXT_CHECK = 1;
+
+    /**
+     * Show a warning if the license has expired but we are still in the same version once per how many days
+     */
+    const AMOUNT_OF_DAYS_UNTIL_WARNING = 30;
+
+    /**
+     * License server credentials
+     */
+    const API_USER = 'license_check';
+    const API_PASSWORD = 'lGKLiHc5We6gBqsggVlwdLNoWv9CEKnWiy7cgMUO';
+    const API_URL = 'https://shop.sgalinski.de/api/license';
+
+    /**
+     * @var array
+     */
+    private static $versionToReleaseTimestamp = [
+        '2.5.0' => 1688468637, // Tue, 04 Jul 2023 14:11:50 GMT
+    ];
+
+    /**
+     * The current extension version
+     */
+    const CURRENT_VERSION = '2.5.0';
+
+    /**
+     * @param mixed $validUntil A timestamp, which says the lifetime of this key.
+     * @return boolean True, if the timestamp is invalid.
+     */
+    public static function isTimestampInvalid($validUntil)
+    {
+        if ($validUntil < 0) {
+            return TRUE;
+        }
+        $releaseTimestampOfCurrentVersion = self::$versionToReleaseTimestamp[self::CURRENT_VERSION];
+        if ($releaseTimestampOfCurrentVersion === NULL || $validUntil < $releaseTimestampOfCurrentVersion) {
+            return TRUE;
+        }
+
+        self::$validUntil = $validUntil;
+        return FALSE;
+    }
+
+    /**
+     * Should we perform the license check for this key and in this version at this point of time
+     *
+     * @param string $licenseKey
+     * @return bool
+     */
+    public static function shouldCheckKey($licenseKey)
+    {
+        if ($licenseKey !== self::getLastKey()) {
+            return TRUE;
+        }
+
+        if (self::getLicenseCheckedInVersion() !== self::CURRENT_VERSION) {
+            return TRUE;
+        }
+
+        // the license was valid last time we checked, but it has expired and we haven't done another check since it expired
+        // let's make sure we don't have the wrong state in this case
+        $licenseExpirationDate = self::getValidLicenseUntilTimestamp();
+        /** @noinspection NotOptimalIfConditionsInspection */
+        return self::getValidLicense() && $licenseExpirationDate < $GLOBALS['EXEC_TIME']
+            && $licenseExpirationDate >= self::getLastLicenseCheckTimestamp();
+    }
+
+    /**
+     * Returns the license key that has been set
+     *
+     * @return string
+     */
+    public static function getLicenseKey()
+    {
+        return (string)ExtensionSettingsService::getSetting(ExtensionSettingsService::SETTING_LICENSE);
+    }
+
+    /**
+     * Checks whether the system has a valid license
+     *
+     * @return bool
+     */
+    public static function hasValidLicense()
+    {
+        $licenseKey = self::getLicenseKey();
+        if (!self::shouldCheckKey($licenseKey)) {
+            return self::getValidLicense();
+        }
+        self::clearRegistryValues();
+
+        if (!self::isLicenseServerReachable()) {
+            return TRUE;
+        }
+
+        if (!self::isLicenseValid($licenseKey)) {
+            self::setLastKey($licenseKey);
+            self::setValidLicense(FALSE);
+            self::setLicenseCheckedInVersion(self::CURRENT_VERSION);
+            self::setValidLicenseUntilTimestamp(0);
+            self::setLastLicenseCheckTimestamp();
+        } else {
+            self::setValidLicenseUntilTimestamp(self::getValidUntil());
+            self::setValidLicense(TRUE);
+            self::setLastKey($licenseKey);
+            self::setLicenseCheckedInVersion(self::CURRENT_VERSION);
+            self::setLastLicenseCheckTimestamp();
+            return TRUE;
+        }
+
+        return FALSE;
+    }
+
+    /**
+     * Sets the last key checked for from the registry
+     *
+     * @param string $licenseKey
+     */
+    protected static function setLastKey($licenseKey)
+    {
+        $registry = GeneralUtility::makeInstance(Registry::class);
+        $registry->set(self::REGISTRY_NAMESPACE, self::LAST_LICENSE_KEY_CHECKED_KEY, $licenseKey);
+    }
+
+    /**
+     * Gets the last key checked for from the registry
+     *
+     * @return mixed|null
+     */
+    public static function getLastKey()
+    {
+        $registry = GeneralUtility::makeInstance(Registry::class);
+        return $registry->get(self::REGISTRY_NAMESPACE, self::LAST_LICENSE_KEY_CHECKED_KEY);
+    }
+
+    /**
+     * Sets if the license is valid in the registry
+     *
+     * @param bool $isValid
+     */
+    protected static function setValidLicense($isValid)
+    {
+        $isValid = (bool)$isValid;
+        $registry = GeneralUtility::makeInstance(Registry::class);
+        $registry->set(self::REGISTRY_NAMESPACE, self::IS_KEY_VALID_KEY, $isValid);
+    }
+
+    /**
+     * Gets the isValid from the registry
+     *
+     * @return bool
+     */
+    protected static function getValidLicense()
+    {
+        $registry = GeneralUtility::makeInstance(Registry::class);
+        return (bool)$registry->get(self::REGISTRY_NAMESPACE, self::IS_KEY_VALID_KEY);
+    }
+
+    /**
+     * Stores the last warning timestamp
+     *
+     * @param int $timestamp
+     */
+    protected static function setLastWarningTimestamp($timestamp)
+    {
+        $registry = GeneralUtility::makeInstance(Registry::class);
+        $registry->set(self::REGISTRY_NAMESPACE, self::LAST_WARNING_TIMESTAMP_KEY, $timestamp);
+    }
+
+    /**
+     * Gets the last warning timestamp
+     *
+     * @return mixed|null
+     */
+    protected static function getLastWarningTimestamp()
+    {
+        $registry = GeneralUtility::makeInstance(Registry::class);
+        return $registry->get(self::REGISTRY_NAMESPACE, self::LAST_WARNING_TIMESTAMP_KEY);
+    }
+
+    /**
+     * Stores the valid until timestamp in the registry
+     *
+     * @param mixed $validUntil
+     */
+    protected static function setValidLicenseUntilTimestamp($validUntil)
+    {
+        $registry = GeneralUtility::makeInstance(Registry::class);
+        $registry->set(self::REGISTRY_NAMESPACE, self::HAS_VALID_LICENSE_UNTIL_TIMESTAMP_KEY, $validUntil);
+    }
+
+    /**
+     * Gets the valid until timestamp from the registry
+     *
+     * @return mixed|null
+     */
+    protected static function getValidLicenseUntilTimestamp()
+    {
+        $registry = GeneralUtility::makeInstance(Registry::class);
+        return $registry->get(self::REGISTRY_NAMESPACE, self::HAS_VALID_LICENSE_UNTIL_TIMESTAMP_KEY);
+    }
+
+    /**
+     * Sets the version that the license was last valid for
+     *
+     * @param string $version
+     */
+    protected static function setLicenseCheckedInVersion($version)
+    {
+        $registry = GeneralUtility::makeInstance(Registry::class);
+        $registry->set(self::REGISTRY_NAMESPACE, self::LICENSE_CHECKED_IN_VERSION_KEY, $version);
+    }
+
+    /**
+     * Gets the version that the license was last valid for
+     *
+     * @return mixed|null
+     */
+    protected static function getLicenseCheckedInVersion()
+    {
+        $registry = GeneralUtility::makeInstance(Registry::class);
+        return $registry->get(self::REGISTRY_NAMESPACE, self::LICENSE_CHECKED_IN_VERSION_KEY);
+    }
+
+    /**
+     * Sets the timestamp of the last check in the registry
+     */
+    protected static function setLastLicenseCheckTimestamp()
+    {
+        $registry = GeneralUtility::makeInstance(Registry::class);
+        $registry->set(self::REGISTRY_NAMESPACE, self::LAST_CHECKED_TIMESTAMP_KEY, $GLOBALS['EXEC_TIME']);
+    }
+
+    /**
+     * Gets the timestamp of the last check from the registry
+     *
+     * @return mixed|null
+     */
+    public static function getLastLicenseCheckTimestamp()
+    {
+        $registry = GeneralUtility::makeInstance(Registry::class);
+        return $registry->get(self::REGISTRY_NAMESPACE, self::LAST_CHECKED_TIMESTAMP_KEY);
+    }
+
+    /**
+     * Sets the timestamp of the last AJAX Notification check in the registry
+     */
+    public static function setLastAjaxNotificationCheckTimestamp()
+    {
+        $registry = GeneralUtility::makeInstance(Registry::class);
+        $registry->set(self::REGISTRY_NAMESPACE, self::LAST_AJAX_TIMESTAMP_KEY, $GLOBALS['EXEC_TIME']);
+    }
+
+    /**
+     * Gets the timestamp of the last AJAX Notification check from the registry
+     *
+     * @return mixed|null
+     */
+    protected static function getLastAjaxNotificationCheckTimestamp()
+    {
+        $registry = GeneralUtility::makeInstance(Registry::class);
+        return $registry->get(self::REGISTRY_NAMESPACE, self::LAST_AJAX_TIMESTAMP_KEY);
+    }
+
+    /**
+     * Clears the registry values
+     */
+    protected static function clearRegistryValues()
+    {
+        $registry = GeneralUtility::makeInstance(Registry::class);
+        $registry->remove(self::REGISTRY_NAMESPACE, self::LAST_CHECKED_TIMESTAMP_KEY);
+        $registry->remove(self::REGISTRY_NAMESPACE, self::HAS_VALID_LICENSE_UNTIL_TIMESTAMP_KEY);
+        $registry->remove(self::REGISTRY_NAMESPACE, self::LICENSE_CHECKED_IN_VERSION_KEY);
+        $registry->remove(self::REGISTRY_NAMESPACE, self::IS_KEY_VALID_KEY);
+        $registry->remove(self::REGISTRY_NAMESPACE, self::LAST_LICENSE_KEY_CHECKED_KEY);
+        $registry->remove(self::REGISTRY_NAMESPACE, self::LAST_WARNING_TIMESTAMP_KEY);
+        $registry->remove(self::REGISTRY_NAMESPACE, self::LAST_AJAX_TIMESTAMP_KEY);
+    }
+
+    /**
+     * Gets the validUntil date from this current check
+     *
+     * @return mixed
+     */
+    public static function getValidUntil()
+    {
+        if (self::$validUntil === NULL) {
+            self::$validUntil = self::getValidLicenseUntilTimestamp();
+        }
+        return self::$validUntil;
+    }
+
+    /**
+     * The timestamp of the key lifetime, if the given license key is valid, or -1 if invalid.
+     *
+     * @param string $licenseKey A license key, which should be validated.
+     * @return bool
+     */
+    public static function isLicenseValid($licenseKey)
+    {
+        if (!self::checkLicenseKeyStructure($licenseKey)) {
+            return FALSE;
+        }
+
+        $validUntil = self::getValidUntilTimestampByLicenseKey($licenseKey);
+        return !self::isTimestampInvalid($validUntil);
+    }
+
+    /**
+     * Check if the given license key is valid.
+     *
+     * @param string $licenseKey A license key, which should be validated.
+     * @return boolean
+     */
+    public static function checkLicenseKeyStructure($licenseKey)
+    {
+        // Structure: XXXXXX-XXXXXX-XXXXXX-XXXXXX | All upper case
+        if (substr_count($licenseKey, '-') !== 3) {
+            return FALSE;
+        }
+
+        $caseControl = strtoupper($licenseKey);
+        return $licenseKey === $caseControl && strlen($licenseKey) === 27;
+    }
+
+    /**
+     * True, if the license server is reachable.
+     *
+     * @return boolean
+     */
+    public static function isLicenseServerReachable()
+    {
+        try {
+            $requestFactory = GeneralUtility::makeInstance(RequestFactory::class);
+            $response = $requestFactory->request(
+                self::API_URL,
+                'GET',
+                [
+                    'auth' => [self::API_USER, self::API_PASSWORD],
+                    'timeout' => 1,
+                    'connect_timeout' => 1,
+                ]
+            );
+
+            self::$lastHttpResponseCode = (int)$response->getStatusCode();
+
+            if (self::$lastHttpResponseCode !== 200 && self::$lastHttpResponseCode !== 201) {
+                return FALSE;
+            }
+        } catch (\Exception $exception) {
+            return FALSE;
+        }
+
+        return TRUE;
+    }
+
+    /**
+     * Returns The timestamp of the key lifetime, if the given license key is valid, on the server, or -1 if invalid.
+     *
+     * @param string $licenseKey
+     * @return int
+     */
+    private static function getValidUntilTimestampByLicenseKey($licenseKey)
+    {
+        try {
+            $url = self::API_URL . '/' . urldecode($licenseKey) . '?product='
+                . self::PRODUCT_KEY;
+            $requestFactory = GeneralUtility::makeInstance(RequestFactory::class);
+            $response = $requestFactory->request(
+                $url,
+                'GET',
+                [
+                    'auth' => [self::API_USER, self::API_PASSWORD],
+                    'timeout' => 1,
+                    'connect_timeout' => 1,
+                ]
+            );
+
+            self::$lastHttpResponseCode = (int)$response->getStatusCode();
+
+            if (self::$lastHttpResponseCode !== 200 && self::$lastHttpResponseCode !== 201) {
+                return self::ERROR_INVALID_RESPONSE_CODE;
+            }
+
+            if (!$response->getBody()) {
+                return self::ERROR_INVALID_RESPONSE_DATA;
+            }
+
+            $jsonData = json_decode($response->getBody(), TRUE);
+            if (!$jsonData['serial']['valid']) {
+                return self::ERROR_INVALID_LICENSE_KEY;
+            }
+
+            return (int)$jsonData['serial']['validUntil'];
+        } catch (\Exception $exception) {
+            self::$lastException = $exception->getMessage();
+        }
+
+        return self::ERROR_LICENSE_CHECK_EXCEPTION;
+    }
+
+    /**
+     * Checks whether we are in development context
+     *
+     * @return bool
+     */
+    public static function isInDevelopmentContext()
+    {
+        $versionNumber = VersionNumberUtility::convertVersionNumberToInteger(VersionNumberUtility::getCurrentTypo3Version());
+        if ($versionNumber >= 9000000) {
+            // Since TYPO3 9LTS
+            $context = \TYPO3\CMS\Core\Core\Environment::getContext();
+        } else {
+            // Prior to TYPO3 9LTS
+            $context = \TYPO3\CMS\Core\Utility\GeneralUtility::getApplicationContext();
+        }
+        return $context->isDevelopment();
+    }
+
+    /**
+     * Checks if the current TYPO3 version is supported for the license check
+     *
+     * @return bool
+     */
+    public static function isTYPO3VersionSupported()
+    {
+        $versionNumber = VersionNumberUtility::convertVersionNumberToInteger(VersionNumberUtility::getCurrentTypo3Version());
+        return $versionNumber >= self::EARLIEST_SUPPORTED_VERSION;
+    }
+
+    /**
+     * Checks if the time for the next check has expired.
+     * error = 0 means no error
+     * error = 1 is an error
+     * error = 2 is a warning
+     *
+     * @return bool
+     */
+    public static function isTimeForNextCheck()
+    {
+        return self::getLastAjaxNotificationCheckTimestamp()
+            + self::AMOUNT_OF_DAYS_UNTIL_NEXT_CHECK * 24 * 60 * 60 < $GLOBALS['EXEC_TIME'];
+    }
+
+    /**
+     * Performs the license check and returns the output data to the frontend
+     *
+     * @param bool $isAjaxCheck
+     * @return array
+     */
+    public static function getLicenseCheckResponseData($isAjaxCheck = FALSE)
+    {
+        // if the key is empty - error
+        if (!self::getLicenseKey()) {
+            return [
+                'error' => 1,
+                'title' => LocalizationUtility::translate('backend.licenceCheck.error.title', 'sg_vimeo'),
+                'message' => LocalizationUtility::translate(
+                    'backend.licenceCheck.noLicenseKey',
+                    'sg_vimeo',
+                    [
+                        LocalizationUtility::translate('backend.licenceCheck.shopLink', 'sg_vimeo')
+                    ]
+                )
+            ];
+        }
+
+        // if not valid - error
+        if (!self::hasValidLicense()) {
+            return [
+                'error' => 1,
+                'title' => LocalizationUtility::translate('backend.licenceCheck.error.title', 'sg_vimeo'),
+                'message' => LocalizationUtility::translate(
+                    'backend.licenceCheck.expiredError.message',
+                    'sg_vimeo',
+                    [
+                        LocalizationUtility::translate('backend.licenceCheck.shopLink', 'sg_vimeo')
+                    ]
+                )
+            ];
+        }
+
+        // if it's valid - check validUntil and throw a warning if the license has expired but you are still
+        // on the valid version
+        if (self::getValidUntil() < $GLOBALS['EXEC_TIME']) {
+            $date = date('d.m.Y', self::getValidUntil());
+
+            if ($isAjaxCheck) {
+                $lastWarningTimestamp = (int)self::getLastWarningTimestamp(); // relevant only for the AJAX notifications
+            }
+
+            if (!$isAjaxCheck || ($lastWarningTimestamp + self::AMOUNT_OF_DAYS_UNTIL_WARNING * 24 * 60 * 60 < $GLOBALS['EXEC_TIME'])) {
+                if ($isAjaxCheck) {
+                    self::setLastWarningTimestamp($GLOBALS['EXEC_TIME']);
+                }
+
+                return [
+                    'error' => 2,
+                    'title' => LocalizationUtility::translate('backend.licenceCheck.warning.title', 'sg_vimeo'),
+                    'message' => LocalizationUtility::translate(
+                        'backend.licenceCheck.expiringWarning.message',
+                        'sg_vimeo',
+                        [
+                            $date, LocalizationUtility::translate('backend.licenceCheck.shopLink', 'sg_vimeo')
+                        ]
+                    )
+                ];
+            }
+        }
+
+        /** @noinspection SuspiciousAssignmentsInspection */
+        $date = date('d.m.Y', self::getValidUntil());
+        // 19.01.2038 == lifetime license
+        if ($date === '19.01.2038') {
+            $date = LocalizationUtility::translate(
+                'backend.licenceCheck.status.lifetime',
+                'sg_vimeo'
+            );
+        }
+
+        return [
+            'error' => 0,
+            'title' => LocalizationUtility::translate('backend.licenceCheck.status.title', 'sg_vimeo'),
+            'message' => LocalizationUtility::translate(
+                'backend.licenceCheck.status.okMessage',
+                'sg_vimeo',
+                [
+                    $date
+                ]
+            )
+        ];
+    }
+
+    /**
+     * Returns one of the state constants of this class.
+     *
+     * @return int
+     */
+    public static function checkKey()
+    {
+        $key = ExtensionSettingsService::getSetting(ExtensionSettingsService::SETTING_LICENSE);
+        if (empty($key)) {
+            return self::STATE_LICENSE_NOT_SET;
+        }
+
+        if ((bool)preg_match('/^([A-Z\d]{6}-?){4}$/', $key)) {
+            return self::STATE_LICENSE_VALID;
+        }
+
+        return self::STATE_LICENSE_INVALID;
+    }
+
+    /**
+     * Checks if this instance is in the demo mode.
+     *
+     * @return bool
+     */
+    public static function isInDemoMode()
+    {
+        $demoData = self::getDemoModeData();
+        if (!$demoData) {
+            return FALSE;
+        }
+
+        if (self::getRemainingTimeInDemoMode() <= 0) {
+            return FALSE;
+        }
+
+        if ((int)$demoData['amount'] > self::DEMO_MODE_MAX_AMOUNT) {
+            return FALSE;
+        }
+
+        return TRUE;
+    }
+
+    /**
+     * Returns the remaining time in seconds for the demo mode.
+     *
+     * @return int
+     */
+    public static function getRemainingTimeInDemoMode()
+    {
+        $demoData = self::getDemoModeData();
+        if (!$demoData) {
+            return 0;
+        }
+
+        return $demoData['lastActivation'] + self::DEMO_MODE_LIFETIME - $GLOBALS['EXEC_TIME'];
+    }
+
+    /**
+     * Activates the demo mode for this instance.
+     *
+     * @return void
+     */
+    public static function activateDemoMode()
+    {
+        $amount = 1;
+        $demoData = self::getDemoModeData();
+        if ($demoData && isset($demoData['amount'])) {
+            $amount += (int)$demoData['amount'];
+        }
+
+        $registry = GeneralUtility::makeInstance(Registry::class);
+        $registry->set(self::REGISTRY_NAMESPACE, self::DEMO_MODE_KEY, [
+            'lastActivation' => $GLOBALS['EXEC_TIME'],
+            'amount' => $amount,
+        ]);
+    }
+
+    /**
+     * Returns true, if this instance can use the demo mode.
+     *
+     * @return bool
+     */
+    public static function isDemoModeAcceptable()
+    {
+        $demoData = self::getDemoModeData();
+        if (!$demoData) {
+            return TRUE;
+        }
+
+        return (int)$demoData['amount'] < self::DEMO_MODE_MAX_AMOUNT;
+    }
+
+    /**
+     * Returns the demo mode data, or an empty FALSE on error.
+     *
+     * @return array|FALSE
+     */
+    protected static function getDemoModeData()
+    {
+        $registry = GeneralUtility::makeInstance(Registry::class);
+        $demoData = $registry->get(self::REGISTRY_NAMESPACE, self::DEMO_MODE_KEY);
+        if (!isset($demoData['lastActivation'], $demoData['amount'])) {
+            return FALSE;
+        }
+
+        return $demoData;
+    }
 }
diff --git a/Classes/Service/VimeoService.php b/Classes/Service/VimeoService.php
index 4681f675d8ba16f9258ac3b781ca5b90f7a4158a..d667c1c65380d7d9779b27074cd057f08bade506 100644
--- a/Classes/Service/VimeoService.php
+++ b/Classes/Service/VimeoService.php
@@ -37,259 +37,269 @@ use Vimeo\Vimeo;
 /**
  * Vimeo Helper Service
  */
-class VimeoService implements LoggerAwareInterface {
-	use LoggerAwareTrait;
-
-	protected const API_CHANNEL = '/channels/';
-	protected const API_VIDEO = '/videos/';
-	protected const API_SHOWCASE = '/me/albums/';
-
-	/**
-	 * https://developer.vimeo.com/api/authentication#supported-scopes
-	 */
-	protected const SCOPE = 'public';
-
-	public const CACHE_LIFETIME_IN_SECONDS = 86400;
-
-	/**
-	 * @var FrontendInterface
-	 */
-	protected $cache;
-
-	/**
-	 * @var Vimeo
-	 */
-	protected $vimeoApiClient;
-
-	/**
-	 * @var array
-	 */
-	protected $paginatedResponseData;
-
-	/**
-	 * @var int
-	 * Used for the `per_page` param, for the vimeo API requests.
-	 * Use `per_page` to set the number of representations per page from the default value of 25 up to a maximum value of 100.
-	 */
-	protected $maxResultsPerPage = 25;
-
-	/**
-	 * @var int
-	 * The amount of videos fetched within the current pagination request
-	 */
-	protected $amountOfVideosFetched = 0;
-
-	/**
-	 * VimeoService constructor.
-	 *
-	 * @param string $clientId
-	 * @param string $clientSecret
-	 * @param string $personalAccessToken
-	 */
-	public function __construct(
-		string $clientId,
-		string $clientSecret,
-		string $personalAccessToken,
-		FrontendInterface $cache
-	) {
-		$this->vimeoApiClient = new Vimeo($clientId, $clientSecret, $personalAccessToken);
-		// We only need to request an unauthenticated token, if there is no personal access token provided already.
-		// An authenticated access token with the public scope is identical to an unauthenticated access token,
-		// except that you can use the /me endpoint to refer to the currently logged-in user.
-		// Accessing /me with an unauthenticated access token generates an error.
-		// See also: https://developer.vimeo.com/api/authentication
-		if ($personalAccessToken === '') {
-			$this->requestAccessToken();
-		}
-		$this->cache = $cache;
-	}
-
-	/**
-	 * @param string $vimeoId can be a video id, showcase id or a channel name
-	 * @param int $maxResults
-	 * @return array|null
-	 */
-	public function getVimeoData(string $vimeoId, int $maxResults): ?array {
-		$response = [];
-		$this->maxResultsPerPage = $maxResults;
-		$cacheKey = 'sg_vimeo' . sha1($vimeoId . $maxResults);
-		$disableVimeoCache = (bool) GeneralUtility::_GP('disableVimeoCache');
-		if (!$disableVimeoCache) {
-			$cachedResult = $this->cache->get($cacheKey);
-			if ($cachedResult) {
-				return $cachedResult;
-			}
-		}
-
-		if (strpos($vimeoId, 'showcase') === 0) {
-			$showcaseId = explode('/', $vimeoId)[1];
-			$response['items'] = $this->addVideoIdsToResponse($this->getShowcaseVideos((int) $showcaseId));
-			$response['kind'] = 'showcase';
-		} elseif (strpos($vimeoId, 'channel') === 0) {
-			$channelId = explode('/', $vimeoId)[1];
-			$response['items'] = $this->addVideoIdsToResponse($this->getChannelVideos($channelId));
-			$response['kind'] = 'channel';
-		} else {
-			$response['items'] = $this->addVideoIdsToResponse($this->getVideo((int) $vimeoId));
-			$response['kind'] = 'video';
-		}
-
-		if (!$disableVimeoCache) {
-			$this->cache->set($cacheKey, $response, [], self::CACHE_LIFETIME_IN_SECONDS);
-		}
-
-		return $response;
-	}
-
-	/**
-	 * Extracts the video id from the video's canonical relative URI and adds it to each entry with the key 'videoId'
-	 *
-	 * @param array|null $response
-	 * @return array|null
-	 */
-	protected function addVideoIdsToResponse(?array $response): ?array {
-		if (!is_array($response)) {
-			return NULL;
-		}
-
-		foreach ($response as $index => $item) {
-			if (array_key_exists('uri', $item)) {
-				$uri = $item['uri'];
-				$videoId = (int) str_replace('/videos/', '', $uri);
-				$response[$index]['videoId'] = $videoId;
-			}
-		}
-
-		return $response;
-	}
-
-	/**
-	 * Unauthenticated API requests must generate an access token.
-	 * (Access tokens without a user. These tokens can view only public data.)
-	 * You should not generate a new access token for each request.
-	 * Instead, request an access token once and use it forever.
-	 */
-	protected function requestAccessToken(): void {
-		$token = $this->vimeoApiClient->clientCredentials(self::SCOPE);
-		if (isset($token['body']['access_token'])) {
-			$this->vimeoApiClient->setToken($token['body']['access_token']);
-		}
-	}
-
-	/**
-	 * Returns the response body, wrapped in an array if the response contains a single item.
-	 * If the response is a paginated response, all items are fetched until the maxResultsPerPage is reached,
-	 * or no $nextUrl is available anymore (last page reached). Since the flexform allows a max value of 100 currently,
-	 * this function will never go past the first page, since the vimeo API allows a value of 100 as max value for the `per_page` parameter.
-	 *
-	 * @param array|null $response
-	 * @return array|null
-	 */
-	protected function preprocessApiResponse(?array $response): ?array {
-		if (!is_array($response)) {
-			return NULL;
-		}
-
-		// log error & return here, since the response was not OK
-		if ($response['status'] !== 200) {
-			$this->logger->error('sg_vimeo API Request failed, got the following response:', $response);
-			return [$response['body']];
-		}
-
-		// @TODO: we could check $response['headers‘]['X-RateLimit-Remaining'] here for remaining quota
-		if (array_key_exists('paging', $response['body'])) {
-			$amountOfVideosInResponse = is_countable($response['body']['data']) ? count($response['body']['data']) : 0;
-			$this->amountOfVideosFetched += $amountOfVideosInResponse;
-			$this->paginatedResponseData[] = $response['body']['data'];
-			$nextUrl = $response['body']['paging']['next'];
-			if ($this->amountOfVideosFetched === $this->maxResultsPerPage || $nextUrl === NULL) {
-				// return flattened array here, so that we don't end up with one sub array per pagination page
-				return array_merge(...$this->paginatedResponseData);
-			}
-
-			$this->fetchPaginatedResult($nextUrl);
-		}
-
-		// wrap response body in an array, so that we can treat all return values the same in the template
-		return [$response['body']];
-	}
-
-	/**
-	 * @param string $nextUrl
-	 * @return array|null
-	 */
-	protected function fetchPaginatedResult(string $nextUrl): ?array {
-		try {
-			$response = $this->vimeoApiClient->request($nextUrl);
-		} catch (VimeoRequestException $e) {
-			return NULL;
-		}
-
-		return $this->preprocessApiResponse($response);
-	}
-
-	/**
-	 * Returns a single video for the given $videoId
-	 *
-	 * @see https://developer.vimeo.com/api/reference/videos#get_video
-	 * @param int $videoId
-	 * @return array|null
-	 */
-	public function getVideo(int $videoId): ?array {
-		// use field filtering, to save on quota, see: https://developer.vimeo.com/guidelines/rate-limiting
-		$fieldsToSelect = 'uri,name,description,link,embed,pictures,release_time,width,height';
-		try {
-			$response = $this->vimeoApiClient->request(self::API_VIDEO . $videoId . '?fields=' . $fieldsToSelect);
-		} catch (VimeoRequestException $e) {
-			$response = NULL;
-			throw $e;
-		}
-
-		return $this->preprocessApiResponse($response);
-	}
-
-	/**
-	 * Returns all videos for the given $channelIdentifier
-	 *
-	 * @see https://developer.vimeo.com/api/reference/channels#get_channel_videos
-	 * @param string $channelIdentifier
-	 * @return array|null
-	 */
-	public function getChannelVideos(string $channelIdentifier): ?array {
-		// use field filtering, to save on quota, see: https://developer.vimeo.com/guidelines/rate-limiting
-		$fieldsToSelect = 'uri,name,description,link,embed,pictures,release_time,width,height';
-		try {
-			$response = $this->vimeoApiClient->request(
-				self::API_CHANNEL . $channelIdentifier . self::API_VIDEO . '?fields=' . $fieldsToSelect . '&per_page=' . $this->maxResultsPerPage
-			);
-		} catch (VimeoRequestException $e) {
-			$response = NULL;
-			throw $e;
-		}
-
-		return $this->preprocessApiResponse($response);
-	}
-
-	/**
-	 * Returns all videos for the given $showcaseId
-	 *
-	 * @see https://developer.vimeo.com/api/reference/showcases#get_showcase
-	 * @param string $showcaseId
-	 * @return array|null
-	 */
-	public function getShowcaseVideos(string $showcaseId): ?array {
-		// use field filtering, to save on quota, see: https://developer.vimeo.com/guidelines/rate-limiting
-		$fieldsToSelect = 'uri,name,description,link,embed,pictures,release_time,width,height';
-		// sort videos by the user-selected default: ?sort=default
-		try {
-			$response = $this->vimeoApiClient->request(
-				self::API_SHOWCASE . $showcaseId . self::API_VIDEO . '?sort=default&fields=' . $fieldsToSelect . '&per_page=' . $this->maxResultsPerPage
-			);
-		} catch (VimeoRequestException $e) {
-			$response = NULL;
-			throw $e;
-		}
-
-		return $this->preprocessApiResponse($response);
-	}
+class VimeoService implements LoggerAwareInterface
+{
+    use LoggerAwareTrait;
+
+    protected const API_CHANNEL = '/channels/';
+    protected const API_VIDEO = '/videos/';
+    protected const API_SHOWCASE = '/me/albums/';
+
+    /**
+     * https://developer.vimeo.com/api/authentication#supported-scopes
+     */
+    protected const SCOPE = 'public';
+
+    public const CACHE_LIFETIME_IN_SECONDS = 86400;
+
+    /**
+     * @var FrontendInterface
+     */
+    protected $cache;
+
+    /**
+     * @var Vimeo
+     */
+    protected $vimeoApiClient;
+
+    /**
+     * @var array
+     */
+    protected $paginatedResponseData;
+
+    /**
+     * @var int
+     * Used for the `per_page` param, for the vimeo API requests.
+     * Use `per_page` to set the number of representations per page from the default value of 25 up to a maximum value of 100.
+     */
+    protected $maxResultsPerPage = 25;
+
+    /**
+     * @var int
+     * The amount of videos fetched within the current pagination request
+     */
+    protected $amountOfVideosFetched = 0;
+
+    /**
+     * VimeoService constructor.
+     *
+     * @param string $clientId
+     * @param string $clientSecret
+     * @param string $personalAccessToken
+     */
+    public function __construct(
+        string            $clientId,
+        string            $clientSecret,
+        string            $personalAccessToken,
+        FrontendInterface $cache
+    )
+    {
+        $this->vimeoApiClient = new Vimeo($clientId, $clientSecret, $personalAccessToken);
+        // We only need to request an unauthenticated token, if there is no personal access token provided already.
+        // An authenticated access token with the public scope is identical to an unauthenticated access token,
+        // except that you can use the /me endpoint to refer to the currently logged-in user.
+        // Accessing /me with an unauthenticated access token generates an error.
+        // See also: https://developer.vimeo.com/api/authentication
+        if ($personalAccessToken === '') {
+            $this->requestAccessToken();
+        }
+        $this->cache = $cache;
+    }
+
+    /**
+     * @param string $vimeoId can be a video id, showcase id or a channel name
+     * @param int $maxResults
+     * @return array|null
+     */
+    public function getVimeoData(string $vimeoId, int $maxResults): ?array
+    {
+        $response = [];
+        $this->maxResultsPerPage = $maxResults;
+        $cacheKey = 'sg_vimeo' . sha1($vimeoId . $maxResults);
+        $disableVimeoCache = (bool)GeneralUtility::_GP('disableVimeoCache');
+        if (!$disableVimeoCache) {
+            $cachedResult = $this->cache->get($cacheKey);
+            if ($cachedResult) {
+                return $cachedResult;
+            }
+        }
+
+        if (strpos($vimeoId, 'showcase') === 0) {
+            $showcaseId = explode('/', $vimeoId)[1];
+            $response['items'] = $this->addVideoIdsToResponse($this->getShowcaseVideos((int)$showcaseId));
+            $response['kind'] = 'showcase';
+        } elseif (strpos($vimeoId, 'channel') === 0) {
+            $channelId = explode('/', $vimeoId)[1];
+            $response['items'] = $this->addVideoIdsToResponse($this->getChannelVideos($channelId));
+            $response['kind'] = 'channel';
+        } else {
+            $response['items'] = $this->addVideoIdsToResponse($this->getVideo((int)$vimeoId));
+            $response['kind'] = 'video';
+        }
+
+        if (!$disableVimeoCache) {
+            $this->cache->set($cacheKey, $response, [], self::CACHE_LIFETIME_IN_SECONDS);
+        }
+
+        return $response;
+    }
+
+    /**
+     * Extracts the video id from the video's canonical relative URI and adds it to each entry with the key 'videoId'
+     *
+     * @param array|null $response
+     * @return array|null
+     */
+    protected function addVideoIdsToResponse(?array $response): ?array
+    {
+        if (!is_array($response)) {
+            return NULL;
+        }
+
+        foreach ($response as $index => $item) {
+            if (array_key_exists('uri', $item)) {
+                $uri = $item['uri'];
+                $videoId = (int)str_replace('/videos/', '', $uri);
+                $response[$index]['videoId'] = $videoId;
+            }
+        }
+
+        return $response;
+    }
+
+    /**
+     * Unauthenticated API requests must generate an access token.
+     * (Access tokens without a user. These tokens can view only public data.)
+     * You should not generate a new access token for each request.
+     * Instead, request an access token once and use it forever.
+     */
+    protected function requestAccessToken(): void
+    {
+        $token = $this->vimeoApiClient->clientCredentials(self::SCOPE);
+        if (isset($token['body']['access_token'])) {
+            $this->vimeoApiClient->setToken($token['body']['access_token']);
+        }
+    }
+
+    /**
+     * Returns the response body, wrapped in an array if the response contains a single item.
+     * If the response is a paginated response, all items are fetched until the maxResultsPerPage is reached,
+     * or no $nextUrl is available anymore (last page reached). Since the flexform allows a max value of 100 currently,
+     * this function will never go past the first page, since the vimeo API allows a value of 100 as max value for the `per_page` parameter.
+     *
+     * @param array|null $response
+     * @return array|null
+     */
+    protected function preprocessApiResponse(?array $response): ?array
+    {
+        if (!is_array($response)) {
+            return NULL;
+        }
+
+        // log error & return here, since the response was not OK
+        if ($response['status'] !== 200) {
+            $this->logger->error('sg_vimeo API Request failed, got the following response:', $response);
+            return [$response['body']];
+        }
+
+        // @TODO: we could check $response['headers‘]['X-RateLimit-Remaining'] here for remaining quota
+        if (array_key_exists('paging', $response['body'])) {
+            $amountOfVideosInResponse = is_countable($response['body']['data']) ? count($response['body']['data']) : 0;
+            $this->amountOfVideosFetched += $amountOfVideosInResponse;
+            $this->paginatedResponseData[] = $response['body']['data'];
+            $nextUrl = $response['body']['paging']['next'];
+            if ($this->amountOfVideosFetched === $this->maxResultsPerPage || $nextUrl === NULL) {
+                // return flattened array here, so that we don't end up with one sub array per pagination page
+                return array_merge(...$this->paginatedResponseData);
+            }
+
+            $this->fetchPaginatedResult($nextUrl);
+        }
+
+        // wrap response body in an array, so that we can treat all return values the same in the template
+        return [$response['body']];
+    }
+
+    /**
+     * @param string $nextUrl
+     * @return array|null
+     */
+    protected function fetchPaginatedResult(string $nextUrl): ?array
+    {
+        try {
+            $response = $this->vimeoApiClient->request($nextUrl);
+        } catch (VimeoRequestException $e) {
+            return NULL;
+        }
+
+        return $this->preprocessApiResponse($response);
+    }
+
+    /**
+     * Returns a single video for the given $videoId
+     *
+     * @see https://developer.vimeo.com/api/reference/videos#get_video
+     * @param int $videoId
+     * @return array|null
+     */
+    public function getVideo(int $videoId): ?array
+    {
+        // use field filtering, to save on quota, see: https://developer.vimeo.com/guidelines/rate-limiting
+        $fieldsToSelect = 'uri,name,description,link,embed,pictures,release_time,width,height';
+        try {
+            $response = $this->vimeoApiClient->request(self::API_VIDEO . $videoId . '?fields=' . $fieldsToSelect);
+        } catch (VimeoRequestException $e) {
+            $response = NULL;
+            throw $e;
+        }
+
+        return $this->preprocessApiResponse($response);
+    }
+
+    /**
+     * Returns all videos for the given $channelIdentifier
+     *
+     * @see https://developer.vimeo.com/api/reference/channels#get_channel_videos
+     * @param string $channelIdentifier
+     * @return array|null
+     */
+    public function getChannelVideos(string $channelIdentifier): ?array
+    {
+        // use field filtering, to save on quota, see: https://developer.vimeo.com/guidelines/rate-limiting
+        $fieldsToSelect = 'uri,name,description,link,embed,pictures,release_time,width,height';
+        try {
+            $response = $this->vimeoApiClient->request(
+                self::API_CHANNEL . $channelIdentifier . self::API_VIDEO . '?fields=' . $fieldsToSelect . '&per_page=' . $this->maxResultsPerPage
+            );
+        } catch (VimeoRequestException $e) {
+            $response = NULL;
+            throw $e;
+        }
+
+        return $this->preprocessApiResponse($response);
+    }
+
+    /**
+     * Returns all videos for the given $showcaseId
+     *
+     * @see https://developer.vimeo.com/api/reference/showcases#get_showcase
+     * @param string $showcaseId
+     * @return array|null
+     */
+    public function getShowcaseVideos(string $showcaseId): ?array
+    {
+        // use field filtering, to save on quota, see: https://developer.vimeo.com/guidelines/rate-limiting
+        $fieldsToSelect = 'uri,name,description,link,embed,pictures,release_time,width,height';
+        // sort videos by the user-selected default: ?sort=default
+        try {
+            $response = $this->vimeoApiClient->request(
+                self::API_SHOWCASE . $showcaseId . self::API_VIDEO . '?sort=default&fields=' . $fieldsToSelect . '&per_page=' . $this->maxResultsPerPage
+            );
+        } catch (VimeoRequestException $e) {
+            $response = NULL;
+            throw $e;
+        }
+
+        return $this->preprocessApiResponse($response);
+    }
 }
diff --git a/Classes/ViewHelpers/RenderSvgViewHelper.php b/Classes/ViewHelpers/RenderSvgViewHelper.php
index 07811ef3bcda0ec8c46935000cd8d6fe69cf8a6b..f5fbbc5ad4777b356bcfe8484cf9a8fb5b5e3427 100644
--- a/Classes/ViewHelpers/RenderSvgViewHelper.php
+++ b/Classes/ViewHelpers/RenderSvgViewHelper.php
@@ -33,23 +33,25 @@ use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
  *
  * @package SGalinski\SgVimeo\ViewHelpers
  */
-class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
+class RenderSvgViewHelper extends AbstractTagBasedViewHelper
+{
 
-	/**
-	 * Name of the tag to be created by this view helper
-	 *
-	 * @var string
-	 * @api
-	 */
-	protected $tagName = 'svg';
+    /**
+     * Name of the tag to be created by this view helper
+     *
+     * @var string
+     * @api
+     */
+    protected $tagName = 'svg';
 
     protected $directoryPath = __DIR__ . '/../../Resources/Public/Icons/';
 
-	/**
-	 * Register the ViewHelper arguments
-	 */
-	public function initializeArguments(): void {
-		parent::initializeArguments();
+    /**
+     * Register the ViewHelper arguments
+     */
+    public function initializeArguments(): void
+    {
+        parent::initializeArguments();
         $this->registerArgument('name', 'string', 'The SVG name', TRUE);
         $this->registerArgument('color', 'string', 'The fill color', TRUE);
         $this->registerArgument('id', 'string', 'The HTML id attribute', FALSE);
@@ -60,7 +62,7 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
         $this->registerArgument('height', 'string', 'The HTML height attribute', FALSE);
         $this->registerArgument('style', 'string', 'Inline CSS styles', FALSE);
         $this->registerArgument('use', 'string', 'Inline CSS styles', FALSE);
-	}
+    }
 
 
     /**
@@ -81,7 +83,7 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
         $style = $this->arguments['style'];
         $title = $this->arguments['title'];
 
-        $src = $path ?? $this->directoryPath . '/' . $name .'.svg';
+        $src = $path ?? $this->directoryPath . '/' . $name . '.svg';
 
 
         // Get the content of the SVG file
@@ -97,7 +99,7 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
 
         // Set the attributes of the SVG element
         if ($width > 0) {
-           $this->addOrReplaceAttribute($svg, 'width', $width);
+            $this->addOrReplaceAttribute($svg, 'width', $width);
         }
 
         if ($height > 0) {
@@ -117,7 +119,7 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
         }
 
         if ($title) {
-            $this->addOrReplaceAttribute($svg,'title', $title);
+            $this->addOrReplaceAttribute($svg, 'title', $title);
         }
 
 //        // Set the ID of the SVG element
@@ -153,11 +155,11 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
 
         //Todo: we don't really want this, do we?
         if (!empty($width) && !empty($height)) {
-        		$resultWithoutCssClass = str_replace($cssClass, '', $result);
-        		$cssClasses = $this->processWrapperClasses($cssClassPlain);
+            $resultWithoutCssClass = str_replace($cssClass, '', $result);
+            $cssClasses = $this->processWrapperClasses($cssClassPlain);
 
-        		return "<span $cssClasses style='width: $width; height: $height;'>$resultWithoutCssClass</span>";
-        	}
+            return "<span $cssClasses style='width: $width; height: $height;'>$resultWithoutCssClass</span>";
+        }
 
         if (!empty($width)) {
             $resultWithoutCssClass = str_replace($cssClass, '', $result);
@@ -182,8 +184,9 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
      * @param string $cssClass
      * @return string
      */
-    function processWrapperClasses(string $cssClass): string {
-    	return "class='$cssClass svg-wrapper d-inline-flex justify-content-center align-items-center'";
+    function processWrapperClasses(string $cssClass): string
+    {
+        return "class='$cssClass svg-wrapper d-inline-flex justify-content-center align-items-center'";
     }
 
     /**
@@ -194,31 +197,32 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
      * @param string $use
      * @return string
      */
-    function processUseWrappers(string $svgContent, string $id, string $use): string {
-    	$svgContent = "<g $id>$svgContent</g>";
+    function processUseWrappers(string $svgContent, string $id, string $use): string
+    {
+        $svgContent = "<g $id>$svgContent</g>";
 
-    	if ($use) {
-    		$svgContent = "<use href='#$use' />";
-    	}
+        if ($use) {
+            $svgContent = "<use href='#$use' />";
+        }
 
-    	return $svgContent;
+        return $svgContent;
     }
 
     /**
-    * Set the fill color of an SVG element.
-    *
-    * @param \SimpleXMLElement $element The SVG element
-    * @param string $fill The fill color to set
-    */
-   protected function setFill(\SimpleXMLElement $element, string $fill): void
-   {
-       foreach ($element->children() as $child) {
-           $this->setFill($child, $fill);
-       }
-       if (isset($element->attributes()->fill)) {
-           $element->attributes()->fill = $fill;
-       }
-   }
+     * Set the fill color of an SVG element.
+     *
+     * @param \SimpleXMLElement $element The SVG element
+     * @param string $fill The fill color to set
+     */
+    protected function setFill(\SimpleXMLElement $element, string $fill): void
+    {
+        foreach ($element->children() as $child) {
+            $this->setFill($child, $fill);
+        }
+        if (isset($element->attributes()->fill)) {
+            $element->attributes()->fill = $fill;
+        }
+    }
 
     /**
      * Gets the contents of the SVG file
@@ -250,14 +254,14 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
      */
     private function xmlAdopt(\SimpleXMLElement $root, \SimpleXMLElement $newElement): void
     {
-        $node = $root->addChild($newElement->getName(), (string) $newElement);
+        $node = $root->addChild($newElement->getName(), (string)$newElement);
 
-        foreach($newElement->attributes() as $attr => $value) {
+        foreach ($newElement->attributes() as $attr => $value) {
             /** @noinspection NullPointerExceptionInspection */
             $node->addAttribute($attr, $value);
         }
 
-        foreach($newElement->children() as $ch) {
+        foreach ($newElement->children() as $ch) {
             /** @noinspection NullPointerExceptionInspection */
             $this->xmlAdopt($node, $ch);
         }
@@ -272,8 +276,8 @@ class RenderSvgViewHelper extends AbstractTagBasedViewHelper {
      * @return void
      */
     private function addOrReplaceAttribute(\SimpleXMLElement $element,
-        string $attributeName,
-        string $attributeValue): void
+                                           string            $attributeName,
+                                           string            $attributeValue): void
     {
         if (isset($element[$attributeName])) {
             $element[$attributeName] = $attributeValue; // Replace existing attribute value
diff --git a/Classes/ViewHelpers/StructuredVideoDataViewHelper.php b/Classes/ViewHelpers/StructuredVideoDataViewHelper.php
index 0f54b1601148bf075fb11c19b20e198f5b2edf13..05cb9112caf415725f9fac4e946b5397ff951bc9 100644
--- a/Classes/ViewHelpers/StructuredVideoDataViewHelper.php
+++ b/Classes/ViewHelpers/StructuredVideoDataViewHelper.php
@@ -33,63 +33,66 @@ use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
  *
  * @package SGalinski\SgVimeo\ViewHelpers
  */
-class StructuredVideoDataViewHelper extends AbstractTagBasedViewHelper {
-	/**
-	 * Name of the tag to be created by this view helper
-	 *
-	 * @var string
-	 * @api
-	 */
-	protected $tagName = 'script';
+class StructuredVideoDataViewHelper extends AbstractTagBasedViewHelper
+{
+    /**
+     * Name of the tag to be created by this view helper
+     *
+     * @var string
+     * @api
+     */
+    protected $tagName = 'script';
 
-	/**
-	 * Register the ViewHelper arguments
-	 */
-	public function initializeArguments(): void {
-		parent::initializeArguments();
-		$this->registerArgument('videoArray', 'array', 'An array of videos', TRUE);
-		$this->registerArgument('arrayType', 'string', 'Either "youtube" or "vimeo"', FALSE, "youtube");
-	}
+    /**
+     * Register the ViewHelper arguments
+     */
+    public function initializeArguments(): void
+    {
+        parent::initializeArguments();
+        $this->registerArgument('videoArray', 'array', 'An array of videos', TRUE);
+        $this->registerArgument('arrayType', 'string', 'Either "youtube" or "vimeo"', FALSE, "youtube");
+    }
 
-	/**
-	 * Takes the provided array of videos and creates an array for structured data JSON
-	 *
-	 * @return string
-	 */
-	public function render(): string {
-		$this->escapeOutput = FALSE;
-		$videoArray = $this->arguments['videoArray'];
-		$arrayType = $this->arguments['arrayType'];
+    /**
+     * Takes the provided array of videos and creates an array for structured data JSON
+     *
+     * @return string
+     */
+    public function render(): string
+    {
+        $this->escapeOutput = FALSE;
+        $videoArray = $this->arguments['videoArray'];
+        $arrayType = $this->arguments['arrayType'];
 
-		$structuredData = [];
-		if ($arrayType === "youtube") {
-			foreach ($videoArray as $video) {
-				$structuredData[] = [
-					'@type' => 'VideoObject',
-					'name' => $video['title'],
-					'description' => $video['description'],
-					'thumbnailUrl' => $video['thumbnail'],
-					'contentUrl' => $video['url'],
-					'uploadDate' => $video['publishedAt'],
-				];
-			}
-		} else {
-			foreach ($videoArray as $video) {
-				$structuredData[] = [
-					'@type' => 'VideoObject',
-					'name' => $video['name'],
-					'description' => $video['description'],
-					'thumbnailUrl' => $video['pictures']['sizes'][count($video['pictures']['sizes']) - 1]['link'],
-					'contentUrl' => $video['link'],
-					'uploadDate' => $video['release_time'],
-				];
-			}
-		}
+        $structuredData = [];
+        if ($arrayType === "youtube") {
+            foreach ($videoArray as $video) {
+                $structuredData[] = [
+                    '@type' => 'VideoObject',
+                    'name' => $video['title'],
+                    'description' => $video['description'],
+                    'thumbnailUrl' => $video['thumbnail'],
+                    'contentUrl' => $video['url'],
+                    'uploadDate' => $video['publishedAt'],
+                ];
+            }
+        } else {
+            foreach ($videoArray as $video) {
+                $structuredData[] = [
+                    '@type' => 'VideoObject',
+                    'name' => $video['name'],
+                    'description' => $video['description'],
+                    'thumbnailUrl' => $video['pictures']['sizes'][count($video['pictures']['sizes']) - 1]['link'],
+                    'contentUrl' => $video['link'],
+                    'uploadDate' => $video['release_time'],
+                ];
+            }
+        }
 
-		$this->tag->addAttribute('type', 'application/ld+json');
-		$this->tag->setContent(
-			'{"@context": "http://schema.org", "@type": "WebPage", "video": ' . json_encode($structuredData) . '}'
-		);
-		return $this->tag->render();
-	}
+        $this->tag->addAttribute('type', 'application/ld+json');
+        $this->tag->setContent(
+            '{"@context": "http://schema.org", "@type": "WebPage", "video": ' . json_encode($structuredData) . '}'
+        );
+        return $this->tag->render();
+    }
 }
diff --git a/Classes/ViewHelpers/UrlWithQueryParametersViewHelper.php b/Classes/ViewHelpers/UrlWithQueryParametersViewHelper.php
index c09daf68a31e893c758e39453ac963c1a7309bd4..d381d61ac4d4416615dd282dabab7b3c69e6a50e 100644
--- a/Classes/ViewHelpers/UrlWithQueryParametersViewHelper.php
+++ b/Classes/ViewHelpers/UrlWithQueryParametersViewHelper.php
@@ -1,7 +1,5 @@
 <?php
 
-namespace SGalinski\SgVimeo\ViewHelpers;
-
 /***************************************************************
  *  Copyright notice
  *
@@ -26,6 +24,8 @@ namespace SGalinski\SgVimeo\ViewHelpers;
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+namespace SGalinski\SgVimeo\ViewHelpers;
+
 use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
 
 /**
@@ -36,38 +36,41 @@ use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
  * <vi:urlWithQueryParameters url="https://player.vimeo.com/video/123?h=xyz" parameters="?origin=https://demo.sgalinski.de" />
  * Result: https://player.vimeo.com/video/123?h=xyz&origin=https://demo.sgalinski.de
  */
-class UrlWithQueryParametersViewHelper extends AbstractViewHelper {
-	/**
-	 * Register the ViewHelper arguments
-	 */
-	public function initializeArguments(): void {
-		parent::initializeArguments();
-		$this->registerArgument('url', 'string', 'The url to add the query parameters to', TRUE);
-		$this->registerArgument('parameters', 'string', 'The query parameters to add', FALSE, '');
-	}
+class UrlWithQueryParametersViewHelper extends AbstractViewHelper
+{
+    /**
+     * Register the ViewHelper arguments
+     */
+    public function initializeArguments(): void
+    {
+        parent::initializeArguments();
+        $this->registerArgument('url', 'string', 'The url to add the query parameters to', TRUE);
+        $this->registerArgument('parameters', 'string', 'The query parameters to add', FALSE, '');
+    }
 
-	/**
-	 * Returns the url with the added query parameters
-	 *
-	 * @return string
-	 */
-	public function render(): string {
-		$url = $this->arguments['url'];
-		$additionalUrlParameters = $this->arguments['parameters'];
+    /**
+     * Returns the url with the added query parameters
+     *
+     * @return string
+     */
+    public function render(): string
+    {
+        $url = $this->arguments['url'];
+        $additionalUrlParameters = $this->arguments['parameters'];
 
-		if ($additionalUrlParameters === '') {
-			return $url;
-		}
+        if ($additionalUrlParameters === '') {
+            return $url;
+        }
 
-		$beginsWithQuestionMark = $additionalUrlParameters[0] === '?';
-		$beginsWithAmpersand = $additionalUrlParameters[0] === '&';
+        $beginsWithQuestionMark = $additionalUrlParameters[0] === '?';
+        $beginsWithAmpersand = $additionalUrlParameters[0] === '&';
 
-		if ($beginsWithQuestionMark || $beginsWithAmpersand) {
-			$additionalUrlParameters = substr($additionalUrlParameters, 1);
-		}
+        if ($beginsWithQuestionMark || $beginsWithAmpersand) {
+            $additionalUrlParameters = substr($additionalUrlParameters, 1);
+        }
 
-		return strpos($url, '?') !== FALSE
-			? $url . '&' . $additionalUrlParameters
-			: $url . '?' . $additionalUrlParameters;
-	}
+        return strpos($url, '?') !== FALSE
+            ? $url . '&' . $additionalUrlParameters
+            : $url . '?' . $additionalUrlParameters;
+    }
 }