';
	/**
	 *
	 */
	public function init()
	{
		add_action('init', array($this, 'triggersAfterInit'));
		add_action('wp_footer', static function() {
			if ( Plugin::preventAnyFrontendOptimization() || Main::isTestModeActive() ) { return; }
			/* [wpacu_timing] */ Misc::scriptExecTimer( 'prepare_optimize_files_css' ); /* [/wpacu_timing] */
			self::prepareOptimizeList();
			/* [wpacu_timing] */ Misc::scriptExecTimer( 'prepare_optimize_files_css', 'end' ); /* [/wpacu_timing] */
			echo self::MOVE_NOSCRIPT_TO_BODY_FOR_CERTAIN_LINK_TAGS;
		}, PHP_INT_MAX);
		add_filter('wpacu_html_source_after_optimization', static function($htmlSource) {
			// Are any the marks still there & weren't replaced? Strip them to have a clean HTML output!
			return str_replace(self::MOVE_NOSCRIPT_TO_BODY_FOR_CERTAIN_LINK_TAGS, '', $htmlSource);
		});
		add_filter('wpacu_add_noscript_certain_link_tags', array($this, 'appendNoScriptCertainLinkTags'));
	}
	/**
	 *
	 */
	public function triggersAfterInit()
	{
		if (self::isInlineCssEnabled()) {
			$allPatterns = self::getAllInlineChosenPatterns();
			if (! empty($allPatterns)) {
				// Make "Inline CSS Files" compatible with "Optimize CSS Delivery" from WP Rocket
				add_filter('rocket_async_css_regex_pattern', static function($regex) {
					return '/(?=]*\s(rel\s*=\s*[\'"]stylesheet["\']))]*\shref\s*=\s*[\'"]([^\'"]+)[\'"](.*)>/iU';
				});
				add_filter('style_loader_tag', static function($styleTag) use ($allPatterns) {
					foreach ($allPatterns as $patternToCheck) {
						preg_match_all( '#]*stylesheet[^>]*('.$patternToCheck.').*(>)#Usmi', $styleTag, $matchesSourcesFromTags, PREG_SET_ORDER );
						if ( ! empty( $matchesSourcesFromTags ) ) {
							return str_replace( 'settings['inline_css_files_list']);
		$allPatterns = array();
		if (strpos($inlineCssFilesPatterns, "\n")) {
			// Multiple values (one per line)
			foreach (explode("\n", $inlineCssFilesPatterns) as $inlinePattern) {
				$allPatterns[] = trim($inlinePattern);
			}
		} else {
			// Only one value?
			$allPatterns[] = trim($inlineCssFilesPatterns);
		}
		// Strip any empty values
		return array_filter($allPatterns);
	}
	/**
	 *
	 */
	public static function prepareOptimizeList()
	{
		if ( ! self::isWorthCheckingForOptimization() || Plugin::preventAnyFrontendOptimization() ) {
			return;
		}
		global $wp_styles;
		$allStylesHandles = ObjectCache::wpacu_cache_get('wpacu_all_styles_handles');
		if (empty($allStylesHandles)) {
			return;
		}
		// [Start] Collect for caching
		$wpStylesDone       = isset($wp_styles->done)       && is_array($wp_styles->done)       ? $wp_styles->done       : array();
		$wpStylesRegistered = isset($wp_styles->registered) && is_array($wp_styles->registered) ? $wp_styles->registered : array();
		// Collect all enqueued clean (no query strings) HREFs to later compare them against any hardcoded CSS
		$allEnqueuedCleanLinkHrefs = array();
		if (! empty($wpStylesDone) && ! empty($wpStylesRegistered)) {
			foreach ( $wpStylesDone as $index => $styleHandle ) {
				if ( isset( Main::instance()->wpAllStyles['registered'][ $styleHandle ]->src ) && ( $src = Main::instance()->wpAllStyles['registered'][ $styleHandle ]->src ) ) {
					$localAssetPath = OptimizeCommon::getLocalAssetPath( $src, 'css' );
					if ( ! $localAssetPath || ! is_file( $localAssetPath ) ) {
						continue; // not a local file
					}
					ob_start();
					$wp_styles->do_item( $styleHandle );
					$linkSourceTag = trim( ob_get_clean() );
					// Check if the CSS has any 'data-wpacu-skip' attribute; if it does, do not alter it
					if ( preg_match( '#data-wpacu-skip([=>/ ])#i', $linkSourceTag ) ) {
						unset( $wpStylesDone[ $index ] );
						continue;
					}
					$cleanLinkHrefFromTagArray = OptimizeCommon::getLocalCleanSourceFromTag( $linkSourceTag );
					if ( isset( $cleanLinkHrefFromTagArray['source'] ) && $cleanLinkHrefFromTagArray['source'] ) {
						$allEnqueuedCleanLinkHrefs[] = $cleanLinkHrefFromTagArray['source'];
					}
				}
			}
		}
		$cssOptimizeList = array();
		if (! empty($wpStylesDone) && ! empty($wpStylesRegistered)) {
			$isMinifyCssFilesEnabled = MinifyCss::isMinifyCssEnabled() && in_array(Main::instance()->settings['minify_loaded_css_for'], array('href', 'all', ''));
			foreach ( $wpStylesDone as $handle ) {
				if ( ! isset( $wpStylesRegistered[ $handle ]->src ) ) {
					continue;
				}
				$value = $wpStylesRegistered[ $handle ];
				$localAssetPath = OptimizeCommon::getLocalAssetPath( $value->src, 'css' );
				if ( ! $localAssetPath || ! is_file( $localAssetPath ) ) {
					continue; // not a local file
				}
				$optimizeValues = self::maybeOptimizeIt(
					$value,
					array( 'local_asset_path' => $localAssetPath, 'is_minify_css_enabled' => $isMinifyCssFilesEnabled )
				);
				ObjectCache::wpacu_cache_set( 'wpacu_maybe_optimize_it_css_' . $handle, $optimizeValues );
				if ( ! empty( $optimizeValues ) ) {
					$cssOptimizeList[] = $optimizeValues;
				}
			}
		}
		if (empty($cssOptimizeList)) {
			return;
		}
		ObjectCache::wpacu_cache_add('wpacu_css_enqueued_hrefs', $allEnqueuedCleanLinkHrefs);
		ObjectCache::wpacu_cache_add('wpacu_css_optimize_list', $cssOptimizeList);
		// [End] Collect for caching
	}
	/**
	 * @param $value
	 * @param array $fileAlreadyChecked
	 *
	 * @return mixed
	 */
	public static function maybeOptimizeIt($value, $fileAlreadyChecked = array())
	{
		if ($optimizeValues = ObjectCache::wpacu_cache_get('wpacu_maybe_optimize_it_css_'.$value->handle)) {
			return $optimizeValues;
		}
		global $wp_version;
		$src = isset($value->src) ? $value->src : false;
		if (! $src) {
			return array();
		}
		$doFileMinify = true;
		$isMinifyCssFilesEnabled = (isset($fileAlreadyChecked['is_minify_css_enabled']) && $fileAlreadyChecked['is_minify_css_enabled'])
			? $fileAlreadyChecked['is_minify_css_enabled']
			: MinifyCss::isMinifyCssEnabled() && in_array(Main::instance()->settings['minify_loaded_css_for'], array('href', 'all', ''));
		if ( ! $isMinifyCssFilesEnabled || MinifyCss::skipMinify($src, $value->handle) ) {
			$doFileMinify = false;
		}
		// Default (it will be later replaced with the last time the file was modified, which is more accurate)
		$dbVer = (isset($value->ver) && $value->ver) ? $value->ver : $wp_version;
		$isCssFile = false;
		// Already checked? Do not reuse OptimizeCommon::getLocalAssetPath() and is_file()
		if (isset($fileAlreadyChecked['local_asset_path']) && $fileAlreadyChecked['local_asset_path']) {
			$localAssetPath = $fileAlreadyChecked['local_asset_path'];
			$checkCond = $localAssetPath;
		} else {
			$localAssetPath = OptimizeCommon::getLocalAssetPath( $src, 'css' );
			$checkCond = $localAssetPath && is_file($localAssetPath);
		}
		if ($checkCond) {
			if ($fileMTime = @filemtime($localAssetPath)) {
				$dbVer = $fileMTime;
			}
			$isCssFile = true;
		}
		if ($isCssFile) {
			// This is the safest one as handle names for specific static can change on very page load
			// as some developers have a habit of adding the UNIX time or other random string to a handle (e.g. for debugging)
			$uniqueAssetStr = md5 ( str_replace(Misc::getWpRootDirPath(), '', $localAssetPath) );
		} else {
			$uniqueAssetStr = md5( $value->handle );
		}
		$transientName = 'wpacu_css_optimize_'.$uniqueAssetStr;
		$skipCache = false;
		if (isset($_GET['wpacu_no_cache']) || (defined('WPACU_NO_CACHE') && WPACU_NO_CACHE === true)) {
			$skipCache = true;
		}
	    if (! $skipCache) {
			$savedValues = OptimizeCommon::getTransient($transientName);
			if ( $savedValues ) {
				$savedValuesArray = json_decode( $savedValues, ARRAY_A );
				if ( $savedValuesArray['ver'] !== $dbVer ) {
					// New File Version? Delete transient as it will be re-created with the new version
					OptimizeCommon::deleteTransient($transientName);
				} else {
					$localPathToCssOptimized = str_replace( '//', '/', Misc::getWpRootDirPath() . $savedValuesArray['optimize_uri'] );
					// Read the file from its caching (that makes the processing faster)
					if ( isset( $savedValuesArray['source_uri'] ) && is_file( $localPathToCssOptimized ) ) {
						if (Main::instance()->settings['fetch_cached_files_details_from'] === 'db_disk') {
							$GLOBALS['wpacu_from_location_inc']++;
						}
						return array(
							$savedValuesArray['source_uri'],
							$savedValuesArray['optimize_uri'],
							$value->src,
							$value->handle
						);
					}
					// If nothing valid gets returned above, make sure the transient gets deleted as it's re-added later on
					OptimizeCommon::deleteTransient($transientName);
				}
			}
	    }
		// Check if it starts without "/" or a protocol; e.g. "wp-content/theme/style.css"
		if (strpos($src, '/') !== 0 &&
		    strpos($src, '//') !== 0 &&
		    stripos($src, 'http://') !== 0 &&
		    stripos($src, 'https://') !== 0
		) {
			$src = '/'.$src; // append the forward slash to be processed as relative later on
		}
		// Starts with '/', but not with '//'
		if (strpos($src, '/') === 0 && strpos($src, '//') !== 0) {
			$src = site_url() . $src;
		}
		if (Main::instance()->settings['cache_dynamic_loaded_css'] &&
		    $value->handle === 'sccss_style' &&
		    in_array('simple-custom-css/simple-custom-css.php', Misc::getActivePlugins())
		) {
			$pathToAssetDir = '';
			$sourceBeforeOptimization = $value->src;
			if (! ($cssContent = DynamicLoadedAssets::getAssetContentFrom('simple-custom-css', $value))) {
				return array();
			}
		} elseif (Main::instance()->settings['cache_dynamic_loaded_css'] &&
		          ((strpos($src, '/?') !== false) || (strpos($src, rtrim(site_url(),'/').'?') !== false) || (strpos($src, '.php?') !== false) || Misc::endsWith($src, '.php')) &&
		          (strpos($src, rtrim(site_url(), '/')) !== false)
		) {
			$pathToAssetDir = '';
			$sourceBeforeOptimization = str_replace('&', '&', $value->src);
			if (! ($cssContent = DynamicLoadedAssets::getAssetContentFrom('dynamic', $value))) {
				return array();
			}
		} else {
			if (! $isCssFile) {
				return array();
			}
			/*
			 * This is a local .CSS file
			 */
			$pathToAssetDir = OptimizeCommon::getPathToAssetDir($src);
			$cssContent = FileSystem::fileGetContents($localAssetPath, 'combine_css_imports');
			$sourceBeforeOptimization = str_replace(Misc::getWpRootDirPath(), '/', $localAssetPath);
		}
		$cssContent = trim($cssContent);
		/*
		 * [START] CSS Content Optimization
		*/
		// If there are no changes from this point, do not optimize (keep the file where it is)
		$cssContentBefore = $cssContent;
		if ($cssContent) { // only proceed with extra alterations if there is some content there (save resources)
			if ( Main::instance()->settings['google_fonts_display'] ) {
				// Any "font-display" enabled in "Settings" - "Google Fonts"?
				$cssContent = FontsGoogle::alterGoogleFontUrlFromCssContent( $cssContent );
			}
			// Move any @imports to top; This also strips any @imports to Google Fonts if the option is chosen
			$cssContent = self::importsUpdate( $cssContent );
		}
		// If it stays like this, it means there is content there, even if only comments
		$cssContentBecomesEmptyAfterMin = false;
		if ($doFileMinify && $cssContent) { // only bother to minify it if it has any content, save resources
			// Minify this file?
			$cssContentBeforeMin = trim($cssContent);
			$cssContentAfterMin  = MinifyCss::applyMinification($cssContent);
			$cssContent = $cssContentAfterMin;
			if ($cssContentBeforeMin && $cssContentAfterMin === '') {
				// It had content, but became empty after minification, most likely it had only comments (e.g. a default child theme's style)
				$cssContentBecomesEmptyAfterMin = true;
			}
		}
		if ($cssContentBecomesEmptyAfterMin || $cssContent === '') {
			$cssContent = '/**/';
		} else {
			if ( Main::instance()->settings['google_fonts_remove'] ) {
				$cssContent = FontsGoogleRemove::cleanFontFaceReferences( $cssContent );
			}
			// No changes were made, thus, there's no point in changing the original file location
			if ( $isCssFile && ! $cssContentBecomesEmptyAfterMin && trim( $cssContentBefore ) === trim( $cssContent ) ) {
				// There's no point in changing the original CSS (static) file location
				return false;
			}
			// Continue, as changes are to be made
			// Does it have a source map? Strip it
			if (strpos($cssContent, '/*# sourceMappingURL=') !== false) {
				$cssContent = OptimizeCommon::stripSourceMap($cssContent, 'css');
			}
			$cssContent = self::maybeFixCssContent( $cssContent, $pathToAssetDir . '/' ); // Path
		}
		/*
         * [END] CSS Content Optimization
		*/
		// Relative path to the new file
		// Save it to /wp-content/cache/css/{OptimizeCommon::$optimizedSingleFilesDir}/
		/*
		if ($fileVer !== $wp_version) {
			if (is_array($fileVer)) {
				// Convert to string if it's an array (rare cases)
				$fileVer = implode('-', $fileVer);
			}
			$fileVer = trim(str_replace(' ', '_', preg_replace('/\s+/', ' ', $fileVer)));
			$fileVer = (strlen($fileVer) > 50) ? substr(md5($fileVer), 0, 20) : $fileVer; // don't end up with too long filenames
		}
		*/
		$fileVer = sha1($cssContent);
		$uniqueCachedAssetName = OptimizeCommon::generateUniqueNameForCachedAsset($isCssFile, $localAssetPath, $value->handle, $fileVer);
		$newFilePathUri  = self::getRelPathCssCacheDir() . OptimizeCommon::$optimizedSingleFilesDir . '/' . $uniqueCachedAssetName;
		$newFilePathUri .= '.css';
		if ($cssContent === '') {
			$cssContent = '/**/';
		}
		if ($cssContent === '/**/') {
			// Leave a signature that the file is empty, thus it would be faster to take further actions upon it later on, saving resources)
			$newFilePathUri = str_replace('.css', '-wpacu-empty-file.css', $newFilePathUri);
		}
		$newLocalPath    = WP_CONTENT_DIR . $newFilePathUri; // Ful Local path
		$newLocalPathUrl = WP_CONTENT_URL . $newFilePathUri; // Full URL path
		if ($cssContent && $cssContent !== '/**/' && apply_filters('wpacu_print_info_comments_in_cached_assets', true)) {
			$cssContent = '/*!' . $sourceBeforeOptimization . '*/' . $cssContent;
		}
		$saveFile = FileSystem::filePutContents($newLocalPath, $cssContent);
		if (! $saveFile && ! $cssContent) {
			// Fallback to the original CSS if the optimized version can't be created or updated
			return array();
		}
		$saveValues = array(
			'source_uri'   => OptimizeCommon::getSourceRelPath($src),
			'optimize_uri' => OptimizeCommon::getSourceRelPath($newLocalPathUrl),
			'ver'          => $dbVer
		);
		// Re-add transient
		OptimizeCommon::setTransient($transientName, wp_json_encode($saveValues));
		return array(
			OptimizeCommon::getSourceRelPath($src), // Original SRC (Relative path)
			OptimizeCommon::getSourceRelPath($newLocalPathUrl), // New SRC (Relative path)
			$value->src, // SRC (as it is)
			$value->handle
		);
	}
	/**
	 * @param $htmlSource
	 *
	 * @return mixed|void
	 */
	public static function alterHtmlSource($htmlSource)
	{
		// There has to be at least one "preventAssetsSettings()) {
			/* [wpacu_timing] */ $wpacuTimingName = 'alter_html_source_unload_ignore_deps_css'; Misc::scriptExecTimer($wpacuTimingName); /* [/wpacu_timing] */
			$htmlSource = self::ignoreDependencyRuleAndKeepChildrenLoaded($htmlSource);
			/* [wpacu_timing] */ Misc::scriptExecTimer($wpacuTimingName, 'end'); /* [/wpacu_timing] */
		}
		$htmlSource = self::stripAnyReferencesForUnloadedStyles($htmlSource);
		if (self::isWorthCheckingForOptimization()) {
			/* [wpacu_timing] */ $wpacuTimingName = 'alter_html_source_original_to_optimized_css'; Misc::scriptExecTimer($wpacuTimingName); /* [/wpacu_timing] */
			// 'wpacu_css_optimize_list' caching list is also checked; if it's empty, no optimization is made
			$htmlSource = self::updateHtmlSourceOriginalToOptimizedCss($htmlSource);
			/* [wpacu_timing] */ Misc::scriptExecTimer($wpacuTimingName, 'end'); /* [/wpacu_timing] */
		}
		if (! Main::instance()->preventAssetsSettings()) {
			/* [wpacu_timing] */ $wpacuTimingName = 'alter_html_source_for_preload_css'; Misc::scriptExecTimer($wpacuTimingName); /* [/wpacu_timing] */
			$htmlSource = Preloads::instance()->doChanges($htmlSource);
			/* [wpacu_timing] */ Misc::scriptExecTimer($wpacuTimingName, 'end'); /* [/wpacu_timing] */
		}
		if (self::isInlineCssEnabled()) {
			/* [wpacu_timing] */ $wpacuTimingName = 'alter_html_source_for_inline_css'; Misc::scriptExecTimer($wpacuTimingName); /* [/wpacu_timing] */
			$htmlSource = self::doInline($htmlSource);
			/* [wpacu_timing] */ Misc::scriptExecTimer($wpacuTimingName, 'end'); /* [/wpacu_timing] */
		}
		$proceedWithCombineOnThisPage = true;
		$isSingularPage = defined('WPACU_CURRENT_PAGE_ID') && WPACU_CURRENT_PAGE_ID > 0 && is_singular();
		// If "Do not combine CSS on this page" is checked in "Asset CleanUp: Options" side meta box
		// Works for posts, pages and custom post types
		if ($isSingularPage || Misc::isHomePage()) {
			if ($isSingularPage) {
				$pageOptions = MetaBoxes::getPageOptions( WPACU_CURRENT_PAGE_ID ); // Singular page
			} else {
				$pageOptions = MetaBoxes::getPageOptions(0, 'front_page'); // Home page
			}
			// 'no_css_optimize' refers to avoid the combination of CSS files
			if ( (isset( $pageOptions['no_css_optimize'] )    && $pageOptions['no_css_optimize'])
			  || (isset( $pageOptions['no_assets_settings'] ) && $pageOptions['no_assets_settings']) ) {
				$proceedWithCombineOnThisPage = false;
			}
		}
		if ($proceedWithCombineOnThisPage) {
			/* [wpacu_timing] */ $wpacuTimingName = 'alter_html_source_for_combine_css'; Misc::scriptExecTimer($wpacuTimingName); /* [/wpacu_timing] */
			$htmlSource = CombineCss::doCombine($htmlSource);
			/* [wpacu_timing] */ Misc::scriptExecTimer($wpacuTimingName, 'end'); /* [/wpacu_timing] */
		}
		if (self::isWorthCheckingForOptimization() && ! Main::instance()->preventAssetsSettings() && (MinifyCss::isMinifyCssEnabled() && in_array(Main::instance()->settings['minify_loaded_css_for'], array('inline', 'all')))) {
			/* [wpacu_timing] */ $wpacuTimingName = 'alter_html_source_for_minify_inline_style_tags'; Misc::scriptExecTimer($wpacuTimingName); /* [/wpacu_timing] */
			$htmlSource = MinifyCss::minifyInlineStyleTags($htmlSource);
			/* [wpacu_timing] */ Misc::scriptExecTimer($wpacuTimingName, 'end'); /* [/wpacu_timing] */
		}
		// Final cleanups
		$htmlSource = preg_replace('#]*stylesheet[^>]*(>)#Umi', $htmlSource, $matches);
		foreach ($matches[0] as $matchTag) {
			if (strpos($matchTag, $firstLinkHref) !== false) {
				return trim($matchTag);
			}
		}
		return '';
	}
	/**
	 *
	 * @param $cssContent
	 * @param $appendBefore
	 * @param $fix
	 *
	 * @return mixed
	 */
	public static function maybeFixCssContent($cssContent, $appendBefore, $fix = 'path')
	{
		// Updates (background | font etc.) URLs to the right path and others
		if ($fix === 'path') {
			// Clear any extra spaces between @import and the single/double quotes
			$cssContent = preg_replace('/@import(\s+|)([\'"])/i', '@import \\2', $cssContent);
			$cssContentPathReps = array(
				// @import with url(), background-image etc.
				'url("../' => 'url("'.$appendBefore.'../',
				"url('../" => "url('".$appendBefore.'../',
				'url(../'  => 'url('.$appendBefore.'../',
				'url("./'  => 'url("'.$appendBefore.'./',
				"url('./"  => "url('".$appendBefore.'./',
				'url(./'   => 'url('.$appendBefore.'./',
				// @import without URL
				'@import "../' => '@import "'.$appendBefore.'../',
				"@import '../" => "@import '".$appendBefore.'../',
				'@import "./'  => '@import "'.$appendBefore.'./',
				"@import './"  => "@import '".$appendBefore.'./'
			);
			$cssContent = str_replace(array_keys($cssContentPathReps), array_values($cssContentPathReps), $cssContent);
			// Rare cases
			$cssContent = preg_replace('/url\((\s+)http/i', 'url(http', $cssContent);
			// Avoid Background URLs starting with "#", "data", "http" or "https" as they do not need to have a path updated
			preg_match_all('/url\((?![\'"]?(?:#|data|http|https):)[\'"]?([^\'")]*)[\'"]?\)/i', $cssContent, $matches);
			// If it starts with forward slash (/), it doesn't need fix, just skip it
			// Also skip ../ types as they were already processed
			$toSkipList = array("url('/", 'url("/', 'url(/');
			foreach ($matches[0] as $match) {
				$fullUrlMatch = trim($match);
				foreach ($toSkipList as $toSkip) {
					if (substr($fullUrlMatch, 0, strlen($toSkip)) === $toSkip) {
						continue 2; // doesn't need any fix, go to the next match
					}
				}
				// Go through all situations: with and without quotes, with traversal directory (e.g. ../../)
				$alteredMatch = str_replace(
					array('url("', "url('"),
					array('url("' . $appendBefore, "url('" . $appendBefore),
					$fullUrlMatch
				);
				$alteredMatch = trim($alteredMatch);
				if (! in_array($fullUrlMatch[4], array("'", '"', '/', '.', '#'))) {
					$alteredMatch = str_replace('url(', 'url(' . $appendBefore, $alteredMatch);
					$alteredMatch = str_replace(array('")', '\')'), ')', $alteredMatch);
				}
				// Finally, apply the changes
				$cssContent = str_replace($fullUrlMatch, $alteredMatch, $cssContent);
				// Bug fix
				$cssContent = str_replace(
					array($appendBefore . '"' . $appendBefore, $appendBefore . "'" . $appendBefore),
					$appendBefore,
					$cssContent
				);
				// Bug Fix 2
				$cssContent = str_replace($appendBefore . 'http', 'http', $cssContent);
				$cssContent = str_replace($appendBefore . '//', '//', $cssContent);
			}
		}
		return $cssContent;
	}
	/**
	 * Next: Alter the HTML source by updating the original link URLs with the just cached ones
	 *
	 * @param $htmlSource
	 *
	 * @return mixed
	 */
	public static function updateHtmlSourceOriginalToOptimizedCss($htmlSource)
	{
		$parseSiteUrlPath = (string)parse_url(site_url(), PHP_URL_PATH);
		$siteUrlNoProtocol = str_replace(array('http://', 'https://'), '//', site_url());
		$cssOptimizeList = ObjectCache::wpacu_cache_get('wpacu_css_optimize_list') ?: array();
		$allEnqueuedCleanSources = ObjectCache::wpacu_cache_get('wpacu_css_enqueued_hrefs') ?: array();
		$allEnqueuedCleanSourcesIncludingTheirRelPaths = array();
		foreach ($allEnqueuedCleanSources as $allEnqueuedCleanSource) {
			$allEnqueuedCleanSourcesIncludingTheirRelPaths[] = $allEnqueuedCleanSource;
			if (strpos($allEnqueuedCleanSource, 'http://') === 0 || strpos($allEnqueuedCleanSource, 'https://') === 0) {
				$allEnqueuedCleanSourcesIncludingTheirRelPaths[] = str_replace(array('http://', 'https://'), '//', $allEnqueuedCleanSource);
				// e.g. www.mysite.com/blog/
				if ($parseSiteUrlPath !== '/' && strlen($parseSiteUrlPath) > 1) {
					$allEnqueuedCleanSourcesIncludingTheirRelPaths[] = $parseSiteUrlPath . str_replace(site_url(), '', $allEnqueuedCleanSource);
				}
				// e.g. www.mysite.com/
				if ($parseSiteUrlPath === '/' || ! $parseSiteUrlPath) {
					$allEnqueuedCleanSourcesIncludingTheirRelPaths[] = str_replace(site_url(), '', $allEnqueuedCleanSource);
				}
			}
		}
		$cdnUrls = OptimizeCommon::getAnyCdnUrls();
		$cdnUrlForCss = isset($cdnUrls['css']) ? $cdnUrls['css'] : false;
		// Grabs both LINK "stylesheet" and those with as="style" which is for preloaded LINK tags
		preg_match_all('#]*(stylesheet|(as(\s+|)=(\s+|)(|"|\')style(|"|\')))[^>]*>#Umi', OptimizeCommon::cleanerHtmlSource( $htmlSource, array( 'for_fetching_link_tags' ) ), $matchesSourcesFromTags, PREG_SET_ORDER);
		if (empty($matchesSourcesFromTags)) {
			return $htmlSource;
		}
		$cssOptimizeListHardcoded = $linkTagsToUpdate = array();
		foreach ($matchesSourcesFromTags as $matches) {
			$linkSourceTag = $matches[0];
			if ($linkSourceTag === '' || strip_tags($linkSourceTag) !== '') {
				// Hmm? Not a valid tag... Skip it...
				continue;
			}
			// Check if the CSS has any 'data-wpacu-skip' attribute; if it does, do not alter it
			if (preg_match('#data-wpacu-skip([=>/ ])#i', $linkSourceTag)) {
				continue;
			}
			$cleanLinkHrefFromTagArray = OptimizeCommon::getLocalCleanSourceFromTag($linkSourceTag);
			// Skip external links, no point in carrying on
			if (! $cleanLinkHrefFromTagArray || ! is_array($cleanLinkHrefFromTagArray)) {
				continue;
			}
			// Is it a local CSS? Check if it's hardcoded (not enqueued the WordPress way)
			$cleanLinkHrefFromTag = $cleanLinkHrefFromTagArray['source'];
			$afterQuestionMark = $cleanLinkHrefFromTagArray['after_question_mark'];
			$isHardcodedDetected = false;
			if (! in_array($cleanLinkHrefFromTag, $allEnqueuedCleanSourcesIncludingTheirRelPaths)) {
				// Not in the final enqueued list? Most likely hardcoded (not added via wp_enqueue_scripts())
				// Emulate the object value (as the enqueued styles)
				$generatedHandle = md5($cleanLinkHrefFromTag);
				$value = (object)array(
					'handle' => $generatedHandle,
					'src'    => $cleanLinkHrefFromTag,
					'ver'    => md5($afterQuestionMark)
				);
				$optimizeValues = self::maybeOptimizeIt($value);
				ObjectCache::wpacu_cache_set('wpacu_maybe_optimize_it_css_'.$generatedHandle, $optimizeValues);
				if (! empty($optimizeValues)) {
					$isHardcodedDetected = true;
					$cssOptimizeListHardcoded[] = $optimizeValues;
				}
			}
			if ( ! $isHardcodedDetected ) {
				$listToParse = $cssOptimizeList;
			} else {
				$listToParse = $cssOptimizeListHardcoded;
			}
			if (empty($listToParse)) {
				continue;
			}
			foreach ($listToParse as $listValues) {
				// Index 0: Source URL (relative)
				// Index 1: New Optimized URL (relative)
				// Index 2: Source URL (as it is)
				// if the relative path from the WP root does not match the value of the source from the tag, do not continue
				// e.g. '/wp-content/plugins/my-plugin/script.js' has to be inside ''
				if (strpos($cleanLinkHrefFromTag, $listValues[0]) === false) {
					continue;
				}
				// The contents of the CSS file has been changed and thus, we will replace the source path from the original tag with the cached (e.g. minified) one
				// If the minified files are deleted (e.g. /wp-content/cache/ is cleared)
				// do not replace the CSS file path to avoid breaking the website
				$localPathOptimizedFile = rtrim(Misc::getWpRootDirPath(), '/') . $listValues[1];
				if (! is_file($localPathOptimizedFile)) {
					continue;
				}
				// Make sure the source URL gets updated even if it starts with // (some plugins/theme strip the protocol when enqueuing assets)
				// If the first value fails to be replaced, the next one will be attempted for replacement
				// the order of the elements in the array is very important
				$sourceUrlList = array(
					site_url() . $listValues[0], // with protocol
					$siteUrlNoProtocol . $listValues[0], // without protocol
				);
				if ($parseSiteUrlPath && (strpos($listValues[0], $parseSiteUrlPath) === 0 || strpos($cleanLinkHrefFromTag, $parseSiteUrlPath) === 0)) {
					$sourceUrlList[] = $cleanLinkHrefFromTag;
				}
				if ($parseSiteUrlPath && (strpos($cleanLinkHrefFromTag, $parseSiteUrlPath) === 0 && strpos($cleanLinkHrefFromTag, $listValues[0]) !== false)) {
					$sourceUrlList[] = str_replace('//', '/', $parseSiteUrlPath.'/'.$listValues[0]);
				}
				elseif ( $cleanLinkHrefFromTag === $listValues[0] ) {
					$sourceUrlList[] = $listValues[0];
				}
				if ($cdnUrlForCss) {
					// Does it have a CDN?
					$sourceUrlList[] = OptimizeCommon::cdnToUrlFormat($cdnUrlForCss, 'rel') . $listValues[0];
				}
				// Any rel tag? You never know
				// e.g. 
				if ( (strpos($listValues[2], '/') === 0 && strpos($listValues[2], '//') !== 0)
					|| (strpos($listValues[2], '/') !== 0 &&
					    strpos($listValues[2], '//') !== 0 &&
					    stripos($listValues[2], 'http://') !== 0 &&
					    stripos($listValues[2], 'https://') !== 0) ) {
					$sourceUrlList[] = $listValues[2];
					}
				if ( $cleanLinkHrefFromTag === $listValues[0] ) {
					$sourceUrlList[] = $cleanLinkHrefFromTag;
				}
				// If no CDN is set, it will return site_url() as a prefix
				$optimizeUrl = OptimizeCommon::cdnToUrlFormat($cdnUrlForCss, 'raw') . $listValues[1]; // string
				if ($linkSourceTag !== str_replace($sourceUrlList, $optimizeUrl, $linkSourceTag)) {
					// Extra measure: Check the file size which should be 4 bytes, but add some margin error in case some environments will report less
					$isEmptyOptimizedFile = (strpos($localPathOptimizedFile, '-wpacu-empty-file.css') !== false && filesize($localPathOptimizedFile) < 10);
					// Strip it as its content (after optimization, for instance) is empty; no point in having extra HTTP requests
					if ($isEmptyOptimizedFile) {
						// Note: As for September 3, 2020, the inline CSS associated with the handle is no longer removed if the main CSS file is empty
						// There could be cases when the main CSS file is empty (e.g. theme's styling), but the inline STYLE tag associated with it has syntax that is needed
						$htmlSource       = str_replace($linkSourceTag, '', $htmlSource);
						} else {
						// Do the replacement
						$newLinkSourceTag = self::updateOriginalToOptimizedTag( $linkSourceTag, $sourceUrlList, $optimizeUrl );
						$linkTagsToUpdate[$linkSourceTag] = $newLinkSourceTag;
						}
					break; // there was a match, stop here
				}
			}
		}
		return strtr($htmlSource, $linkTagsToUpdate);
	}
	/**
	 * @param $linkSourceTag string
	 * @param $sourceUrlList array
	 * @param $optimizeUrl string
	 *
	 * @return array|string|string[]|null
	 */
	public static function updateOriginalToOptimizedTag($linkSourceTag, $sourceUrlList, $optimizeUrl)
	{
		if (is_array($sourceUrlList) && ! empty($sourceUrlList)) {
			foreach ($sourceUrlList as $sourceUrl) {
				$newLinkSourceTag = str_replace($sourceUrl, $optimizeUrl, $linkSourceTag);
				if ($newLinkSourceTag !== $linkSourceTag) {
					break;
				}
			}
		} else {
			$newLinkSourceTag = str_replace( $sourceUrlList, $optimizeUrl, $linkSourceTag );
		}
		// Needed in case it's added to the Combine CSS exceptions list
		if (CombineCss::proceedWithCssCombine()) {
			$sourceUrlRel = is_array($sourceUrlList) ? OptimizeCommon::getSourceRelPath($sourceUrlList[0]) : OptimizeCommon::getSourceRelPath($sourceUrlList);
			$newLinkSourceTag = str_ireplace('settings['inline_css_files'] &&
            (trim(Main::instance()->settings['inline_css_files_list']) !== '' || self::isAutoInlineEnabled()));
		if (! $isEnabledInSettingsWithListOrAuto) {
			return false;
		}
		// Deactivate it for debugging purposes via query string /?wpacu_no_inline_js
		if ( isset($_GET['wpacu_no_inline_css']) ) {
			return false;
		}
		// Finally, return true
		return true;
	}
	/**
	 * From LINK to STYLE tag: it processes the contents of the LINK stylesheet and replaces the tag with a STYLE tag having the content inlined
	 *
	 * @param $htmlSource
	 *
	 * @return mixed
	 */
	public static function doInline($htmlSource)
	{
		$allPatterns = self::getAllInlineChosenPatterns();
		// Skip any LINK tags within conditional comments (e.g. Internet Explorer ones)
		preg_match_all(
			'#]*stylesheet[^>]*>#Umsi',
			OptimizeCommon::cleanerHtmlSource( $htmlSource, array( 'strip_content_between_conditional_comments', 'for_fetching_link_tags' ) ),
			$matchesSourcesFromTags,
			PREG_SET_ORDER
		);
		// In case automatic inlining is used
		$belowSizeInput = (int)Main::instance()->settings['inline_css_files_below_size_input'];
		if ($belowSizeInput === 0) {
			$belowSizeInput = 1; // needs to have a minimum value
		}
		if (! empty($matchesSourcesFromTags)) {
			$cdnUrls = OptimizeCommon::getAnyCdnUrls();
			$cdnUrlForCss = isset($cdnUrls['css']) ? trim($cdnUrls['css']) : false;
			foreach ($matchesSourcesFromTags as $matchList) {
				$matchedTag = $matchList[0];
				if ( stripos( $matchedTag, '= $belowSizeInput) {
						continue;
					}
				}
				// Is there a media attribute? Make sure to add it to the STYLE tag
				$mediaAttrValue = Misc::getValueFromTag($matchedTag, 'media');
				$mediaAttr = ($mediaAttrValue && $mediaAttrValue !== 'all') ? 'media=\''.$mediaAttrValue.'\'' : '';
				$appendBeforeAnyRelPath = $cdnUrlForCss ? OptimizeCommon::cdnToUrlFormat($cdnUrlForCss, 'raw') : '';
				$cssContent = self::maybeFixCssContent(
					FileSystem::fileGetContents($localAssetPath, 'combine_css_imports'), // CSS content
					$appendBeforeAnyRelPath . OptimizeCommon::getPathToAssetDir($linkHrefOriginal) . '/'
				);
				// The CSS file is read from its original plugin/theme/cache location
				// If minify was enabled, then it's already minified, no point in re-minify it to save resources
				// Changing paths (relative) to fonts, images, etc. are relevant in this case
				$cssContent = self::maybeAlterContentForCssFile($cssContent, false);
				if ($cssContent && $cssContent !== '/**/') {
					$htmlSource = str_replace(
						$matchedTag,
						'',
						$htmlSource
					);
				} else {
					// After CSS alteration (e.g. minify), there's no content left, most likely the CSS file contained only comments, elements without any syntax or empty spaces
					// Strip the tag completely as there's no reason to print an empty SCRIPT tag to further add to the total DOM elements
					$htmlSource = str_replace($matchedTag, '', $htmlSource);
				}
			}
		}
		return $htmlSource;
	}
	/**
	 * This applies to both inline and static JS files contents
	 *
	 * @param $cssContent
	 * @param bool $doCssMinify (false by default as it could be already minified or non-minify type)
	 * @param array $extraParams
	 *
	 * @return mixed|string|string[]|null
	 */
	public static function maybeAlterContentForCssFile($cssContent, $doCssMinify = false, $extraParams = array())
	{
		if (! trim($cssContent)) {
			return $cssContent;
		}
		/* [START] Change CSS Content */
		// Move any @imports to top; This also strips any @imports to Google Fonts if the option is chosen
		$cssContent = self::importsUpdate( $cssContent );
		if ( $doCssMinify ) {
			$cssContent = MinifyCss::applyMinification( $cssContent, $doCssMinify );
		}
		if ( Main::instance()->settings['google_fonts_remove'] ) {
			$cssContent = FontsGoogleRemove::cleanFontFaceReferences( $cssContent );
		}
		// Does it have a source map? Strip it
		if (strpos($cssContent, '/*# sourceMappingURL=') !== false) {
			$cssContent = OptimizeCommon::stripSourceMap($cssContent, 'css');
		}
		/* [END] Change CSS Content */
		return $cssContent;
	}
	/**
	 * @param $cssContent
	 * @param bool $doCssMinify
	 * @param array $extraParams
	 *
	 * @return mixed|string
	 */
	public static function maybeAlterContentForInlineStyleTag($cssContent, $doCssMinify = false, $extraParams = array())
	{
		if (! trim($cssContent)) {
			return $cssContent;
		}
		$useCacheForInlineStyle = true;
		if (mb_strlen($cssContent) > 500000) { // Bigger then ~500KB? Skip alteration
			return $cssContent;
		}
		if (mb_strlen($cssContent) < 40000) { // Smaller than ~40KB? Do not cache it
			$useCacheForInlineStyle = false;
		}
		// For debugging purposes
		if (isset($_GET['wpacu_no_cache']) || (defined('WPACU_NO_CACHE') && WPACU_NO_CACHE === true)) { $useCacheForInlineStyle = false; }
		if ($useCacheForInlineStyle) {
			// Anything in the cache? Take it from there and don't spend resources with the minification
			// (which in some environments uses the CPU, depending on the complexity of the JavaScript code) and any other alteration
			$cssContentBeforeHash = sha1( $cssContent );
			$pathToInlineCssOptimizedItem = WP_CONTENT_DIR . self::getRelPathCssCacheDir() . '/item/inline/' . $cssContentBeforeHash . '.css';
			// Check if the file exists before moving forward
			if ( is_file( $pathToInlineCssOptimizedItem ) ) {
				$cachedCssFileExpiresIn = OptimizeCommon::$cachedAssetFileExpiresIn;
				if ( filemtime( $pathToInlineCssOptimizedItem ) < ( time() - 1 * $cachedCssFileExpiresIn ) ) {
					// Has the caching period expired? Remove the file as a new one has to be generated
					@unlink( $pathToInlineCssOptimizedItem );
				} else {
					// Not expired / Return its content from the cache in a faster way
					$inlineCssStorageItemJsonContent = trim( FileSystem::fileGetContents( $pathToInlineCssOptimizedItem ) );
					if ( $inlineCssStorageItemJsonContent !== '' ) {
						return $inlineCssStorageItemJsonContent;
					}
				}
			}
		}
		/* [START] Change CSS Content */
		if ( $doCssMinify && in_array('just_minify', $extraParams) ) {
			$cssContent = MinifyCss::applyMinification( $cssContent, $useCacheForInlineStyle );
		} else {
			// Move any @imports to top; This also strips any @imports to Google Fonts if the option is chosen
			$cssContent = self::importsUpdate( $cssContent );
			if ( $doCssMinify ) {
				$cssContent = MinifyCss::applyMinification( $cssContent, $useCacheForInlineStyle );
			}
			if ( Main::instance()->settings['google_fonts_remove'] ) {
				$cssContent = FontsGoogleRemove::cleanFontFaceReferences( $cssContent );
			}
		}
		/* [END] Change CSS Content */
		if ($useCacheForInlineStyle && isset($pathToInlineCssOptimizedItem)) {
			// Store the optimized content to the cached CSS file which would be read quicker
			FileSystem::filePutContents( $pathToInlineCssOptimizedItem, $cssContent );
		}
		return $cssContent;
	}
	/**
	 * @return bool
	 */
	public static function isAutoInlineEnabled()
	{
		return Main::instance()->settings['inline_css_files'] &&
		       Main::instance()->settings['inline_css_files_below_size'] &&
		       (int)Main::instance()->settings['inline_css_files_below_size_input'] > 0;
	}
	/**
	 * Source: https://www.minifier.org/ | https://github.com/matthiasmullie/minify
	 *
	 * @param $content
	 *
	 * @return string
	 */
	public static function importsUpdate($content)
	{
		if (preg_match_all('/(;?)(@import (?url\()?(?P["\']?).+?(?P=quotes)(?(url)\)));?/', $content, $matches)) {
			// Remove from content (they will be appended to the top if they qualify)
			foreach ($matches[0] as $import) {
				$content = str_replace($import, '', $content);
			}
			// Strip any @imports to Google Fonts if it's the case
			$importsAddToTop = Main::instance()->settings['google_fonts_remove'] ? FontsGoogleRemove::stripGoogleApisImport($matches[2]) : $matches[2];
			// Add to top if there are any imports left
			if (! empty($importsAddToTop)) {
				$content = implode(';', $importsAddToTop) . ';' . trim($content, ';');
			}
		}
		return $content;
	}
	/**
	 * e.g. if a style is unloaded, strip any LINK tag that preloads that style (e.g. added by other plugins)
	 *
	 * @param $htmlSource
	 *
	 * @return array|mixed|string|string[]
	 */
	public static function stripAnyReferencesForUnloadedStyles($htmlSource)
	{
		// Gather all HREFs of the unloaded styles (if any)
		$unloadedStyleRelHrefs = array();
		if ( isset( Main::instance()->allUnloadedAssets['styles'] ) && ! empty( Main::instance()->allUnloadedAssets['styles'] ) ) {
			foreach ( array_unique( Main::instance()->allUnloadedAssets['styles'] ) as $styleHandle ) {
				if ( ! (isset(Main::instance()->wpAllStyles['registered'][ $styleHandle ]->src) && Main::instance()->wpAllStyles['registered'][ $styleHandle ]->src) ) {
					continue; // does not have a "src" (e.g. inline CSS)
				}
				$unloadedStyleRelHrefs[] = OptimizeCommon::getSourceRelPath( Main::instance()->wpAllStyles['registered'][ $styleHandle ]->src );
			}
		}
		if ( ! empty($unloadedStyleRelHrefs) ) {
			$htmlSource = OptimizeCommon::matchAndReplaceLinkTags($htmlSource, array('as' => 'style', 'unloaded_assets_rel_sources' => $unloadedStyleRelHrefs));
		}
		return $htmlSource;
	}
	/**
	 * @param string $returnType
	 *
	 * @return array|bool
	 */
	public static function isOptimizeCssEnabledByOtherParty($returnType = 'list')
	{
		$pluginsToCheck = array(
			'autoptimize/autoptimize.php'            => 'Autoptimize',
			'wp-rocket/wp-rocket.php'                => 'WP Rocket',
			'wp-fastest-cache/wpFastestCache.php'    => 'WP Fastest Cache',
			'w3-total-cache/w3-total-cache.php'      => 'W3 Total Cache',
			'sg-cachepress/sg-cachepress.php'        => 'SG Optimizer',
			'fast-velocity-minify/fvm.php'           => 'Fast Velocity Minify',
			'litespeed-cache/litespeed-cache.php'    => 'LiteSpeed Cache',
			'swift-performance-lite/performance.php' => 'Swift Performance Lite',
			'breeze/breeze.php'                      => 'Breeze – WordPress Cache Plugin'
		);
		$cssOptimizeEnabledIn = array();
		foreach ($pluginsToCheck as $plugin => $pluginTitle) {
			// "Autoptimize" check
			if ($plugin === 'autoptimize/autoptimize.php' && Misc::isPluginActive($plugin) && get_option('autoptimize_css')) {
				$cssOptimizeEnabledIn[] = $pluginTitle;
				if ($returnType === 'if_enabled') { return true; }
			}
			// "WP Rocket" check
			if ($plugin === 'wp-rocket/wp-rocket.php' && Misc::isPluginActive($plugin)) {
				if (function_exists('get_rocket_option')) {
					$wpRocketMinifyCss = trim(get_rocket_option('minify_css')) ?: false;
					$wpRocketMinifyConcatenateCss = trim(get_rocket_option('minify_concatenate_css')) ?: false;
				} else {
					$wpRocketSettings  = get_option('wp_rocket_settings');
					$wpRocketMinifyCss = isset($wpRocketSettings['minify_css']) && trim($wpRocketSettings['minify_css']);
					$wpRocketMinifyConcatenateCss = isset($wpRocketSettings['minify_concatenate_css']) && trim($wpRocketSettings['minify_concatenate_css']);
				}
				if ($wpRocketMinifyCss || $wpRocketMinifyConcatenateCss) {
					$cssOptimizeEnabledIn[] = $pluginTitle;
					if ($returnType === 'if_enabled') { return true; }
				}
			}
			// "WP Fastest Cache" check
			if ($plugin === 'wp-fastest-cache/wpFastestCache.php' && Misc::isPluginActive($plugin)) {
				$wpfcOptionsJson = get_option('WpFastestCache');
				$wpfcOptions = @json_decode($wpfcOptionsJson, ARRAY_A);
				if (isset($wpfcOptions['wpFastestCacheMinifyCss']) || isset($wpfcOptions['wpFastestCacheCombineCss'])) {
					$cssOptimizeEnabledIn[] = $pluginTitle;
					if ($returnType === 'if_enabled') { return true; }
				}
			}
			// "W3 Total Cache" check
			if ($plugin === 'w3-total-cache/w3-total-cache.php' && Misc::isPluginActive($plugin)) {
				$w3tcConfigMaster = Misc::getW3tcMasterConfig();
				$w3tcEnableCss = (int)trim(Misc::extractBetween($w3tcConfigMaster, '"minify.css.enable":', ','), '" ');
				if ($w3tcEnableCss === 1) {
					$cssOptimizeEnabledIn[] = $pluginTitle;
					if ($returnType === 'if_enabled') { return true; }
				}
			}
			// "SG Optimizer" check
			if ($plugin === 'sg-cachepress/sg-cachepress.php' && Misc::isPluginActive($plugin)) {
				if (class_exists('\SiteGround_Optimizer\Options\Options')
				    && method_exists('\SiteGround_Optimizer\Options\Options', 'is_enabled')
				    && @\SiteGround_Optimizer\Options\Options::is_enabled('siteground_optimizer_combine_css')) {
					$cssOptimizeEnabledIn[] = $pluginTitle;
					if ($returnType === 'if_enabled') { return true; }
				}
			}
			// "Fast Velocity Minify" check
			if ($plugin === 'fast-velocity-minify/fvm.php' && Misc::isPluginActive($plugin)) {
				// It's enough if it's active due to its configuration
				$cssOptimizeEnabledIn[] = $pluginTitle;
				if ($returnType === 'if_enabled') { return true; }
			}
			// "LiteSpeed Cache" check
			if ($plugin === 'litespeed-cache/litespeed-cache.php' && Misc::isPluginActive($plugin) && ($liteSpeedCacheConf = apply_filters('litespeed_cache_get_options', get_option('litespeed-cache-conf')))) {
				if ( (isset($liteSpeedCacheConf['css_minify']) && $liteSpeedCacheConf['css_minify'])
				     || (isset($liteSpeedCacheConf['css_combine']) && $liteSpeedCacheConf['css_combine']) ) {
					$cssOptimizeEnabledIn[] = $pluginTitle;
					if ($returnType === 'if_enabled') { return true; }
				}
			}
			// "Swift Performance Lite" check
			if ($plugin === 'swift-performance-lite/performance.php' && Misc::isPluginActive($plugin)
			    && class_exists('Swift_Performance_Lite') && method_exists('Swift_Performance_Lite', 'check_option')) {
				if ( @\Swift_Performance_Lite::check_option('merge-styles', 1) ) {
					$cssOptimizeEnabledIn[] = $pluginTitle;
				}
				if ($returnType === 'if_enabled') { return true; }
			}
			// "Breeze – WordPress Cache Plugin"
			if ($plugin === 'breeze/breeze.php' && Misc::isPluginActive($plugin)) {
				$breezeBasicSettings    = get_option('breeze_basic_settings');
				$breezeAdvancedSettings = get_option('breeze_advanced_settings');
				if (isset($breezeBasicSettings['breeze-minify-css'], $breezeAdvancedSettings['breeze-group-css'])
				    && $breezeBasicSettings['breeze-minify-css'] && $breezeAdvancedSettings['breeze-group-css']) {
					$cssOptimizeEnabledIn[] = $pluginTitle;
					if ($returnType === 'if_enabled') { return true; }
				}
			}
		}
		if ($returnType === 'if_enabled') { return false; }
		return $cssOptimizeEnabledIn;
	}
	/**
	 * @return bool
	 */
	public static function isWpRocketOptimizeCssDeliveryEnabled()
	{
		if (Misc::isPluginActive('wp-rocket/wp-rocket.php')) {
			if (function_exists('get_rocket_option')) {
				$wpRocketAsyncCss = trim(get_rocket_option('async_css')) ?: false;
			} else {
				$wpRocketSettings  = get_option('wp_rocket_settings');
				$wpRocketAsyncCss = isset($wpRocketSettings['async_css']) && trim($wpRocketSettings['async_css']);
			}
			return $wpRocketAsyncCss;
		}
		return false;
	}
	/**
	 * @return bool
	 */
	public static function wpfcMinifyCssEnabledOnly()
	{
		if (Misc::isPluginActive('wp-fastest-cache/wpFastestCache.php')) {
			$wpfcOptionsJson = get_option('WpFastestCache');
			$wpfcOptions     = @json_decode($wpfcOptionsJson, ARRAY_A);
			// "Minify CSS" is enabled, "Combine CSS" is disabled
			return isset($wpfcOptions['wpFastestCacheMinifyCss']) && ! isset($wpfcOptions['wpFastestCacheCombineCss']);
		}
		return false;
	}
	/**
	 * @return bool
	 */
	public static function isWorthCheckingForOptimization()
	{
		// At least one of these options have to be enabled
		// Otherwise, we will not perform specific useless actions and save resources
		return MinifyCss::isMinifyCssEnabled() ||
		       Main::instance()->settings['google_fonts_display'] ||
		       Main::instance()->settings['google_fonts_remove'];
	}
	/**
	 * @param $htmlSource
	 *
	 * @return mixed
	 */
	public static function ignoreDependencyRuleAndKeepChildrenLoaded($htmlSource)
	{
		$ignoreChild = Main::instance()->getIgnoreChildren();
		if (isset($ignoreChild['styles']) && ! empty($ignoreChild['styles'])) {
			foreach (array_keys($ignoreChild['styles']) as $styleHandle) {
				// Always load the Dashicons if the top admin bar (toolbar) is shown
				if ($styleHandle === 'dashicons' && is_admin_bar_showing()) {
					continue;
				}
				if (isset(Main::instance()->wpAllStyles['registered'][$styleHandle]->src, Main::instance()->ignoreChildren['styles'][$styleHandle.'_has_unload_rule']) && Main::instance()->wpAllStyles['registered'][$styleHandle]->src && Main::instance()->ignoreChildren['styles'][$styleHandle.'_has_unload_rule']) {
					if ($scriptExtraAfterHtml = self::generateInlineAssocHtmlForHandle($styleHandle)) {
						$htmlSource = str_replace($scriptExtraAfterHtml, '', $htmlSource);
					}
					$listWithMatches   = array();
					$listWithMatches[] = 'data-wpacu-style-handle=[\'"]'.$styleHandle.'[\'"]';
					if ($styleSrc = Main::instance()->wpAllStyles['registered'][$styleHandle]->src) {
						$listWithMatches[] = OptimizeCommon::getSourceRelPath($styleSrc);
					}
					$htmlSource = CleanUp::cleanLinkTagFromHtmlSource($listWithMatches, $htmlSource);
				}
			}
		}
		return $htmlSource;
	}
	/**
	 * @param $styleTagOrHandle
	 * @param $wpacuRegisteredStyles
	 * @param $from
	 * @param string $return ("value": CSS Inline Content / "html": CSS Inline Content surrounded by tags)
	 *
	 * @return array
	 */
	public static function getInlineAssociatedWithLinkHandle($styleTagOrHandle, $wpacuRegisteredStyles, $from = 'tag', $return = 'value')
	{
		$styleExtraAfter = '';
		if ($from === 'tag') {
			preg_match_all('#data-wpacu-style-handle=([\'])' . '(.*)' . '(\1)#Usmi', $styleTagOrHandle, $outputMatches);
			$styleHandle = (isset($outputMatches[2][0]) && $outputMatches[2][0]) ? trim($outputMatches[2][0], '"\'') : '';
		} else {
			$styleHandle = $styleTagOrHandle;
		}
		if ($return === 'value' && $styleHandle && isset($wpacuRegisteredStyles[$styleHandle]->extra)) {
			$styleExtraArray = $wpacuRegisteredStyles[$styleHandle]->extra;
			if (isset($styleExtraArray['after']) && ! empty($styleExtraArray['after'])) {
				$styleExtraAfter .= "';
			}
			return array('after' => $styleExtraAfter);
		}
		if ( $return === 'html' && $styleHandle ) {
			// 'after' is the only one for inline CSS; there's no 'data' or 'before' like in the inline JS
			return array('after' => self::generateInlineAssocHtmlForHandle($styleHandle));
		}
		return array('after' => array());
	}
	/**
	 * @param $handle
	 * @param $inlineStyleContent
	 *
	 * @return string
	 */
	public static function generateInlineAssocHtmlForHandle($handle, $inlineStyleContent = '')
	{
		global $wp_styles;
		if ( ! $inlineStyleContent ) {
			$inlineStyleContent = $wp_styles->print_inline_style( $handle, false );
		}
		$output = '';
		if ( $inlineStyleContent ) {
			$output = sprintf(
				"",
				esc_attr( $handle ),
				Misc::getStyleTypeAttribute(),
				$inlineStyleContent
			);
		}
		return $output;
	}
	/**
	 * @param $htmlSource
	 *
	 * @return array|string|string[]
	 */
	public function appendNoScriptCertainLinkTags($htmlSource)
	{
		preg_match_all('#]*(data-wpacu-preload-it-async)[^>]*(>)#Umi', $htmlSource, $matchesSourcesFromTags, PREG_SET_ORDER);
		$noScripts = '';
		if (! empty($matchesSourcesFromTags)) {
			foreach ($matchesSourcesFromTags as $matchedValues) {
				$matchedTag = $matchedValues[0];
				$mediaAttrValue = Misc::getValueFromTag($matchedTag, 'media');
				$hrefAttrValue  = Misc::getValueFromTag($matchedTag);
				$noScripts .= ''."\n";
			}
		}
		return str_replace(self::MOVE_NOSCRIPT_TO_BODY_FOR_CERTAIN_LINK_TAGS, $noScripts, $htmlSource);
	}
	}