[BUGFIX] Check for enabled devlog inside devLog()
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Utility / GeneralUtility.php
old mode 100755 (executable)
new mode 100644 (file)
index b36a3a4..bd44ca7
@@ -14,12 +14,15 @@ namespace TYPO3\CMS\Core\Utility;
  * The TYPO3 project - inspiring people to share!
  */
 
+use GuzzleHttp\Exception\RequestException;
 use TYPO3\CMS\Core\Charset\CharsetConverter;
 use TYPO3\CMS\Core\Core\ApplicationContext;
 use TYPO3\CMS\Core\Core\ClassLoadingInformation;
+use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Http\RequestFactory;
 use TYPO3\CMS\Core\Service\OpcodeCacheService;
 use TYPO3\CMS\Core\SingletonInterface;
-use TYPO3\CMS\Frontend\Page\PageRepository;
+use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
 
 /**
  * The legendary "t3lib_div" class - Miscellaneous functions for general purpose.
@@ -59,21 +62,21 @@ class GeneralUtility
      *
      * @var array<\TYPO3\CMS\Core\SingletonInterface>
      */
-    protected static $singletonInstances = array();
+    protected static $singletonInstances = [];
 
     /**
      * Instances returned by makeInstance, using the class names as array keys
      *
      * @var array<array><object>
      */
-    protected static $nonSingletonInstances = array();
+    protected static $nonSingletonInstances = [];
 
     /**
      * Cache for makeInstance with given class name and final class names to reduce number of self::getClassName() calls
      *
      * @var array Given class name => final class name
      */
-    protected static $finalClassNameCache = array();
+    protected static $finalClassNameCache = [];
 
     /**
      * The application context
@@ -87,12 +90,12 @@ class GeneralUtility
      *
      * @var array<string>
      */
-    protected static $idnaStringCache = array();
+    protected static $idnaStringCache = [];
 
     /**
      * IDNA converter
      *
-     * @var \idna_convert
+     * @var \Mso\IdnaConvert\IdnaConvert
      */
     protected static $idnaConverter = null;
 
@@ -101,13 +104,13 @@ class GeneralUtility
      * NOTICE: This is a duplicate of the SAME array in SystemEnvironmentBuilder
      * @var array
      */
-    protected static $supportedCgiServerApis = array(
+    protected static $supportedCgiServerApis = [
         'fpm-fcgi',
         'cgi',
         'isapi',
         'cgi-fcgi',
         'srv', // HHVM with fastcgi
-    );
+    ];
 
     /**
      * @var array
@@ -163,8 +166,8 @@ class GeneralUtility
      */
     public static function _GPmerged($parameter)
     {
-        $postParameter = isset($_POST[$parameter]) && is_array($_POST[$parameter]) ? $_POST[$parameter] : array();
-        $getParameter = isset($_GET[$parameter]) && is_array($_GET[$parameter]) ? $_GET[$parameter] : array();
+        $postParameter = isset($_POST[$parameter]) && is_array($_POST[$parameter]) ? $_POST[$parameter] : [];
+        $getParameter = isset($_GET[$parameter]) && is_array($_GET[$parameter]) ? $_GET[$parameter] : [];
         $mergedParameters = $getParameter;
         ArrayUtility::mergeRecursiveWithOverrule($mergedParameters, $postParameter);
         return $mergedParameters;
@@ -212,14 +215,13 @@ class GeneralUtility
      *
      * @param mixed $inputGet
      * @param string $key
-     * @return void
      */
     public static function _GETset($inputGet, $key = '')
     {
         if ($key != '') {
             if (strpos($key, '|') !== false) {
                 $pieces = explode('|', $key);
-                $newGet = array();
+                $newGet = [];
                 $pointer = &$newGet;
                 foreach ($pieces as $piece) {
                     $pointer = &$pointer[$piece];
@@ -239,26 +241,6 @@ class GeneralUtility
         }
     }
 
-    /**
-     * Wrapper for the RemoveXSS function.
-     * Removes potential XSS code from an input string.
-     *
-     * Using an external class by Travis Puderbaugh <kallahar@quickwired.com>
-     *
-     * @param string $string Input string
-     * @return string Input string with potential XSS code removed
-     */
-    public static function removeXSS($string)
-    {
-        return \RemoveXSS::process($string);
-    }
-
-    /*************************
-     *
-     * IMAGE FUNCTIONS
-     *
-     *************************/
-
     /*************************
      *
      * STRING FUNCTIONS
@@ -441,7 +423,7 @@ class GeneralUtility
         // According to RFC lowercase-representation is recommended
         $address = strtolower($address);
         // Normalized representation has 39 characters (0000:0000:0000:0000:0000:0000:0000:0000)
-        if (strlen($address) == 39) {
+        if (strlen($address) === 39) {
             // Already in full expanded form
             return $address;
         }
@@ -453,7 +435,7 @@ class GeneralUtility
             $left = count($chunksLeft);
             $right = count($chunksRight);
             // Special case: leading zero-only blocks count to 1, should be 0
-            if ($left == 1 && strlen($chunksLeft[0]) == 0) {
+            if ($left === 1 && strlen($chunksLeft[0]) === 0) {
                 $left = 0;
             }
             $hiddenBlocks = 8 - ($left + $right);
@@ -463,7 +445,7 @@ class GeneralUtility
                 $hiddenPart .= '0000:';
                 $h++;
             }
-            if ($left == 0) {
+            if ($left === 0) {
                 $stageOneAddress = $hiddenPart . $chunks[1];
             } else {
                 $stageOneAddress = $chunks[0] . ':' . $hiddenPart . $chunks[1];
@@ -667,7 +649,7 @@ class GeneralUtility
     public static function expandList($list)
     {
         $items = explode(',', $list);
-        $list = array();
+        $list = [];
         foreach ($items as $item) {
             $range = explode('-', $item);
             if (isset($range[1])) {
@@ -687,19 +669,6 @@ class GeneralUtility
     }
 
     /**
-     * Returns TRUE if the current TYPO3 version (or compatibility version) is compatible to the input version
-     * Notice that this function compares branches, not versions (4.0.1 would be > 4.0.0 although they use the same compat_version)
-     *
-     * @param string $verNumberStr Minimum branch number required (format x.y / e.g. "4.0" NOT "4.0.0"!)
-     * @return bool Returns TRUE if this setup is compatible with the provided version number
-     * @todo Still needs a function to convert versions to branches
-     */
-    public static function compat_version($verNumberStr)
-    {
-        return VersionNumberUtility::convertVersionNumberToInteger(TYPO3_branch) >= VersionNumberUtility::convertVersionNumberToInteger($verNumberStr);
-    }
-
-    /**
      * Makes a positive integer hash out of the first 7 chars from the md5 hash of the input
      *
      * @param string $str String to md5-hash
@@ -726,7 +695,7 @@ class GeneralUtility
      * Returns a proper HMAC on a given input string and secret TYPO3 encryption key.
      *
      * @param string $input Input string to create HMAC from
-     * @param string $additionalSecret additionalSecret to prevent hmac beeing used in a different context
+     * @param string $additionalSecret additionalSecret to prevent hmac being used in a different context
      * @return string resulting (hexadecimal) HMAC currently with a length of 40 (HMAC-SHA-1)
      */
     public static function hmac($input, $additionalSecret = '')
@@ -781,7 +750,7 @@ class GeneralUtility
      */
     public static function split_fileref($fileNameWithPath)
     {
-        $reg = array();
+        $reg = [];
         if (preg_match('/(.*\\/)(.*)$/', $fileNameWithPath, $reg)) {
             $info['path'] = $reg[1];
             $info['file'] = $reg[2];
@@ -846,10 +815,10 @@ class GeneralUtility
      */
     public static function formatSize($sizeInBytes, $labels = '', $base = 0)
     {
-        $defaultFormats = array(
-            'iec' => array('base' => 1024, 'labels' => array(' ', ' Ki', ' Mi', ' Gi', ' Ti', ' Pi', ' Ei', ' Zi', ' Yi')),
-            'si' => array('base' => 1000, 'labels' => array(' ', ' k', ' M', ' G', ' T', ' P', ' E', ' Z', ' Y')),
-        );
+        $defaultFormats = [
+            'iec' => ['base' => 1024, 'labels' => [' ', ' Ki', ' Mi', ' Gi', ' Ti', ' Pi', ' Ei', ' Zi', ' Yi']],
+            'si' => ['base' => 1000, 'labels' => [' ', ' k', ' M', ' G', ' T', ' P', ' E', ' Z', ' Y']],
+        ];
         // Set labels and base:
         if (empty($labels)) {
             $labels = 'iec';
@@ -886,18 +855,6 @@ class GeneralUtility
     }
 
     /**
-     * Returns microtime input to milliseconds
-     *
-     * @param string $microtime Microtime
-     * @return int Microtime input string converted to an integer (milliseconds)
-     */
-    public static function convertMicrotime($microtime)
-    {
-        $parts = explode(' ', $microtime);
-        return round(($parts[0] + $parts[1]) * 1000);
-    }
-
-    /**
      * This splits a string by the chars in $operators (typical /+-*) and returns an array with them in
      *
      * @param string $string Input string, eg "123 + 456 / 789 - 4
@@ -907,12 +864,12 @@ class GeneralUtility
      */
     public static function splitCalc($string, $operators)
     {
-        $res = array();
+        $res = [];
         $sign = '+';
         while ($string) {
             $valueLen = strcspn($string, $operators);
             $value = substr($string, 0, $valueLen);
-            $res[] = array($sign, trim($value));
+            $res[] = [$sign, trim($value)];
             $sign = substr($string, $valueLen, 1);
             $string = substr($string, $valueLen + 1);
         }
@@ -921,60 +878,6 @@ class GeneralUtility
     }
 
     /**
-     * Re-converts HTML entities if they have been converted by htmlspecialchars()
-     * Note: Use htmlspecialchars($str, ENT_COMPAT, 'UTF-8', FALSE) to avoid double encoding.
-     *       This makes the call to this method obsolete.
-     *
-     * @param string $str String which contains eg. "&amp;amp;" which should stay "&amp;". Or "&amp;#1234;" to "&#1234;". Or "&amp;#x1b;" to "&#x1b;
-     * @return string Converted result.
-     *
-     */
-    public static function deHSCentities($str)
-    {
-        return preg_replace('/&amp;([#[:alnum:]]*;)/', '&\\1', $str);
-    }
-
-    /**
-     * This function is used to escape any ' -characters when transferring text to JavaScript!
-     *
-     * @param string $string String to escape
-     * @param bool $extended If set, also backslashes are escaped.
-     * @param string $char The character to escape, default is ' (single-quote)
-     * @return string Processed input string
-     */
-    public static function slashJS($string, $extended = false, $char = '\'')
-    {
-        if ($extended) {
-            $string = str_replace('\\', '\\\\', $string);
-        }
-        return str_replace($char, '\\' . $char, $string);
-    }
-
-    /**
-     * Version of rawurlencode() where all spaces (%20) are re-converted to space-characters.
-     * Useful when passing text to JavaScript where you simply url-encode it to get around problems with syntax-errors, linebreaks etc.
-     *
-     * @param string $str String to raw-url-encode with spaces preserved
-     * @return string Rawurlencoded result of input string, but with all %20 (space chars) converted to real spaces.
-     */
-    public static function rawUrlEncodeJS($str)
-    {
-        return str_replace('%20', ' ', rawurlencode($str));
-    }
-
-    /**
-     * rawurlencode which preserves "/" chars
-     * Useful when file paths should keep the "/" chars, but have all other special chars encoded.
-     *
-     * @param string $str Input string
-     * @return string Output string
-     */
-    public static function rawUrlEncodeFP($str)
-    {
-        return str_replace('%2F', '/', rawurlencode($str));
-    }
-
-    /**
      * Checking syntax of input email address
      *
      * http://tools.ietf.org/html/rfc3696
@@ -1012,144 +915,6 @@ class GeneralUtility
     }
 
     /**
-     * Converts string to uppercase
-     * The function converts all Latin characters (a-z, but no accents, etc) to
-     * uppercase. It is safe for all supported character sets (incl. utf-8).
-     * Unlike strtoupper() it does not honour the locale.
-     *
-     * @param string $str Input string
-     * @return string Uppercase String
-     */
-    public static function strtoupper($str)
-    {
-        return strtr((string)$str, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
-    }
-
-    /**
-     * Converts string to lowercase
-     * The function converts all Latin characters (A-Z, but no accents, etc) to
-     * lowercase. It is safe for all supported character sets (incl. utf-8).
-     * Unlike strtolower() it does not honour the locale.
-     *
-     * @param string $str Input string
-     * @return string Lowercase String
-     */
-    public static function strtolower($str)
-    {
-        return strtr((string)$str, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
-    }
-
-    /**
-     * Returns a string of highly randomized bytes (over the full 8-bit range).
-     *
-     * Note: Returned values are not guaranteed to be crypto-safe,
-     * most likely they are not, depending on the used retrieval method.
-     *
-     * @param int $bytesToReturn Number of characters (bytes) to return
-     * @return string Random Bytes
-     * @see http://bugs.php.net/bug.php?id=52523
-     * @see http://www.php-security.org/2010/05/09/mops-submission-04-generating-unpredictable-session-ids-and-hashes/index.html
-     */
-    public static function generateRandomBytes($bytesToReturn)
-    {
-        // Cache 4k of the generated bytestream.
-        static $bytes = '';
-        $bytesToGenerate = max(4096, $bytesToReturn);
-        // if we have not enough random bytes cached, we generate new ones
-        if (!isset($bytes[$bytesToReturn - 1])) {
-            if (TYPO3_OS === 'WIN') {
-                // Openssl seems to be deadly slow on Windows, so try to use mcrypt
-                $bytes .= self::generateRandomBytesMcrypt($bytesToGenerate);
-            } else {
-                // Try to use native PHP functions first, precedence has openssl
-                $bytes .= self::generateRandomBytesOpenSsl($bytesToGenerate);
-                if (!isset($bytes[$bytesToReturn - 1])) {
-                    $bytes .= self::generateRandomBytesMcrypt($bytesToGenerate);
-                }
-                // If openssl and mcrypt failed, try /dev/urandom
-                if (!isset($bytes[$bytesToReturn - 1])) {
-                    $bytes .= self::generateRandomBytesUrandom($bytesToGenerate);
-                }
-            }
-            // Fall back if other random byte generation failed until now
-            if (!isset($bytes[$bytesToReturn - 1])) {
-                $bytes .= self::generateRandomBytesFallback($bytesToReturn);
-            }
-        }
-        // get first $bytesToReturn and remove it from the byte cache
-        $output = substr($bytes, 0, $bytesToReturn);
-        $bytes = substr($bytes, $bytesToReturn);
-        return $output;
-    }
-
-    /**
-     * Generate random bytes using openssl if available
-     *
-     * @param string $bytesToGenerate
-     * @return string
-     */
-    protected static function generateRandomBytesOpenSsl($bytesToGenerate)
-    {
-        if (!function_exists('openssl_random_pseudo_bytes')) {
-            return '';
-        }
-        $isStrong = null;
-        return (string)openssl_random_pseudo_bytes($bytesToGenerate, $isStrong);
-    }
-
-    /**
-     * Generate random bytes using mcrypt if available
-     *
-     * @param $bytesToGenerate
-     * @return string
-     */
-    protected static function generateRandomBytesMcrypt($bytesToGenerate)
-    {
-        if (!function_exists('mcrypt_create_iv')) {
-            return '';
-        }
-        return (string)(@mcrypt_create_iv($bytesToGenerate, MCRYPT_DEV_URANDOM));
-    }
-
-    /**
-     * Read random bytes from /dev/urandom if it is accessible
-     *
-     * @param $bytesToGenerate
-     * @return string
-     */
-    protected static function generateRandomBytesUrandom($bytesToGenerate)
-    {
-        $bytes = '';
-        $fh = @fopen('/dev/urandom', 'rb');
-        if ($fh) {
-            // PHP only performs buffered reads, so in reality it will always read
-            // at least 4096 bytes. Thus, it costs nothing extra to read and store
-            // that much so as to speed any additional invocations.
-            $bytes = fread($fh, $bytesToGenerate);
-            fclose($fh);
-        }
-        return $bytes;
-    }
-
-    /**
-     * Generate pseudo random bytes as last resort
-     *
-     * @param $bytesToReturn
-     * @return string
-     */
-    protected static function generateRandomBytesFallback($bytesToReturn)
-    {
-        $bytes = '';
-        // We initialize with somewhat random.
-        $randomState = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . base_convert(memory_get_usage() % pow(10, 6), 10, 2) . microtime() . StringUtility::getUniqueId() . getmypid();
-        while (!isset($bytes[$bytesToReturn - 1])) {
-            $randomState = sha1(microtime() . mt_rand() . $randomState);
-            $bytes .= sha1(mt_rand() . $randomState, true);
-        }
-        return $bytes;
-    }
-
-    /**
      * Returns an ASCII string (punicode) representation of $value
      *
      * @param string $value
@@ -1161,7 +926,7 @@ class GeneralUtility
             return self::$idnaStringCache[$value];
         } else {
             if (!self::$idnaConverter) {
-                self::$idnaConverter = new \idna_convert(array('idn_version' => 2008));
+                self::$idnaConverter = new \Mso\IdnaConvert\IdnaConvert(['idn_version' => 2008]);
             }
             self::$idnaStringCache[$value] = self::$idnaConverter->encode($value);
             return self::$idnaStringCache[$value];
@@ -1169,17 +934,6 @@ class GeneralUtility
     }
 
     /**
-     * Returns a hex representation of a random byte string.
-     *
-     * @param int $count Number of hex characters to return
-     * @return string Random Bytes
-     */
-    public static function getRandomHexString($count)
-    {
-        return substr(bin2hex(self::generateRandomBytes((int)(($count + 1) / 2))), 0, $count);
-    }
-
-    /**
      * Returns a given string with underscores as UpperCamelCase.
      * Example: Converts blog_example to BlogExample
      *
@@ -1188,8 +942,7 @@ class GeneralUtility
      */
     public static function underscoredToUpperCamelCase($string)
     {
-        $upperCamelCase = str_replace(' ', '', ucwords(str_replace('_', ' ', self::strtolower($string))));
-        return $upperCamelCase;
+        return str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower($string))));
     }
 
     /**
@@ -1201,9 +954,7 @@ class GeneralUtility
      */
     public static function underscoredToLowerCamelCase($string)
     {
-        $upperCamelCase = str_replace(' ', '', ucwords(str_replace('_', ' ', self::strtolower($string))));
-        $lowerCamelCase = self::lcfirst($upperCamelCase);
-        return $lowerCamelCase;
+        return lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower($string)))));
     }
 
     /**
@@ -1215,19 +966,8 @@ class GeneralUtility
      */
     public static function camelCaseToLowerCaseUnderscored($string)
     {
-        return self::strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $string));
-    }
-
-    /**
-     * Converts the first char of a string to lowercase if it is a latin character (A-Z).
-     * Example: Converts "Hello World" to "hello World"
-     *
-     * @param string $string The string to be used to lowercase the first character
-     * @return string The string with the first character as lowercase
-     */
-    public static function lcfirst($string)
-    {
-        return self::strtolower($string[0]) . substr($string, 1);
+        $value = preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $string);
+        return mb_strtolower($value, 'utf-8');
     }
 
     /**
@@ -1285,7 +1025,7 @@ class GeneralUtility
      *************************/
 
     /**
-     * Explodes a $string delimited by $delim and casts each item in the array to (int).
+     * Explodes a $string delimited by $delimiter and casts each item in the array to (int).
      * Corresponds to \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(), but with conversion to integers for all values.
      *
      * @param string $delimiter Delimiter string to explode with
@@ -1337,12 +1077,12 @@ class GeneralUtility
         if ($count === 2) {
             $position = strrpos($string, strrev($delimiter));
             if ($position !== false) {
-                return array(substr($string, 0, $position), substr($string, $position + strlen($delimiter)));
+                return [substr($string, 0, $position), substr($string, $position + strlen($delimiter))];
             } else {
-                return array($string);
+                return [$string];
             }
         } elseif ($count <= 1) {
-            return array($string);
+            return [$string];
         } else {
             $explodedValues = explode($delimiter, strrev($string), $count);
             $explodedValues = array_map('strrev', $explodedValues);
@@ -1366,7 +1106,7 @@ class GeneralUtility
     {
         $result = explode($delim, $string);
         if ($removeEmptyValues) {
-            $temp = array();
+            $temp = [];
             foreach ($result as $value) {
                 if (trim($value) !== '') {
                     $temp[] = $value;
@@ -1420,7 +1160,7 @@ class GeneralUtility
      */
     public static function explodeUrl2Array($string, $multidim = false)
     {
-        $output = array();
+        $output = [];
         if ($multidim) {
             parse_str($string, $output);
         } else {
@@ -1447,7 +1187,7 @@ class GeneralUtility
     public static function compileSelectedGetVarsFromArray($varList, array $getArray, $GPvarAlt = true)
     {
         $keys = self::trimExplode(',', $varList, true);
-        $outArr = array();
+        $outArr = [];
         foreach ($keys as $v) {
             if (isset($getArray[$v])) {
                 $outArr[$v] = $getArray[$v];
@@ -1459,24 +1199,6 @@ class GeneralUtility
     }
 
     /**
-     * Takes a row and returns a CSV string of the values with $delim (default is ,) and $quote (default is ") as separator chars.
-     *
-     * @param array $row Input array of values
-     * @param string $delim Delimited, default is comma
-     * @param string $quote Quote-character to wrap around the values.
-     * @return string A single line of CSV
-     */
-    public static function csvValues(array $row, $delim = ',', $quote = '"')
-    {
-        $out = array();
-        foreach ($row as $value) {
-            $out[] = str_replace($quote, $quote . $quote, $value);
-        }
-        $str = $quote . implode(($quote . $delim . $quote), $out) . $quote;
-        return $str;
-    }
-
-    /**
      * Removes dots "." from end of a key identifier of TypoScript styled array.
      * array('key.' => array('property.' => 'value')) --> array('key' => array('property' => 'value'))
      *
@@ -1485,7 +1207,7 @@ class GeneralUtility
      */
     public static function removeDotsFromTS(array $ts)
     {
-        $out = array();
+        $out = [];
         foreach ($ts as $key => $value) {
             if (is_array($value)) {
                 $key = rtrim($key, '.');
@@ -1516,10 +1238,10 @@ class GeneralUtility
         // Attribute name is stored here
         $name = '';
         $valuemode = false;
-        $attributes = array();
+        $attributes = [];
         foreach ($components as $key => $val) {
             // Only if $name is set (if there is an attribute, that waits for a value), that valuemode is enabled. This ensures that the attribute is assigned it's value
-            if ($val != '=') {
+            if ($val !== '=') {
                 if ($valuemode) {
                     if ($name) {
                         $attributes[$name] = $val;
@@ -1551,7 +1273,7 @@ class GeneralUtility
         $tag_tmp = trim(preg_replace('/^<[^[:space:]]*/', '', trim($tag)));
         // Removes any > in the end of the string
         $tag_tmp = trim(rtrim($tag_tmp, '>'));
-        $value = array();
+        $value = [];
         // Compared with empty string instead , 030102
         while ($tag_tmp !== '') {
             $firstChar = $tag_tmp[0];
@@ -1585,7 +1307,7 @@ class GeneralUtility
     public static function implodeAttributes(array $arr, $xhtmlSafe = false, $dontOmitBlankAttribs = false)
     {
         if ($xhtmlSafe) {
-            $newArr = array();
+            $newArr = [];
             foreach ($arr as $p => $v) {
                 if (!isset($newArr[strtolower($p)])) {
                     $newArr[strtolower($p)] = htmlspecialchars($v);
@@ -1593,7 +1315,7 @@ class GeneralUtility
             }
             $arr = $newArr;
         }
-        $list = array();
+        $list = [];
         foreach ($arr as $p => $v) {
             if ((string)$v !== '' || $dontOmitBlankAttribs) {
                 $list[] = $p . '="' . $v . '"';
@@ -1608,28 +1330,25 @@ class GeneralUtility
      * This is nice for indenting JS code with PHP code on the same level.
      *
      * @param string $string JavaScript code
-     * @param bool $linebreak Wrap script element in line breaks? Default is TRUE.
      * @return string The wrapped JS code, ready to put into a XHTML page
      */
-    public static function wrapJS($string, $linebreak = true)
+    public static function wrapJS($string)
     {
         if (trim($string)) {
-            // <script wrapped in nl?
-            $cr = $linebreak ? LF : '';
             // remove nl from the beginning
-            $string = preg_replace('/^\\n+/', '', $string);
+            $string = ltrim($string, LF);
             // re-ident to one tab using the first line as reference
-            $match = array();
+            $match = [];
             if (preg_match('/^(\\t+)/', $string, $match)) {
                 $string = str_replace($match[1], TAB, $string);
             }
-            $string = $cr . '<script type="text/javascript">
+            return '<script type="text/javascript">
 /*<![CDATA[*/
 ' . $string . '
 /*]]>*/
-</script>' . $cr;
+</script>';
         }
-        return trim($string);
+        return '';
     }
 
     /**
@@ -1640,13 +1359,13 @@ class GeneralUtility
      * @param array $parserOptions Options that will be passed to PHP's xml_parser_set_option()
      * @return mixed The array with the parsed structure unless the XML parser returns with an error in which case the error message string is returned.
      */
-    public static function xml2tree($string, $depth = 999, $parserOptions = array())
+    public static function xml2tree($string, $depth = 999, $parserOptions = [])
     {
         // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept
         $previousValueOfEntityLoader = libxml_disable_entity_loader(true);
         $parser = xml_parser_create();
-        $vals = array();
-        $index = array();
+        $vals = [];
+        $index = [];
         xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
         xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
         foreach ($parserOptions as $option => $value) {
@@ -1658,19 +1377,19 @@ class GeneralUtility
             return 'Line ' . xml_get_current_line_number($parser) . ': ' . xml_error_string(xml_get_error_code($parser));
         }
         xml_parser_free($parser);
-        $stack = array(array());
+        $stack = [[]];
         $stacktop = 0;
         $startPoint = 0;
-        $tagi = array();
+        $tagi = [];
         foreach ($vals as $key => $val) {
             $type = $val['type'];
             // open tag:
-            if ($type == 'open' || $type == 'complete') {
+            if ($type === 'open' || $type === 'complete') {
                 $stack[$stacktop++] = $tagi;
                 if ($depth == $stacktop) {
                     $startPoint = $key;
                 }
-                $tagi = array('tag' => $val['tag']);
+                $tagi = ['tag' => $val['tag']];
                 if (isset($val['attributes'])) {
                     $tagi['attrs'] = $val['attributes'];
                 }
@@ -1679,7 +1398,7 @@ class GeneralUtility
                 }
             }
             // finish tag:
-            if ($type == 'complete' || $type == 'close') {
+            if ($type === 'complete' || $type === 'close') {
                 $oldtagi = $tagi;
                 $tagi = $stack[--$stacktop];
                 $oldtag = $oldtagi['tag'];
@@ -1696,7 +1415,7 @@ class GeneralUtility
                 unset($oldtagi);
             }
             // cdata
-            if ($type == 'cdata') {
+            if ($type === 'cdata') {
                 $tagi['values'][] = $val['value'];
             }
         }
@@ -1704,26 +1423,6 @@ class GeneralUtility
     }
 
     /**
-     * Turns PHP array into XML. See array2xml()
-     *
-     * @param array $array The input PHP array with any kind of data; text, binary, integers. Not objects though.
-     * @param string $docTag Alternative document tag. Default is "phparray".
-     * @param array $options Options for the compilation. See array2xml() for description.
-     * @param string $charset Forced charset to prologue
-     * @return string An XML string made from the input content in the array.
-     * @see xml2array(),array2xml()
-     */
-    public static function array2xml_cs(array $array, $docTag = 'phparray', array $options = array(), $charset = '')
-    {
-        // Set default charset unless explicitly specified
-        $charset = $charset ?: 'utf-8';
-        // Return XML:
-        return '<?xml version="1.0" encoding="' . htmlspecialchars($charset) . '" standalone="yes" ?>' . LF . self::array2xml($array, '', 0, $docTag, 0, $options);
-    }
-
-    /**
-     * Deprecated to call directly (unless you are aware of using XML prologues)! Use "array2xml_cs" instead (which adds an XML-prologue)
-     *
      * Converts a PHP array into an XML string.
      * The XML output is optimized for readability since associative keys are used as tag names.
      * This also means that only alphanumeric characters are allowed in the tag names AND only keys NOT starting with numbers (so watch your usage of keys!). However there are options you can set to avoid this problem.
@@ -1743,7 +1442,7 @@ class GeneralUtility
      * @return string An XML string made from the input content in the array.
      * @see xml2array()
      */
-    public static function array2xml(array $array, $NSprefix = '', $level = 0, $docTag = 'phparray', $spaceInd = 0, array $options = array(), array $stackData = array())
+    public static function array2xml(array $array, $NSprefix = '', $level = 0, $docTag = 'phparray', $spaceInd = 0, array $options = [], array $stackData = [])
     {
         // The list of byte values which will trigger binary-safe storage. If any value has one of these char values in it, it will be encoded in base64
         $binaryChars = chr(0) . chr(1) . chr(2) . chr(3) . chr(4) . chr(5) . chr(6) . chr(7) . chr(8) . chr(11) . chr(12) . chr(14) . chr(15) . chr(16) . chr(17) . chr(18) . chr(19) . chr(20) . chr(21) . chr(22) . chr(23) . chr(24) . chr(25) . chr(26) . chr(27) . chr(28) . chr(29) . chr(30) . chr(31);
@@ -1804,11 +1503,11 @@ class GeneralUtility
                 if (empty($v)) {
                     $content = '';
                 } else {
-                    $content = $nl . self::array2xml($v, $NSprefix, ($level + 1), '', $spaceInd, $subOptions, array(
+                    $content = $nl . self::array2xml($v, $NSprefix, ($level + 1), '', $spaceInd, $subOptions, [
                             'parentTagName' => $tagName,
                             'grandParentTagName' => $stackData['parentTagName'],
                             'path' => ($clearStackPath ? '' : $stackData['path'] . '/' . $tagName)
-                        )) . ($spaceInd >= 0 ? str_pad('', ($level + 1) * $indentN, $indentChar) : '');
+                        ]) . ($spaceInd >= 0 ? str_pad('', ($level + 1) * $indentN, $indentChar) : '');
                 }
                 // Do not set "type = array". Makes prettier XML but means that empty arrays are not restored with xml2array
                 if ((int)$options['disableTypeAttrib'] != 2) {
@@ -1827,7 +1526,7 @@ class GeneralUtility
                     // Otherwise, just htmlspecialchar the stuff:
                     $content = htmlspecialchars($v);
                     $dType = gettype($v);
-                    if ($dType == 'string') {
+                    if ($dType === 'string') {
                         if ($options['useCDATA'] && $content != $v) {
                             $content = '<![CDATA[' . $v . ']]>';
                         }
@@ -1862,19 +1561,13 @@ class GeneralUtility
      */
     public static function xml2array($string, $NSprefix = '', $reportDocTag = false)
     {
-        static $firstLevelCache = array();
+        static $firstLevelCache = [];
         $identifier = md5($string . $NSprefix . ($reportDocTag ? '1' : '0'));
         // Look up in first level cache
         if (!empty($firstLevelCache[$identifier])) {
             $array = $firstLevelCache[$identifier];
         } else {
-            // Look up in second level cache
-            // @todo: Is this cache really required? It basically substitutes a little cpu work with a db query?
-            $array = PageRepository::getHash($identifier, 0);
-            if (!is_array($array)) {
-                $array = self::xml2arrayProcess($string, $NSprefix, $reportDocTag);
-                PageRepository::storeHash($identifier, $array, 'ident_xml2array');
-            }
+            $array = self::xml2arrayProcess(trim($string), $NSprefix, $reportDocTag);
             // Store content in first level cache
             $firstLevelCache[$identifier] = $array;
         }
@@ -1897,12 +1590,12 @@ class GeneralUtility
         $previousValueOfEntityLoader = libxml_disable_entity_loader(true);
         // Create parser:
         $parser = xml_parser_create();
-        $vals = array();
-        $index = array();
+        $vals = [];
+        $index = [];
         xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
         xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
         // Default output charset is UTF-8, only ASCII, ISO-8859-1 and UTF-8 are supported!!!
-        $match = array();
+        $match = [];
         preg_match('/^[[:space:]]*<\\?xml[^>]*encoding[[:space:]]*=[[:space:]]*"([^"]*)"/', substr($string, 0, 200), $match);
         $theCharset = $match[1] ?: 'utf-8';
         // us-ascii / utf-8 / iso-8859-1
@@ -1916,9 +1609,9 @@ class GeneralUtility
         }
         xml_parser_free($parser);
         // Init vars:
-        $stack = array(array());
+        $stack = [[]];
         $stacktop = 0;
-        $current = array();
+        $current = [];
         $tagName = '';
         $documentTag = '';
         // Traverse the parsed XML structure:
@@ -1943,9 +1636,9 @@ class GeneralUtility
                 case 'open':
                     // If open tag it means there is an array stored in sub-elements. Therefore increase the stackpointer and reset the accumulation array:
                     // Setting blank place holder
-                    $current[$tagName] = array();
+                    $current[$tagName] = [];
                     $stack[$stacktop++] = $current;
-                    $current = array();
+                    $current = [];
                     break;
                 case 'close':
                     // If the tag is "close" then it is an array which is closing and we decrease the stack pointer.
@@ -1979,7 +1672,7 @@ class GeneralUtility
                                 break;
                             case 'array':
                                 // MUST be an empty array since it is processed as a value; Empty arrays would end up here because they would have no tags inside...
-                                $current[$tagName] = array();
+                                $current[$tagName] = [];
                                 break;
                         }
                     }
@@ -2005,14 +1698,14 @@ class GeneralUtility
         foreach ($vals as $val) {
             $type = $val['type'];
             // Open tag:
-            if ($type == 'open' || $type == 'complete') {
+            if ($type === 'open' || $type === 'complete') {
                 $XMLcontent .= '<' . $val['tag'];
                 if (isset($val['attributes'])) {
                     foreach ($val['attributes'] as $k => $v) {
                         $XMLcontent .= ' ' . $k . '="' . htmlspecialchars($v) . '"';
                     }
                 }
-                if ($type == 'complete') {
+                if ($type === 'complete') {
                     if (isset($val['value'])) {
                         $XMLcontent .= '>' . htmlspecialchars($val['value']) . '</' . $val['tag'] . '>';
                     } else {
@@ -2021,16 +1714,16 @@ class GeneralUtility
                 } else {
                     $XMLcontent .= '>';
                 }
-                if ($type == 'open' && isset($val['value'])) {
+                if ($type === 'open' && isset($val['value'])) {
                     $XMLcontent .= htmlspecialchars($val['value']);
                 }
             }
             // Finish tag:
-            if ($type == 'close') {
+            if ($type === 'close') {
                 $XMLcontent .= '</' . $val['tag'] . '>';
             }
             // Cdata
-            if ($type == 'cdata') {
+            if ($type === 'cdata') {
                 $XMLcontent .= htmlspecialchars($val['value']);
             }
         }
@@ -2038,22 +1731,6 @@ class GeneralUtility
     }
 
     /**
-     * Extracts the attributes (typically encoding and version) of an XML prologue (header).
-     *
-     * @param string $xmlData XML data
-     * @return array Attributes of the xml prologue (header)
-     * @deprecated since TYPO3 CMS 8, will be removed in TYPO3 CMS 9.
-     */
-    public static function xmlGetHeaderAttribs($xmlData)
-    {
-        self::logDeprecatedFunction();
-        $match = array();
-        if (preg_match('/^\\s*<\\?xml([^>]*)\\?\\>/', $xmlData, $match)) {
-            return self::get_tag_attributes($match[1]);
-        }
-    }
-
-    /**
      * Minifies JavaScript
      *
      * @param string $script Script to minify
@@ -2066,16 +1743,16 @@ class GeneralUtility
             $fakeThis = false;
             foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['minifyJavaScript'] as $hookMethod) {
                 try {
-                    $parameters = array('script' => $script);
+                    $parameters = ['script' => $script];
                     $script = static::callUserFunction($hookMethod, $parameters, $fakeThis);
                 } catch (\Exception $e) {
                     $errorMessage = 'Error minifying java script: ' . $e->getMessage();
                     $error .= $errorMessage;
-                    static::devLog($errorMessage, \TYPO3\CMS\Core\Utility\GeneralUtility::class, 2, array(
+                    static::devLog($errorMessage, \TYPO3\CMS\Core\Utility\GeneralUtility::class, 2, [
                         'JavaScript' => $script,
                         'Stack trace' => $e->getTrace(),
                         'hook' => $hookMethod
-                    ));
+                    ]);
                 }
             }
         }
@@ -2089,7 +1766,7 @@ class GeneralUtility
      *************************/
     /**
      * Reads the file or url $url and returns the content
-     * If you are having trouble with proxys when reading URLs you can configure your way out of that with settings like $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlUse'] etc.
+     * If you are having trouble with proxies when reading URLs you can configure your way out of that with settings within $GLOBALS['TYPO3_CONF_VARS']['HTTP'].
      *
      * @param string $url File/URL to read
      * @param int $includeHeader Whether the HTTP header should be fetched or not. 0=disable, 1=fetch header+content, 2=fetch header only
@@ -2097,174 +1774,75 @@ class GeneralUtility
      * @param array $report Error code/message and, if $includeHeader is 1, response meta data (HTTP status and content type)
      * @return mixed The content from the resource given as input. FALSE if an error has occurred.
      */
-    public static function getUrl($url, $includeHeader = 0, $requestHeaders = false, &$report = null)
+    public static function getUrl($url, $includeHeader = 0, $requestHeaders = null, &$report = null)
     {
-        $content = false;
         if (isset($report)) {
             $report['error'] = 0;
             $report['message'] = '';
         }
-        // Use cURL for: http, https, ftp, ftps, sftp and scp
-        if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlUse'] == '1' && preg_match('/^(?:http|ftp)s?|s(?:ftp|cp):/', $url)) {
-            if (isset($report)) {
-                $report['lib'] = 'cURL';
-            }
-            // External URL without error checking.
-            if (!function_exists('curl_init') || !($ch = curl_init())) {
-                if (isset($report)) {
-                    $report['error'] = -1;
-                    $report['message'] = 'Couldn\'t initialize cURL.';
-                }
-                return false;
-            }
-
-            $followLocationSucceeded = @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
-
-            curl_setopt($ch, CURLOPT_URL, $url);
-            curl_setopt($ch, CURLOPT_HEADER, !$followLocationSucceeded || $includeHeader ? 1 : 0);
-            curl_setopt($ch, CURLOPT_NOBODY, $includeHeader == 2 ? 1 : 0);
-            curl_setopt($ch, CURLOPT_HTTPGET, $includeHeader == 2 ? 'HEAD' : 'GET');
-            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
-            curl_setopt($ch, CURLOPT_FAILONERROR, 1);
-            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, max(0, (int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['curlTimeout']));
-
+        // Looks like it's an external file, use Guzzle by default
+        if (preg_match('/^(?:http|ftp)s?|s(?:ftp|cp):/', $url)) {
+            /** @var RequestFactory $requestFactory */
+            $requestFactory = static::makeInstance(RequestFactory::class);
             if (is_array($requestHeaders)) {
-                curl_setopt($ch, CURLOPT_HTTPHEADER, $requestHeaders);
-            }
-            // (Proxy support implemented by Arco <arco@appeltaart.mine.nu>)
-            if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']) {
-                curl_setopt($ch, CURLOPT_PROXY, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']);
-                if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyNTLM']) {
-                    curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_NTLM);
-                }
-                if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyTunnel']) {
-                    curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyTunnel']);
-                }
-                if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass']) {
-                    curl_setopt($ch, CURLOPT_PROXYUSERPWD, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass']);
-                }
-            }
-            $content = curl_exec($ch);
-            $curlInfo = curl_getinfo($ch);
-
-            if (!$followLocationSucceeded) {
-                // Check if we need to do redirects
-                if ($curlInfo['http_code'] >= 300 && $curlInfo['http_code'] < 400) {
-                    $locationUrl = $curlInfo['redirect_url'];
-                    if (!$locationUrl) {
-                        // Some curllib versions do not return redirect_url. Examine headers.
-                        $locationUrl = self::getRedirectUrlFromHttpHeaders($content);
-                    }
-                    if ($locationUrl) {
-                        $content = self::getUrl($locationUrl, $includeHeader, $requestHeaders, $report);
-                        $followLocationSucceeded = true;
-                    } else {
-                        // Failure: we got a redirection status code but not the URL to redirect to.
-                        $content = false;
-                    }
-                }
-                if ($content && !$includeHeader) {
-                    $content = self::stripHttpHeaders($content);
-                }
+                $configuration = ['headers' => $requestHeaders];
+            } else {
+                $configuration = [];
             }
 
-            if (isset($report)) {
-                if (!$followLocationSucceeded && $curlInfo['http_code'] >= 300 && $curlInfo['http_code'] < 400) {
-                    $report['http_code'] = $curlInfo['http_code'];
-                    $report['content_type'] = $curlInfo['content_type'];
-                    $report['error'] = CURLE_GOT_NOTHING;
-                    $report['message'] = 'Expected "Location" header but got nothing.';
-                } elseif ($content === false) {
-                    $report['error'] = curl_errno($ch);
-                    $report['message'] = curl_error($ch);
-                } elseif ($includeHeader) {
-                    // Set only for $includeHeader to work exactly like PHP variant
-                    $report['http_code'] = $curlInfo['http_code'];
-                    $report['content_type'] = $curlInfo['content_type'];
-                }
-            }
-            curl_close($ch);
-        } elseif ($includeHeader) {
-            if (isset($report)) {
-                $report['lib'] = 'socket';
-            }
-            $parsedURL = parse_url($url);
-            if (!preg_match('/^https?/', $parsedURL['scheme'])) {
+            try {
                 if (isset($report)) {
-                    $report['error'] = -1;
-                    $report['message'] = 'Reading headers is not allowed for this protocol.';
-                }
-                return false;
-            }
-            $port = (int)$parsedURL['port'];
-            if ($port < 1) {
-                if ($parsedURL['scheme'] == 'http') {
-                    $port = $port > 0 ? $port : 80;
-                    $scheme = '';
-                } else {
-                    $port = $port > 0 ? $port : 443;
-                    $scheme = 'ssl://';
+                    $report['lib'] = 'GuzzleHttp';
                 }
-            }
-            $errno = 0;
-            $fp = @fsockopen(($scheme . $parsedURL['host']), $port, $errno, $errstr, 2.0);
-            if (!$fp || $errno > 0) {
+                $response = $requestFactory->request($url, 'GET', $configuration);
+            } catch (RequestException $exception) {
                 if (isset($report)) {
-                    $report['error'] = $errno ?: -1;
-                    $report['message'] = $errno ? ($errstr ?: 'Socket error.') : 'Socket initialization error.';
+                    $report['error'] = $exception->getHandlerContext()['errno'];
+                    $report['message'] = $exception->getMessage();
+                    $report['exception'] = $exception;
                 }
                 return false;
             }
-            $method = $includeHeader == 2 ? 'HEAD' : 'GET';
-            $msg = $method . ' ' . (isset($parsedURL['path']) ? $parsedURL['path'] : '/')
-                   . ($parsedURL['query'] ? '?' . $parsedURL['query'] : '') . ' HTTP/1.0' . CRLF
-                   . 'Host: ' . $parsedURL['host'] . CRLF
-                   . 'Connection: close' . CRLF;
-            if (is_array($requestHeaders)) {
-                $msg .= implode(CRLF, $requestHeaders) . CRLF;
-            }
-            $msg .= CRLF;
-            fputs($fp, $msg);
-            while (!feof($fp)) {
-                $line = fgets($fp, 2048);
-                if (isset($report)) {
-                    if (preg_match('|^HTTP/\\d\\.\\d +(\\d+)|', $line, $status)) {
-                        $report['http_code'] = $status[1];
-                    } elseif (preg_match('/^Content-Type: *(.*)/i', $line, $type)) {
-                        $report['content_type'] = $type[1];
-                    }
+
+            $content = '';
+
+            // Add the headers to the output
+            $includeHeader = (int)$includeHeader;
+            if ($includeHeader) {
+                $parsedURL = parse_url($url);
+                $method = $includeHeader === 2 ? 'HEAD' : 'GET';
+                $content = $method . ' ' . (isset($parsedURL['path']) ? $parsedURL['path'] : '/')
+                    . ($parsedURL['query'] ? '?' . $parsedURL['query'] : '') . ' HTTP/1.0' . CRLF
+                    . 'Host: ' . $parsedURL['host'] . CRLF
+                    . 'Connection: close' . CRLF;
+                if (is_array($requestHeaders)) {
+                    $content .= implode(CRLF, $requestHeaders) . CRLF;
                 }
-                $content .= $line;
-                if (trim($line) === '') {
-                    // Stop at the first empty line (= end of header)
-                    break;
+                foreach ($response->getHeaders() as $headerName => $headerValues) {
+                    $content .= $headerName . ': ' . implode(', ', $headerValues) . CRLF;
                 }
+                // Headers are separated from the body with two CRLFs
+                $content .= CRLF;
             }
-            if ($includeHeader != 2) {
-                $content .= stream_get_contents($fp);
+            // If not just headers are requested, add the body
+            if ($includeHeader !== 2) {
+                $content .= $response->getBody()->getContents();
             }
-            fclose($fp);
-        } elseif (is_array($requestHeaders)) {
             if (isset($report)) {
-                $report['lib'] = 'file/context';
-            }
-            $parsedURL = parse_url($url);
-            if (!preg_match('/^https?/', $parsedURL['scheme'])) {
-                if (isset($report)) {
-                    $report['error'] = -1;
-                    $report['message'] = 'Sending request headers is not allowed for this protocol.';
+                $report['lib'] = 'http';
+                if ($response->getStatusCode() >= 300 && $response->getStatusCode() < 400) {
+                    $report['http_code'] = $response->getStatusCode();
+                    $report['content_type'] = $response->getHeader('Content-Type');
+                    $report['error'] = $response->getStatusCode();
+                    $report['message'] = $response->getReasonPhrase();
+                } elseif (!empty($content)) {
+                    $report['error'] = $response->getStatusCode();
+                    $report['message'] = $response->getReasonPhrase();
+                } elseif ($includeHeader) {
+                    // Set only for $includeHeader to work exactly like PHP variant
+                    $report['http_code'] = $response->getStatusCode();
+                    $report['content_type'] = $response->getHeader('Content-Type');
                 }
-                return false;
-            }
-            $ctx = stream_context_get_default(array(
-                'http' => array(
-                    'header' => implode(CRLF, $requestHeaders)
-                )
-            ));
-            $content = @file_get_contents($url, false, $ctx);
-            if ($content === false && isset($report)) {
-                $report['error'] = -1;
-                $report['message'] = 'Couldn\'t get URL: ' . (isset($http_response_header) ? implode(LF, $http_response_header) : $url);
             }
         } else {
             if (isset($report)) {
@@ -2273,54 +1851,13 @@ class GeneralUtility
             $content = @file_get_contents($url);
             if ($content === false && isset($report)) {
                 $report['error'] = -1;
-                $report['message'] = 'Couldn\'t get URL: ' . (isset($http_response_header) ? implode(LF, $http_response_header) : $url);
+                $report['message'] = 'Couldn\'t get URL: ' . $url;
             }
         }
         return $content;
     }
 
     /**
-     * Parses HTTP headers and returns the content of the "Location" header
-     * or the empty string if no such header found.
-     *
-     * @param string $content
-     * @return string
-     */
-    protected static function getRedirectUrlFromHttpHeaders($content)
-    {
-        $result = '';
-        $headers = explode("\r\n", $content);
-        foreach ($headers as $header) {
-            if ($header == '') {
-                break;
-            }
-            if (preg_match('/^\s*Location\s*:/i', $header)) {
-                list(, $result) = self::trimExplode(':', $header, false, 2);
-                if ($result) {
-                    $result = self::locationHeaderUrl($result);
-                }
-                break;
-            }
-        }
-        return $result;
-    }
-
-    /**
-     * Strips HTTP headers from the content.
-     *
-     * @param string $content
-     * @return string
-     */
-    protected static function stripHttpHeaders($content)
-    {
-        $headersEndPos = strpos($content, "\r\n\r\n");
-        if ($headersEndPos) {
-            $content = substr($content, $headersEndPos + 4);
-        }
-        return $content;
-    }
-
-    /**
      * Writes $content to the file $file
      *
      * @param string $file Filepath to write to
@@ -2394,20 +1931,22 @@ class GeneralUtility
             // Call recursive if recursive flag if set and $path is directory
             if ($recursive && @is_dir($path)) {
                 $handle = opendir($path);
-                while (($file = readdir($handle)) !== false) {
-                    $recursionResult = null;
-                    if ($file !== '.' && $file !== '..') {
-                        if (@is_file(($path . '/' . $file))) {
-                            $recursionResult = static::fixPermissions($path . '/' . $file);
-                        } elseif (@is_dir(($path . '/' . $file))) {
-                            $recursionResult = static::fixPermissions($path . '/' . $file, true);
-                        }
-                        if (isset($recursionResult) && !$recursionResult) {
-                            $result = false;
+                if (is_resource($handle)) {
+                    while (($file = readdir($handle)) !== false) {
+                        $recursionResult = null;
+                        if ($file !== '.' && $file !== '..') {
+                            if (@is_file(($path . '/' . $file))) {
+                                $recursionResult = static::fixPermissions($path . '/' . $file);
+                            } elseif (@is_dir(($path . '/' . $file))) {
+                                $recursionResult = static::fixPermissions($path . '/' . $file, true);
+                            }
+                            if (isset($recursionResult) && !$recursionResult) {
+                                $result = false;
+                            }
                         }
                     }
+                    closedir($handle);
                 }
-                closedir($handle);
             }
         }
         return $result;
@@ -2423,10 +1962,6 @@ class GeneralUtility
      */
     public static function writeFileToTypo3tempDir($filepath, $content)
     {
-        if (!defined('PATH_site')) {
-            return 'PATH_site constant was NOT defined!';
-        }
-
         // Parse filepath into directory and basename:
         $fI = pathinfo($filepath);
         $fI['dirname'] .= '/';
@@ -2456,13 +1991,13 @@ class GeneralUtility
         }
         // Checking dir-name again (sub-dir might have been created):
         if (@is_dir($dirName)) {
-            if ($filepath == $dirName . $fI['basename']) {
+            if ($filepath === $dirName . $fI['basename']) {
                 static::writeFile($filepath, $content);
                 if (!@is_file($filepath)) {
                     return 'The file was not written to the disk. Please, check that you have write permissions to the typo3temp/ directory.';
                 }
             } else {
-                return 'Calculated filelocation didn\'t match input "' . $filepath . '".';
+                return 'Calculated file location didn\'t match input "' . $filepath . '".';
             }
         } else {
             return '"' . $dirName . '" is not a directory!';
@@ -2493,7 +2028,6 @@ class GeneralUtility
      *
      * @param string $directory Target directory to create. Must a have trailing slash
      * @param string $deepDirectory Directory to create. This second parameter
-     * @return void
      * @throws \InvalidArgumentException If $directory or $deepDirectory are not strings
      * @throws \RuntimeException If directory could not be created
      */
@@ -2563,7 +2097,7 @@ class GeneralUtility
             if (!is_link($path) && is_dir($path)) {
                 if ($removeNonEmpty == true && ($handle = @opendir($path))) {
                     while ($OK && false !== ($file = readdir($handle))) {
-                        if ($file == '.' || $file == '..') {
+                        if ($file === '.' || $file === '..') {
                             continue;
                         }
                         $OK = static::rmdir($path . '/' . $file, $removeNonEmpty);
@@ -2582,6 +2116,10 @@ class GeneralUtility
             clearstatcache();
         } elseif (is_link($path)) {
             $OK = @unlink($path);
+            if (!$OK && TYPO3_OS === 'WIN') {
+                // Try to delete dead folder links on Windows systems
+                $OK = @rmdir($path);
+            }
             clearstatcache();
         }
         return $OK;
@@ -2605,7 +2143,7 @@ class GeneralUtility
             $temporaryDirectory = rtrim($directory, '/') . '.' . StringUtility::getUniqueId('remove') . '/';
             if (rename($directory, $temporaryDirectory)) {
                 if ($flushOpcodeCache) {
-                    GeneralUtility::makeInstance(OpcodeCacheService::class)->clearAllActive($directory);
+                    self::makeInstance(OpcodeCacheService::class)->clearAllActive($directory);
                 }
                 if ($keepOriginalDirectory) {
                     static::mkdir($directory);
@@ -2627,12 +2165,13 @@ class GeneralUtility
      */
     public static function get_dirs($path)
     {
+        $dirs = null;
         if ($path) {
             if (is_dir($path)) {
                 $dir = scandir($path);
-                $dirs = array();
+                $dirs = [];
                 foreach ($dir as $entry) {
-                    if (is_dir($path . '/' . $entry) && $entry != '..' && $entry != '.') {
+                    if (is_dir($path . '/' . $entry) && $entry !== '..' && $entry !== '.') {
                         $dirs[] = $entry;
                     }
                 }
@@ -2660,7 +2199,7 @@ class GeneralUtility
         $excludePattern = (string)$excludePattern;
         $path = rtrim($path, '/');
         if (!@is_dir($path)) {
-            return array();
+            return [];
         }
 
         $rawFileList = scandir($path);
@@ -2670,7 +2209,7 @@ class GeneralUtility
 
         $pathPrefix = $path . '/';
         $extensionList = ',' . $extensionList . ',';
-        $files = array();
+        $files = [];
         foreach ($rawFileList as $entry) {
             $completePathToEntry = $pathPrefix . $entry;
             if (!@is_file($completePathToEntry)) {
@@ -2697,7 +2236,7 @@ class GeneralUtility
         }
 
         $valuePathPrefix = $prependPath ? $pathPrefix : '';
-        $foundFiles = array();
+        $foundFiles = [];
         foreach ($files as $key => $value) {
             // Don't change this ever - extensions may depend on the fact that the hash is an md5 of the path! (import/export extension)
             $foundFiles[md5($pathPrefix . ${$valueName})] = $valuePathPrefix . ${$valueName};
@@ -2762,7 +2301,7 @@ class GeneralUtility
      */
     public static function fixWindowsFilePath($theFile)
     {
-        return str_replace(array('\\', '//'), '/', $theFile);
+        return str_replace(['\\', '//'], '/', $theFile);
     }
 
     /**
@@ -2778,7 +2317,7 @@ class GeneralUtility
             return $pathStr;
         }
         $parts = explode('/', $pathStr);
-        $output = array();
+        $output = [];
         $c = 0;
         foreach ($parts as $part) {
             if ($part === '..') {
@@ -2845,7 +2384,7 @@ class GeneralUtility
      */
     public static function getBytesFromSizeMeasurement($measurement)
     {
-        $bytes = doubleval($measurement);
+        $bytes = (float)$measurement;
         if (stripos($measurement, 'G')) {
             $bytes *= 1024 * 1024 * 1024;
         } elseif (stripos($measurement, 'M')) {
@@ -2857,16 +2396,6 @@ class GeneralUtility
     }
 
     /**
-     * Retrieves the maximum path length that is valid in the current environment.
-     *
-     * @return int The maximum available path length
-     */
-    public static function getMaximumPathLength()
-    {
-        return PHP_MAXPATHLEN;
-    }
-
-    /**
      * Function for static version numbers on files, based on the filemtime
      *
      * This will make the filename automatically change when a file is
@@ -2888,7 +2417,7 @@ class GeneralUtility
         $path = self::resolveBackPath(self::dirname(PATH_thisScript) . '/' . $lookupFile[0]);
 
         $doNothing = false;
-        if (TYPO3_MODE == 'FE') {
+        if (TYPO3_MODE === 'FE') {
             $mode = strtolower($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['versionNumberInFilename']);
             if ($mode === 'embed') {
                 $mode = true;
@@ -2942,7 +2471,7 @@ class GeneralUtility
      * @param array $getParams Array of GET parameters to include
      * @return string
      */
-    public static function linkThisScript(array $getParams = array())
+    public static function linkThisScript(array $getParams = [])
     {
         $parts = self::getIndpEnv('SCRIPT_NAME');
         $params = self::_GET();
@@ -2965,10 +2494,10 @@ class GeneralUtility
      * @param array $getParams Array of key/value pairs for get parameters to add/overrule with. Can be multidimensional.
      * @return string Output URL with added getParams.
      */
-    public static function linkThisUrl($url, array $getParams = array())
+    public static function linkThisUrl($url, array $getParams = [])
     {
         $parts = parse_url($url);
-        $getP = array();
+        $getP = [];
         if ($parts['query']) {
             parse_str($parts['query'], $getP);
         }
@@ -3158,7 +2687,6 @@ class GeneralUtility
             case 'REMOTE_HOST':
 
             case 'QUERY_STRING':
-                $retVal = '';
                 if (isset($_SERVER[$getEnvName])) {
                     $retVal = $_SERVER[$getEnvName];
                 }
@@ -3171,7 +2699,7 @@ class GeneralUtility
                 $SFN = self::getIndpEnv('SCRIPT_FILENAME');
                 $SN_A = explode('/', strrev(self::getIndpEnv('SCRIPT_NAME')));
                 $SFN_A = explode('/', strrev($SFN));
-                $acc = array();
+                $acc = [];
                 foreach ($SN_A as $kk => $vv) {
                     if ((string)$SFN_A[$kk] === (string)$vv) {
                         $acc[] = $vv;
@@ -3181,9 +2709,8 @@ class GeneralUtility
                 }
                 $commonEnd = strrev(implode('/', $acc));
                 if ((string)$commonEnd !== '') {
-                    $DR = substr($SFN, 0, -(strlen($commonEnd) + 1));
+                    $retVal = substr($SFN, 0, -(strlen($commonEnd) + 1));
                 }
-                $retVal = $DR;
                 break;
             case 'TYPO3_HOST_ONLY':
                 $httpHost = self::getIndpEnv('HTTP_HOST');
@@ -3216,7 +2743,7 @@ class GeneralUtility
                 } elseif (defined('PATH_thisScript') && defined('PATH_site')) {
                     $lPath = PathUtility::stripPathSitePrefix(dirname(PATH_thisScript)) . '/';
                     $siteUrl = substr($url, 0, -strlen($lPath));
-                    if (substr($siteUrl, -1) != '/') {
+                    if (substr($siteUrl, -1) !== '/') {
                         $siteUrl .= '/';
                     }
                     $retVal = $siteUrl;
@@ -3230,7 +2757,7 @@ class GeneralUtility
                 break;
             case 'TYPO3_SSL':
                 $proxySSL = trim($GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxySSL']);
-                if ($proxySSL == '*') {
+                if ($proxySSL === '*') {
                     $proxySSL = $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP'];
                 }
                 if (self::cmpIP($_SERVER['REMOTE_ADDR'], $proxySSL)) {
@@ -3240,9 +2767,9 @@ class GeneralUtility
                 }
                 break;
             case '_ARRAY':
-                $out = array();
+                $out = [];
                 // Here, list ALL possible keys to this function for debug display.
-                $envTestVars = array(
+                $envTestVars = [
                     'HTTP_HOST',
                     'TYPO3_HOST_ONLY',
                     'TYPO3_PORT',
@@ -3265,7 +2792,7 @@ class GeneralUtility
                     'REMOTE_HOST',
                     'HTTP_USER_AGENT',
                     'HTTP_ACCEPT_LANGUAGE'
-                );
+                ];
                 foreach ($envTestVars as $v) {
                     $out[$v] = self::getIndpEnv($v);
                 }
@@ -3349,7 +2876,7 @@ class GeneralUtility
      */
     protected static function isInternalRequestType()
     {
-        return (!defined('TYPO3_REQUESTTYPE') || (defined('TYPO3_REQUESTTYPE') && TYPO3_REQUESTTYPE & (TYPO3_REQUESTTYPE_INSTALL | TYPO3_REQUESTTYPE_CLI)));
+        return !defined('TYPO3_REQUESTTYPE') || (defined('TYPO3_REQUESTTYPE') && TYPO3_REQUESTTYPE & (TYPO3_REQUESTTYPE_INSTALL | TYPO3_REQUESTTYPE_CLI));
     }
 
     /**
@@ -3373,7 +2900,7 @@ class GeneralUtility
         if (!$useragent) {
             $useragent = self::getIndpEnv('HTTP_USER_AGENT');
         }
-        $bInfo = array();
+        $bInfo = [];
         // Which browser?
         if (strpos($useragent, 'Konqueror') !== false) {
             $bInfo['BROWSER'] = 'konqu';
@@ -3390,29 +2917,29 @@ class GeneralUtility
             // Browser version
             switch ($bInfo['BROWSER']) {
                 case 'net':
-                    $bInfo['VERSION'] = doubleval(substr($useragent, 8));
+                    $bInfo['VERSION'] = (float)substr($useragent, 8);
                     if (strpos($useragent, 'Netscape6/') !== false) {
-                        $bInfo['VERSION'] = doubleval(substr(strstr($useragent, 'Netscape6/'), 10));
+                        $bInfo['VERSION'] = (float)substr(strstr($useragent, 'Netscape6/'), 10);
                     }
                     // Will we ever know if this was a typo or intention...?! :-(
                     if (strpos($useragent, 'Netscape/6') !== false) {
-                        $bInfo['VERSION'] = doubleval(substr(strstr($useragent, 'Netscape/6'), 10));
+                        $bInfo['VERSION'] = (float)substr(strstr($useragent, 'Netscape/6'), 10);
                     }
                     if (strpos($useragent, 'Netscape/7') !== false) {
-                        $bInfo['VERSION'] = doubleval(substr(strstr($useragent, 'Netscape/7'), 9));
+                        $bInfo['VERSION'] = (float)substr(strstr($useragent, 'Netscape/7'), 9);
                     }
                     break;
                 case 'msie':
                     $tmp = strstr($useragent, 'MSIE');
-                    $bInfo['VERSION'] = doubleval(preg_replace('/^[^0-9]*/', '', substr($tmp, 4)));
+                    $bInfo['VERSION'] = (float)preg_replace('/^[^0-9]*/', '', substr($tmp, 4));
                     break;
                 case 'opera':
                     $tmp = strstr($useragent, 'Opera');
-                    $bInfo['VERSION'] = doubleval(preg_replace('/^[^0-9]*/', '', substr($tmp, 5)));
+                    $bInfo['VERSION'] = (float)preg_replace('/^[^0-9]*/', '', substr($tmp, 5));
                     break;
                 case 'konqu':
                     $tmp = strstr($useragent, 'Konqueror/');
-                    $bInfo['VERSION'] = doubleval(substr($tmp, 10));
+                    $bInfo['VERSION'] = (float)substr($tmp, 10);
                     break;
             }
             // Client system
@@ -3437,7 +2964,6 @@ class GeneralUtility
     {
         $host = '';
         // If not called from the command-line, resolve on getIndpEnv()
-        // Note that TYPO3_REQUESTTYPE is not used here as it may not yet be defined
         if ($requestHost && !(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI)) {
             $host = self::getIndpEnv('HTTP_HOST');
         }
@@ -3478,22 +3004,13 @@ class GeneralUtility
      * \TYPO3\CMS\Core\Utility\GeneralUtility::validPathStr().
      *
      * @param string $filename The input filename/filepath to evaluate
-     * @param bool $_ - obsolete, will be removed in TYPO3 CMS 9
-     * @param bool $_2 - obsolete, will be removed in TYPO3 CMS 9
      * @return string Returns the absolute filename of $filename if valid, otherwise blank string.
      */
-    public static function getFileAbsFileName($filename, $_ = null, $_2 = null)
+    public static function getFileAbsFileName($filename)
     {
         if ((string)$filename === '') {
             return '';
         }
-        if ($_ !== null) {
-            self::deprecationLog('Parameter 2 of GeneralUtility::getFileAbsFileName is obsolete and can be omitted.');
-        }
-        if ($_2 !== null) {
-            self::deprecationLog('Parameter 3 of GeneralUtility::getFileAbsFileName is obsolete and can be omitted.');
-        }
-
         // Extension
         if (strpos($filename, 'EXT:') === 0) {
             list($extKey, $local) = explode('/', substr($filename, 4), 2);
@@ -3526,12 +3043,11 @@ class GeneralUtility
      * @param string $theFile File path to evaluate
      * @return bool TRUE, $theFile is allowed path string, FALSE otherwise
      * @see http://php.net/manual/en/security.filesystem.nullbytes.php
-     * @todo Possible improvement: Should it rawurldecode the string first to check if any of these characters is encoded?
      */
     public static function validPathStr($theFile)
     {
         return strpos($theFile, '//') === false && strpos($theFile, '\\') === false
-            && !preg_match('#(?:^\\.\\.|/\\.\\./|[[:cntrl:]])#u', $theFile);
+            && preg_match('#(?:^\\.\\.|/\\.\\./|[[:cntrl:]])#u', $theFile) === 0;
     }
 
     /**
@@ -3611,14 +3127,17 @@ class GeneralUtility
      * Checks if a given string is a valid frame URL to be loaded in the
      * backend.
      *
+     * If the given url is empty or considered to be harmless, it is returned
+     * as is, else the event is logged and an empty string is returned.
+     *
      * @param string $url potential URL to check
-     * @return string either $url if $url is considered to be harmless, or an
+     * @return string $url or empty string
      */
     public static function sanitizeLocalUrl($url = '')
     {
         $sanitizedUrl = '';
-        $decodedUrl = rawurldecode($url);
-        if (!empty($url) && self::removeXSS($decodedUrl) === $decodedUrl) {
+        if (!empty($url)) {
+            $decodedUrl = rawurldecode($url);
             $parsedUrl = parse_url($decodedUrl);
             $testAbsoluteUrl = self::resolveBackPath($decodedUrl);
             $testRelativeUrl = self::resolveBackPath(self::dirname(self::getIndpEnv('SCRIPT_NAME')) . '/' . $decodedUrl);
@@ -3631,7 +3150,9 @@ class GeneralUtility
                 $sanitizedUrl = $url;
             } elseif (strpos($testAbsoluteUrl, self::getIndpEnv('TYPO3_SITE_PATH')) === 0 && $decodedUrl[0] === '/') {
                 $sanitizedUrl = $url;
-            } elseif (empty($parsedUrl['scheme']) && strpos($testRelativeUrl, self::getIndpEnv('TYPO3_SITE_PATH')) === 0 && $decodedUrl[0] !== '/') {
+            } elseif (empty($parsedUrl['scheme']) && strpos($testRelativeUrl, self::getIndpEnv('TYPO3_SITE_PATH')) === 0
+                && $decodedUrl[0] !== '/' && strpbrk($decodedUrl, '*:|"<>') === false && strpos($decodedUrl, '\\\\') === false
+            ) {
                 $sanitizedUrl = $url;
             }
         }
@@ -3651,18 +3172,19 @@ class GeneralUtility
      */
     public static function upload_copy_move($source, $destination)
     {
+        $result = false;
         if (is_uploaded_file($source)) {
-            $uploaded = true;
-            // Return the value of move_uploaded_file, and if FALSE the temporary $source is still around so the user can use unlink to delete it:
-            $uploadedResult = move_uploaded_file($source, $destination);
+            // Return the value of move_uploaded_file, and if FALSE the temporary $source is still
+            // around so the user can use unlink to delete it:
+            $result = move_uploaded_file($source, $destination);
         } else {
-            $uploaded = false;
             @copy($source, $destination);
         }
         // Change the permissions of the file
         self::fixPermissions($destination);
-        // If here the file is copied and the temporary $source is still around, so when returning FALSE the user can try unlink to delete the $source
-        return $uploaded ? $uploadedResult : false;
+        // If here the file is copied and the temporary $source is still around,
+        // so when returning FALSE the user can try unlink to delete the $source
+        return $result;
     }
 
     /**
@@ -3721,8 +3243,11 @@ class GeneralUtility
     public static function tempnam($filePrefix, $fileSuffix = '')
     {
         $temporaryPath = PATH_site . 'typo3temp/var/transient/';
+        if (!is_dir($temporaryPath)) {
+            self::mkdir_deep($temporaryPath);
+        }
         if ($fileSuffix === '') {
-            $tempFileName = static::fixWindowsFilePath(tempnam($temporaryPath, $filePrefix));
+            $tempFileName = $temporaryPath . basename(tempnam($temporaryPath, $filePrefix));
         } else {
             do {
                 $tempFileName = $temporaryPath . $filePrefix . mt_rand(1, PHP_INT_MAX) . $fileSuffix;
@@ -3744,7 +3269,7 @@ class GeneralUtility
     public static function stdAuthCode($uid_or_record, $fields = '', $codeLength = 8)
     {
         if (is_array($uid_or_record)) {
-            $recCopy_temp = array();
+            $recCopy_temp = [];
             if ($fields) {
                 $fieldArr = self::trimExplode(',', $fields, true);
                 foreach ($fieldArr as $k => $v) {
@@ -3835,138 +3360,36 @@ class GeneralUtility
     }
 
     /**
-     * Looks for a sheet-definition in the input data structure array. If found it will return the data structure for the sheet given as $sheet (if found).
-     * If the sheet definition is in an external file that file is parsed and the data structure inside of that is returned.
-     *
-     * @param array $dataStructArray Input data structure, possibly with a sheet-definition and references to external data source files.
-     * @param string $sheet The sheet to return, preferably.
-     * @return array An array with two num. keys: key0: The data structure is returned in this key (array) UNLESS an error occurred in which case an error string is returned (string). key1: The used sheet key value!
-     */
-    public static function resolveSheetDefInDS($dataStructArray, $sheet = 'sDEF')
-    {
-        if (!is_array($dataStructArray)) {
-            return 'Data structure must be an array';
-        }
-        if (is_array($dataStructArray['sheets'])) {
-            $singleSheet = false;
-            if (!isset($dataStructArray['sheets'][$sheet])) {
-                $sheet = 'sDEF';
-            }
-            $dataStruct = $dataStructArray['sheets'][$sheet];
-            // If not an array, but still set, then regard it as a relative reference to a file:
-            if ($dataStruct && !is_array($dataStruct)) {
-                $file = self::getFileAbsFileName($dataStruct);
-                if ($file && @is_file($file)) {
-                    $dataStruct = self::xml2array(self::getUrl($file));
-                }
-            }
-        } else {
-            $singleSheet = true;
-            $dataStruct = $dataStructArray;
-            if (isset($dataStruct['meta'])) {
-                unset($dataStruct['meta']);
-            }
-            // Meta data should not appear there.
-            // Default sheet
-            $sheet = 'sDEF';
-        }
-        return array($dataStruct, $sheet, $singleSheet);
-    }
-
-    /**
-     * Resolves ALL sheet definitions in dataStructArray
-     * If no sheet is found, then the default "sDEF" will be created with the dataStructure inside.
-     *
-     * @param array $dataStructArray Input data structure, possibly with a sheet-definition and references to external data source files.
-     * @return array Output data structure with all sheets resolved as arrays.
-     */
-    public static function resolveAllSheetsInDS(array $dataStructArray)
-    {
-        if (is_array($dataStructArray['sheets'])) {
-            $out = array('sheets' => array());
-            foreach ($dataStructArray['sheets'] as $sheetId => $sDat) {
-                list($ds, $aS) = self::resolveSheetDefInDS($dataStructArray, $sheetId);
-                if ($sheetId == $aS) {
-                    $out['sheets'][$aS] = $ds;
-                }
-            }
-        } else {
-            list($ds) = self::resolveSheetDefInDS($dataStructArray);
-            $out = array('sheets' => array('sDEF' => $ds));
-        }
-        return $out;
-    }
-
-    /**
      * Calls a user-defined function/method in class
      * Such a function/method should look like this: "function proc(&$params, &$ref) {...}"
      *
-     * @param string $funcName Function/Method reference or Closure, '[file-reference":"]["&"]class/function["->"method-name]'. You can prefix this reference with "[file-reference]:" and \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName() will then be used to resolve the filename and subsequently include it by "require_once()" which means you don't have to worry about including the class file either! Example: "EXT:realurl/class.tx_realurl.php:&tx_realurl->encodeSpURL". Finally; you can prefix the class name with "&" if you want to reuse a former instance of the same object call ("singleton").
+     * @param string $funcName Function/Method reference or Closure.
      * @param mixed $params Parameters to be pass along (typically an array) (REFERENCE!)
      * @param mixed $ref Reference to be passed along (typically "$this" - being a reference to the calling object) (REFERENCE!)
-     * @param string $checkPrefix Not used anymore since 6.0
+     * @param string $_ Not used anymore since 6.0
      * @param int $errorMode Error mode (when class/function could not be found): 0 - call debug(), 1 - do nothing, 2 - raise an exception (allows to call a user function that may return FALSE)
      * @return mixed Content from method/function call or FALSE if the class/method/function was not found
-     * @see getUserObj()
+     * @see makeInstance()
      */
-    public static function callUserFunction($funcName, &$params, &$ref, $checkPrefix = '', $errorMode = 0)
+    public static function callUserFunction($funcName, &$params, &$ref, $_ = '', $errorMode = 0)
     {
         $content = false;
         // Check if we're using a closure and invoke it directly.
         if (is_object($funcName) && is_a($funcName, 'Closure')) {
-            return call_user_func_array($funcName, array(&$params, &$ref));
-        }
-        // Check persistent object and if found, call directly and exit.
-        if (isset($GLOBALS['T3_VAR']['callUserFunction'][$funcName]) && is_array($GLOBALS['T3_VAR']['callUserFunction'][$funcName])) {
-            return call_user_func_array(array(
-                &$GLOBALS['T3_VAR']['callUserFunction'][$funcName]['obj'],
-                $GLOBALS['T3_VAR']['callUserFunction'][$funcName]['method']
-            ), array(&$params, &$ref));
-        }
-        // Check file-reference prefix; if found, require_once() the file (should be library of code)
-        if (strpos($funcName, ':') !== false) {
-            list($file, $funcRef) = self::revExplode(':', $funcName, 2);
-            $requireFile = self::getFileAbsFileName($file);
-            if ($requireFile) {
-                require_once $requireFile;
-            }
-        } else {
-            $funcRef = $funcName;
-        }
-        // Check for persistent object token, "&"
-        if ($funcRef[0] === '&') {
-            $funcRef = substr($funcRef, 1);
-            $storePersistentObject = true;
-        } else {
-            $storePersistentObject = false;
+            return call_user_func_array($funcName, [&$params, &$ref]);
         }
-        // Call function or method:
-        $parts = explode('->', $funcRef);
+        $funcName = trim($funcName);
+        $parts = explode('->', $funcName);
+        // Call function or method
         if (count($parts) === 2) {
             // Class
             // Check if class/method exists:
             if (class_exists($parts[0])) {
-                // Get/Create object of class:
-                if ($storePersistentObject) {
-                    // Get reference to current instance of class:
-                    if (!is_object($GLOBALS['T3_VAR']['callUserFunction_classPool'][$parts[0]])) {
-                        $GLOBALS['T3_VAR']['callUserFunction_classPool'][$parts[0]] = self::makeInstance($parts[0]);
-                    }
-                    $classObj = $GLOBALS['T3_VAR']['callUserFunction_classPool'][$parts[0]];
-                } else {
-                    // Create new object:
-                    $classObj = self::makeInstance($parts[0]);
-                }
+                // Create object
+                $classObj = self::makeInstance($parts[0]);
                 if (method_exists($classObj, $parts[1])) {
-                    // If persistent object should be created, set reference:
-                    if ($storePersistentObject) {
-                        $GLOBALS['T3_VAR']['callUserFunction'][$funcName] = array(
-                            'method' => $parts[1],
-                            'obj' => &$classObj
-                        );
-                    }
                     // Call method:
-                    $content = call_user_func_array(array(&$classObj, $parts[1]), array(&$params, &$ref));
+                    $content = call_user_func_array([&$classObj, $parts[1]], [&$params, &$ref]);
                 } else {
                     $errorMsg = 'No method name \'' . $parts[1] . '\' in class ' . $parts[0];
                     if ($errorMode == 2) {
@@ -3985,10 +3408,10 @@ class GeneralUtility
             }
         } else {
             // Function
-            if (function_exists($funcRef)) {
-                $content = call_user_func_array($funcRef, array(&$params, &$ref));
+            if (function_exists($funcName)) {
+                $content = call_user_func_array($funcName, [&$params, &$ref]);
             } else {
-                $errorMsg = 'No function named: ' . $funcRef;
+                $errorMsg = 'No function named: ' . $funcName;
                 if ($errorMode == 2) {
                     throw new \InvalidArgumentException($errorMsg, 1294585867);
                 } elseif (!$errorMode) {
@@ -4000,43 +3423,23 @@ class GeneralUtility
     }
 
     /**
+     * This method should be avoided, as it will be deprecated completely in TYPO3 v9, and will be removed in TYPO3 v10.
+     * Instead use makeInstance() directly.
+     *
      * Creates and returns reference to a user defined object.
      * This function can return an object reference if you like.
-     * Just prefix the function call with "&": "$objRef = &\TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj('EXT:myext/class.tx_myext_myclass.php:&tx_myext_myclass');".
-     * This will work ONLY if you prefix the class name with "&" as well. See description of function arguments.
      *
-     * @todo Deprecate the whole method in several steps:
-     *      1. Deprecated singleton pattern (was removed in TYPO3 CMS 8)
-     *      2. Deprecate file prefix/ require file,
-     *      3. Deprecate usage without valid class name.
-     *      4. The last step should be to deprecate the method itself.
-     *
-     * @param string $classRef Class reference, '[file-reference":"]["&"]class-name'. You can prefix the class name with "[file-reference]:" and \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName() will then be used to resolve the filename and subsequently include it by "require_once()" which means you don't have to worry about including the class file either! Example: "EXT:realurl/class.tx_realurl.php:&tx_realurl". Finally; for the class name you can prefix it with "&" and you will reuse the previous instance of the object identified by the full reference string (meaning; if you ask for the same $classRef later in another place in the code you will get a reference to the first created one!).
-     * @return object The instance of the class asked for. Instance is created with \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance
+     * @param string $className Class name
+     * @return object The instance of the class asked for. Instance is created with GeneralUtility::makeInstance
      * @see callUserFunction()
+     * @deprecated since TYPO3 v9, will be removed in TYPO3 v10, use makeInstance instead.
      */
-    public static function getUserObj($classRef)
+    public static function getUserObj($className)
     {
-        // Check persistent object and if found, call directly and exit.
-        if (is_object($GLOBALS['T3_VAR']['getUserObj'][$classRef])) {
-            return $GLOBALS['T3_VAR']['getUserObj'][$classRef];
-        } else {
-            // Check file-reference prefix; if found, require_once() the file (should be library of code)
-            if (strpos($classRef, ':') !== false) {
-                list($file, $class) = self::revExplode(':', $classRef, 2);
-                $requireFile = self::getFileAbsFileName($file);
-                if ($requireFile) {
-                    require_once $requireFile;
-                }
-            } else {
-                $class = $classRef;
-            }
-
-            // Check if class exists:
-            if (class_exists($class)) {
-                $classObj = self::makeInstance($class);
-                return $classObj;
-            }
+        self::logDeprecatedFunction();
+        // Check if class exists:
+        if (class_exists($className)) {
+            return self::makeInstance($className);
         }
     }
 
@@ -4055,12 +3458,11 @@ class GeneralUtility
      * the instance of a specific class.
      *
      * @param string $className name of the class to instantiate, must not be empty and not start with a backslash
-     *
+     * @param array<int, mixed> $constructorArguments Arguments for the constructor
      * @return object the created instance
-     *
      * @throws \InvalidArgumentException if $className is empty or starts with a backslash
      */
-    public static function makeInstance($className)
+    public static function makeInstance($className, ...$constructorArguments)
     {
         if (!is_string($className) || empty($className)) {
             throw new \InvalidArgumentException('$className must be a non empty string.', 1288965219);
@@ -4089,7 +3491,7 @@ class GeneralUtility
             return array_shift(self::$nonSingletonInstances[$finalClassName]);
         }
         // Create new instance and call constructor with parameters
-        $instance = static::instantiateClass($finalClassName, func_get_args());
+        $instance = new $finalClassName(...$constructorArguments);
         // Register new singleton instance
         if ($instance instanceof SingletonInterface) {
             self::$singletonInstances[$finalClassName] = $instance;
@@ -4098,54 +3500,6 @@ class GeneralUtility
     }
 
     /**
-     * Speed optimized alternative to ReflectionClass::newInstanceArgs()
-     *
-     * @param string $className Name of the class to instantiate
-     * @param array $arguments Arguments passed to self::makeInstance() thus the first one with index 0 holds the requested class name
-     * @return mixed
-     */
-    protected static function instantiateClass($className, $arguments)
-    {
-        switch (count($arguments)) {
-            case 1:
-                $instance = new $className();
-                break;
-            case 2:
-                $instance = new $className($arguments[1]);
-                break;
-            case 3:
-                $instance = new $className($arguments[1], $arguments[2]);
-                break;
-            case 4:
-                $instance = new $className($arguments[1], $arguments[2], $arguments[3]);
-                break;
-            case 5:
-                $instance = new $className($arguments[1], $arguments[2], $arguments[3], $arguments[4]);
-                break;
-            case 6:
-                $instance = new $className($arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5]);
-                break;
-            case 7:
-                $instance = new $className($arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6]);
-                break;
-            case 8:
-                $instance = new $className($arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6], $arguments[7]);
-                break;
-            case 9:
-                $instance = new $className($arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6], $arguments[7], $arguments[8]);
-                break;
-            default:
-                // The default case for classes with constructors that have more than 8 arguments.
-                // This will fail when one of the arguments shall be passed by reference.
-                // In case we really need to support this edge case, we can implement the solution from here: https://review.typo3.org/26344
-                $class = new \ReflectionClass($className);
-                array_shift($arguments);
-                $instance = $class->newInstanceArgs($arguments);
-        }
-        return $instance;
-    }
-
-    /**
      * Returns the class name for a new instance, taking into account
      * registered implementations for this class
      *
@@ -4206,7 +3560,6 @@ class GeneralUtility
      * @see makeInstance
      * @param string $className
      * @param \TYPO3\CMS\Core\SingletonInterface $instance
-     * @return void
      * @internal
      */
     public static function setSingletonInstance($className, SingletonInterface $instance)
@@ -4228,7 +3581,6 @@ class GeneralUtility
      * @throws \InvalidArgumentException
      * @param string $className
      * @param \TYPO3\CMS\Core\SingletonInterface $instance
-     * @return void
      * @internal
      */
     public static function removeSingletonInstance($className, SingletonInterface $instance)
@@ -4255,11 +3607,10 @@ class GeneralUtility
      *
      * @internal
      * @param array $newSingletonInstances $className => $object
-     * @return void
      */
     public static function resetSingletonInstances(array $newSingletonInstances)
     {
-        static::$singletonInstances = array();
+        static::$singletonInstances = [];
         foreach ($newSingletonInstances as $className => $instance) {
             static::setSingletonInstance($className, $instance);
         }
@@ -4295,7 +3646,6 @@ class GeneralUtility
      * @throws \InvalidArgumentException if class extends \TYPO3\CMS\Core\SingletonInterface
      * @param string $className
      * @param object $instance
-     * @return void
      */
     public static function addInstance($className, $instance)
     {
@@ -4304,7 +3654,7 @@ class GeneralUtility
             throw new \InvalidArgumentException('$instance must not be an instance of TYPO3\\CMS\\Core\\SingletonInterface. ' . 'For setting singletons, please use setSingletonInstance.', 1288969325);
         }
         if (!isset(self::$nonSingletonInstances[$className])) {
-            self::$nonSingletonInstances[$className] = array();
+            self::$nonSingletonInstances[$className] = [];
         }
         self::$nonSingletonInstances[$className][] = $instance;
     }
@@ -4316,7 +3666,6 @@ class GeneralUtility
      * @throws \InvalidArgumentException if $className is empty or if $instance is no instance of $className
      * @param string $className a class name
      * @param object $instance an object
-     * @return void
      */
     protected static function checkInstanceClassName($className, $instance)
     {
@@ -4337,12 +3686,11 @@ class GeneralUtility
      * Warning: This is a helper method for unit tests. Do not call this directly in production code!
      *
      * @see makeInstance
-     * @return void
      */
     public static function purgeInstances()
     {
-        self::$singletonInstances = array();
-        self::$nonSingletonInstances = array();
+        self::$singletonInstances = [];
+        self::$nonSingletonInstances = [];
     }
 
     /**
@@ -4350,7 +3698,6 @@ class GeneralUtility
      *
      * Used in unit tests only.
      *
-     * @return void
      * @internal
      */
     public static function flushInternalRuntimeCaches()
@@ -4368,17 +3715,17 @@ class GeneralUtility
      * @param mixed $excludeServiceKeys List of service keys which should be excluded in the search for a service. Array or comma list.
      * @return object|string[] The service object or an array with error infos.
      */
-    public static function makeInstanceService($serviceType, $serviceSubType = '', $excludeServiceKeys = array())
+    public static function makeInstanceService($serviceType, $serviceSubType = '', $excludeServiceKeys = [])
     {
         $error = false;
         if (!is_array($excludeServiceKeys)) {
             $excludeServiceKeys = self::trimExplode(',', $excludeServiceKeys, true);
         }
-        $requestInfo = array(
+        $requestInfo = [
             'requestedServiceType' => $serviceType,
             'requestedServiceSubType' => $serviceSubType,
             'requestedExcludeServiceKeys' => $excludeServiceKeys
-        );
+        ];
         while ($info = ExtensionManagementUtility::findService($serviceType, $serviceSubType, $excludeServiceKeys)) {
             // provide information about requested service to service object
             $info = array_merge($info, $requestInfo);
@@ -4392,7 +3739,7 @@ class GeneralUtility
             } else {
                 $obj = self::makeInstance($info['className']);
                 if (is_object($obj)) {
-                    if (!@is_callable(array($obj, 'init'))) {
+                    if (!@is_callable([$obj, 'init'])) {
                         // use silent logging??? I don't think so.
                         die('Broken service:' . DebugUtility::viewArray($info));
                     }
@@ -4414,39 +3761,6 @@ class GeneralUtility
     }
 
     /**
-     * Require a class for TYPO3
-     * Useful to require classes from inside other classes (not global scope). A limited set of global variables are available (see function)
-     *
-     * @param string $requireFile: Path of the file to be included
-     * @return void
-     * @deprecated since TYPO3 CMS 8, this file will be removed in TYPO3 CMS 9
-     */
-    public static function requireOnce($requireFile)
-    {
-        self::logDeprecatedFunction();
-        // Needed for require_once
-        global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;
-        require_once $requireFile;
-    }
-
-    /**
-     * Requires a class for TYPO3
-     * Useful to require classes from inside other classes (not global scope).
-     * A limited set of global variables are available (see function)
-     *
-     * @param string $requireFile: Path of the file to be included
-     * @return void
-     * @deprecated since TYPO3 CMS 8, this file will be removed in TYPO3 CMS 9
-     */
-    public static function requireFile($requireFile)
-    {
-        self::logDeprecatedFunction();
-        // Needed for require
-        global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;
-        require $requireFile;
-    }
-
-    /**
      * Create a shortened "redirect" URL with specified length from an incoming URL
      *
      * @param string $inUrl Input URL
@@ -4458,53 +3772,44 @@ class GeneralUtility
     {
         if (strlen($inUrl) > $l) {
             $md5 = substr(md5($inUrl), 0, 20);
-            $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', 'cache_md5params', 'md5hash=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($md5, 'cache_md5params'));
+            $connection = self::makeInstance(ConnectionPool::class)->getConnectionForTable('cache_md5params');
+            $count = $connection->count(
+                '*',
+                'cache_md5params',
+                ['md5hash' => $md5]
+            );
             if (!$count) {
-                $insertFields = array(
-                    'md5hash' => $md5,
-                    'tstamp' => $GLOBALS['EXEC_TIME'],
-                    'type' => 2,
-                    'params' => $inUrl
+                $connection->insert(
+                    'cache_md5params',
+                    [
+                        'md5hash' => $md5,
+                        'tstamp'  => $GLOBALS['EXEC_TIME'],
+                        'type'    => 2,
+                        'params'  => $inUrl
+                    ]
                 );
-                $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_md5params', $insertFields);
             }
-            $inUrl = ($index_script_url ? $index_script_url : self::getIndpEnv('TYPO3_REQUEST_DIR') . 'index.php') . '?RDCT=' . $md5;
+            $inUrl = ($index_script_url ?: self::getIndpEnv('TYPO3_REQUEST_DIR') . 'index.php') . '?RDCT=' . $md5;
         }
         return $inUrl;
     }
 
     /**
-     * Function to compensate for DPI resolution.
-     *
-     * @param float $fontSize font size for freetype function call
-     *
-     * @return float compensated font size based on 96 dpi
-     */
-    public static function freetypeDpiComp($fontSize)
-    {
-        // FreeType 2 always has 96 dpi.
-        $dpi = 96.0;
-        return $fontSize / $dpi * 72;
-    }
-
-    /**
      * Initialize the system log.
      *
-     * @return void
      * @see sysLog()
      */
     public static function initSysLog()
     {
         // For CLI logging name is <fqdn-hostname>:<TYPO3-path>
-        // Note that TYPO3_REQUESTTYPE is not used here as it may not yet be defined
         if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) {
-            $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'] = self::getHostname(($requestHost = false)) . ':' . PATH_site;
+            $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'] = self::getHostname() . ':' . PATH_site;
         } else {
             $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'] = self::getIndpEnv('TYPO3_SITE_URL');
         }
         // Init custom logging
         if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'])) {
-            $params = array('initLog' => true);
+            $params = ['initLog' => true];
             $fakeThis = false;
             foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'] as $hookMethod) {
                 self::callUserFunction($hookMethod, $params, $fakeThis);
@@ -4513,8 +3818,8 @@ class GeneralUtility
         // Init TYPO3 logging
         foreach (explode(';', $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLog'], 2) as $log) {
             list($type, $destination) = explode(',', $log, 3);
-            if ($type == 'syslog') {
-                if (TYPO3_OS == 'WIN') {
+            if ($type === 'syslog') {
+                if (TYPO3_OS === 'WIN') {
                     $facility = LOG_USER;
                 } else {
                     $facility = constant('LOG_' . strtoupper($destination));
@@ -4535,7 +3840,6 @@ class GeneralUtility
      * @param string $msg Message (in English).
      * @param string $extKey Extension key (from which extension you are calling the log) or "Core
      * @param int $severity \TYPO3\CMS\Core\Utility\GeneralUtility::SYSLOG_SEVERITY_* constant
-     * @return void
      */
     public static function sysLog($msg, $extKey, $severity = 0)
     {
@@ -4550,7 +3854,7 @@ class GeneralUtility
         }
         // Do custom logging
         if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog']) && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'])) {
-            $params = array('msg' => $msg, 'extKey' => $extKey, 'backTrace' => debug_backtrace(), 'severity' => $severity);
+            $params = ['msg' => $msg, 'extKey' => $extKey, 'backTrace' => debug_backtrace(), 'severity' => $severity];
             $fakeThis = false;
             foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'] as $hookMethod) {
                 self::callUserFunction($hookMethod, $params, $fakeThis);
@@ -4571,14 +3875,14 @@ class GeneralUtility
             }
             $msgLine = ' - ' . $extKey . ': ' . $msg;
             // Write message to a file
-            if ($type == 'file') {
+            if ($type === 'file') {
                 $file = fopen($destination, 'a');
                 if ($file) {
                     fwrite($file, date(($dateFormat . ' ' . $timeFormat)) . $msgLine . LF);
                     fclose($file);
                     self::fixPermissions($destination);
                 }
-            } elseif ($type == 'mail') {
+            } elseif ($type === 'mail') {
                 list($to, $from) = explode('/', $destination);
                 if (!self::validEmail($from)) {
                     $from = MailUtility::getSystemFrom();
@@ -4587,10 +3891,10 @@ class GeneralUtility
                 $mail = self::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class);
                 $mail->setTo($to)->setFrom($from)->setSubject('Warning - error in TYPO3 installation')->setBody('Host: ' . $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'] . LF . 'Extension: ' . $extKey . LF . 'Severity: ' . $severity . LF . LF . $msg);
                 $mail->send();
-            } elseif ($type == 'error_log') {
+            } elseif ($type === 'error_log') {
                 error_log($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'] . $msgLine, 0);
-            } elseif ($type == 'syslog') {
-                $priority = array(LOG_INFO, LOG_NOTICE, LOG_WARNING, LOG_ERR, LOG_CRIT);
+            } elseif ($type === 'syslog') {
+                $priority = [LOG_INFO, LOG_NOTICE, LOG_WARNING, LOG_ERR, LOG_CRIT];
                 syslog($priority[(int)$severity], $msgLine);
             }
         }
@@ -4601,19 +3905,18 @@ class GeneralUtility
      * This should be implemented around the source code, both frontend and backend, logging everything from the flow through an application, messages, results from comparisons to fatal errors.
      * The result is meant to make sense to developers during development or debugging of a site.
      * The idea is that this function is only a wrapper for external extensions which can set a hook which will be allowed to handle the logging of the information to any format they might wish and with any kind of filter they would like.
-     * If you want to implement the devLog in your applications, simply add lines like:
-     * if (TYPO3_DLOG) \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[write message in english here]', 'extension key');
+     * If you want to implement the devLog in your applications, simply add a line like:
+     * \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('[write message in english here]', 'extension key');
      *
      * @param string $msg Message (in english).
      * @param string $extKey Extension key (from which extension you are calling the log)
      * @param int $severity Severity: 0 is info, 1 is notice, 2 is warning, 3 is fatal error, -1 is "OK" message
      * @param mixed $dataVar Additional data you want to pass to the logger.
-     * @return void
      */
     public static function devLog($msg, $extKey, $severity = 0, $dataVar = false)
     {
-        if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['devLog'])) {
-            $params = array('msg' => $msg, 'extKey' => $extKey, 'severity' => $severity, 'dataVar' => $dataVar);
+        if ((bool)$GLOBALS['TYPO3_CONF_VARS']['SYS']['enable_DLOG'] && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['devLog'])) {
+            $params = ['msg' => $msg, 'extKey' => $extKey, 'severity' => $severity, 'dataVar' => $dataVar];
             $fakeThis = false;
             foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['devLog'] as $hookMethod) {
                 self::callUserFunction($hookMethod, $params, $fakeThis);
@@ -4625,7 +3928,6 @@ class GeneralUtility
      * Writes a message to the deprecation log.
      *
      * @param string $msg Message (in English).
-     * @return void
      */
     public static function deprecationLog($msg)
     {
@@ -4635,7 +3937,7 @@ class GeneralUtility
         // Legacy values (no strict comparison, $log can be boolean, string or int)
         $log = $GLOBALS['TYPO3_CONF_VARS']['SYS']['enableDeprecationLog'];
         if ($log === true || $log == '1') {
-            $log = array('file');
+            $log = ['file'];
         } else {
             $log = self::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['SYS']['enableDeprecationLog'], true);
         }
@@ -4661,6 +3963,45 @@ class GeneralUtility
     }
 
     /**
+     * Logs the usage of a deprecated fluid ViewHelper argument.
+     * The log message will be generated automatically and contains the template path.
+     * With the third argument of this method it is possible to append some text to the log message.
+     *
+     * example usage:
+     *  if ($htmlEscape !== null) {
+     *      GeneralUtility::logDeprecatedViewHelperAttribute(
+     *          'htmlEscape',
+     *          $renderingContext,
+     *          'Please wrap the view helper in <f:format.raw> if you want to disable HTML escaping, which is enabled by default now.'
+     *      );
+     *  }
+     *
+     * The example above will create this deprecation log message:
+     * 15-02-17 23:12: [typo3/sysext/backend/Resources/Private/Templates/ToolbarItems/HelpToolbarItemDropDown.html]
+     *   The property "htmlEscape" has been deprecated.
+     *   Please wrap the view helper in <f:format.raw> if you want to disable HTML escaping,
+     *   which is enabled by default now.
+     *
+     * @param string $property
+     * @param RenderingContextInterface $renderingContext
+     * @param string $additionalMessage
+     */
+    public static function logDeprecatedViewHelperAttribute(string $property, RenderingContextInterface $renderingContext, string $additionalMessage = '')
+    {
+        $template = $renderingContext->getTemplatePaths()->resolveTemplateFileForControllerAndActionAndFormat(
+            $renderingContext->getControllerName(),
+            $renderingContext->getControllerAction()
+        );
+        $template = str_replace(PATH_site, '', $template);
+        $message = [];
+        $message[] = '[' . $template . ']';
+        $message[] = 'The property "' . $property . '" has been marked as deprecated.';
+        $message[] = $additionalMessage;
+        $message[] = 'Please check also your partial and layout files of this template';
+        self::deprecationLog(implode(' ', $message));
+    }
+
+    /**
      * Gets the absolute path to the deprecation log file.
      *
      * @return string Absolute path to the deprecation log file
@@ -4673,8 +4014,6 @@ class GeneralUtility
     /**
      * Logs a call to a deprecated function.
      * The log message will be taken from the annotation.
-     *
-     * @return void
      */
     public static function logDeprecatedFunction()
     {
@@ -4707,7 +4046,7 @@ class GeneralUtility
      * @param int $valueLength Long string values are shortened to this length. Default: 20
      * @return string Output string with key names and their value as string
      */
-    public static function arrayToLogString(array $arr, $valueList = array(), $valueLength = 20)
+    public static function arrayToLogString(array $arr, $valueList = [], $valueLength = 20)
     {
         $str = '';
         if (!is_array($valueList)) {
@@ -4723,25 +4062,8 @@ class GeneralUtility
     }
 
     /**
-     * Compile the command for running ImageMagick/GraphicsMagick.
-     *
-     * @param string $command Command to be run: identify, convert or combine/composite
-     * @param string $parameters The parameters string
-     * @param string $path Override the default path (e.g. used by the install tool)
-     * @return string Compiled command that deals with ImageMagick & GraphicsMagick
-     * @deprecated since TYPO3 CMS 8, will be removed in TYPO3 CMS 9. - use CommandUtility directly
-     */
-    public static function imageMagickCommand($command, $parameters, $path = '')
-    {
-        self::logDeprecatedFunction();
-        return CommandUtility::imageMagickCommand($command, $parameters, $path);
-    }
-
-    /**
      * Explode a string (normally a list of filenames) with whitespaces by considering quotes in that string.
      *
-     * This is mostly needed by the imageMagickCommand function above.
-     *
      * @param string $parameters The whole parameters string
      * @param bool $unQuote If set, the elements of the resulting array are unquoted.
      * @return array Exploded parameters
@@ -4786,7 +4108,7 @@ class GeneralUtility
     {
         return strtr(
             json_encode((string)$value, JSON_HEX_AMP|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_TAG),
-            array(
+            [
                 '"' => '\'',
                 '\\\\' => '\\u005C',
                 ' ' => '\\u0020',
@@ -4794,47 +4116,18 @@ class GeneralUtility
                 '\\t' => '\\u0009',
                 '\\n' => '\\u000A',
                 '\\r' => '\\u000D'
-            )
+            ]
         );
     }
 
     /**
-     * Ends and flushes all output buffers
-     *
-     * @return void
-     * @deprecated since TYPO3 CMS 8, will be removed in TYPO3 CMS 9.
-     */
-    public static function flushOutputBuffers()
-    {
-        self::logDeprecatedFunction();
-        $obContent = '';
-        while ($content = ob_get_clean()) {
-            $obContent .= $content;
-        }
-        // If previously a "Content-Encoding: whatever" has been set, we have to unset it
-        if (!headers_sent()) {
-            $headersList = headers_list();
-            foreach ($headersList as $header) {
-                // Split it up at the :
-                list($key, $value) = self::trimExplode(':', $header, true);
-                // Check if we have a Content-Encoding other than 'None'
-                if (strtolower($key) === 'content-encoding' && strtolower($value) !== 'none') {
-                    header('Content-Encoding: None');
-                    break;
-                }
-            }
-        }
-        echo $obContent;
-    }
-
-    /**
      * Set the ApplicationContext
      *
      * This function is used by the Bootstrap to hand over the application context. It must not be used anywhere else,
      * because the context shall never be changed on runtime!
      *
      * @param \TYPO3\CMS\Core\Core\ApplicationContext $applicationContext
-     * @throws \RuntimeException if applicationContext is overriden
+     * @throws \RuntimeException if applicationContext is overridden
      * @internal This is not a public API method, do not use in own extensions
      */
     public static function presetApplicationContext(ApplicationContext $applicationContext)