[BUG] t3lib_div::getFilesInDir order differs from order in File list
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_div.php
index 6a8c2a6..77ac69c 100644 (file)
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
-       // a tabulator
-define('TAB', chr(9));
-       // a linefeed
-define('LF', chr(10));
-       // a carriage return
-define('CR', chr(13));
-       // a CR-LF combination
-define('CRLF', CR . LF);
-
 /**
  * The legendary "t3lib_div" class - Miscellaneous functions for general purpose.
  * Most of the functions do not relate specifically to TYPO3
@@ -74,13 +65,6 @@ final class t3lib_div {
         */
        protected static $nonSingletonInstances = array();
 
-       /**
-        * Register for makeInstance with given class name and final class names to reduce number of class_exists() calls
-        *
-        * @var array Given class name => final class name
-        */
-       protected static $finalClassNameRegister = array();
-
        /*************************
         *
         * GET/POST Variables
@@ -144,7 +128,8 @@ final class t3lib_div {
         */
        public static function _GET($var = NULL) {
                $value = ($var === NULL) ? $_GET : (empty($var) ? NULL : $_GET[$var]);
-               if (isset($value)) { // Removes slashes since TYPO3 has added them regardless of magic_quotes setting.
+                       // Removes slashes since TYPO3 has added them regardless of magic_quotes setting.
+               if (isset($value)) {
                        if (is_array($value)) {
                                self::stripSlashesOnArray($value);
                        } else {
@@ -164,7 +149,8 @@ final class t3lib_div {
         */
        public static function _POST($var = NULL) {
                $value = ($var === NULL) ? $_POST : (empty($var) ? NULL : $_POST[$var]);
-               if (isset($value)) { // Removes slashes since TYPO3 has added them regardless of magic_quotes setting.
+                       // Removes slashes since TYPO3 has added them regardless of magic_quotes setting.
+               if (isset($value)) {
                        if (is_array($value)) {
                                self::stripSlashesOnArray($value);
                        } else {
@@ -178,11 +164,11 @@ final class t3lib_div {
         * Writes input value to $_GET.
         *
         * @param mixed $inputGet
-        *              array or single value to write to $_GET. Values should NOT be
+        *              Array or single value to write to $_GET. Values should NOT be
         *              escaped at input time (but will be escaped before writing
         *              according to TYPO3 standards).
         * @param string $key
-        *              alternative key; If set, this will not set the WHOLE GET array,
+        *              Alternative key; If set, this will not set the WHOLE GET array,
         *              but only the key in it specified by this value!
         *              You can specify to replace keys on deeper array levels by
         *              separating the keys with a pipe.
@@ -192,7 +178,7 @@ final class t3lib_div {
         * @return void
         */
        public static function _GETset($inputGet, $key = '') {
-                       // adds slashes since TYPO3 standard currently is that slashes
+                       // Adds slashes since TYPO3 standard currently is that slashes
                        // must be applied (regardless of magic_quotes setting)
                if (is_array($inputGet)) {
                        self::addSlashesOnArray($inputGet);
@@ -240,14 +226,12 @@ final class t3lib_div {
                return $string;
        }
 
-
        /*************************
         *
         * IMAGE FUNCTIONS
         *
         *************************/
 
-
        /**
         * Compressing a GIF file if not already LZW compressed.
         * This function is a workaround for the fact that ImageMagick and/or GD does not compress GIF-files to their minimun size (that is RLE or no compression used)
@@ -269,11 +253,13 @@ final class t3lib_div {
        public static function gif_compress($theFile, $type) {
                $gfxConf = $GLOBALS['TYPO3_CONF_VARS']['GFX'];
                $returnCode = '';
-               if ($gfxConf['gif_compress'] && strtolower(substr($theFile, -4, 4)) == '.gif') { // GIF...
-                       if (($type == 'IM' || !$type) && $gfxConf['im'] && $gfxConf['im_path_lzw']) { // IM
-                                       // use temporary file to prevent problems with read and write lock on same file on network file systems
+                       // GIF...
+               if ($gfxConf['gif_compress'] && strtolower(substr($theFile, -4, 4)) == '.gif') {
+                               // IM
+                       if (($type == 'IM' || !$type) && $gfxConf['im'] && $gfxConf['im_path_lzw']) {
+                                       // Use temporary file to prevent problems with read and write lock on same file on network file systems
                                $temporaryName  =  dirname($theFile) . '/' . md5(uniqid()) . '.gif';
-                                       // rename could fail, if a simultaneous thread is currently working on the same thing
+                                       // Rename could fail, if a simultaneous thread is currently working on the same thing
                                if (@rename($theFile, $temporaryName)) {
                                        $cmd = self::imageMagickCommand('convert', '"' . $temporaryName . '" "' . $theFile . '"', $gfxConf['im_path_lzw']);
                                        t3lib_utility_Command::exec($cmd);
@@ -301,8 +287,8 @@ final class t3lib_div {
         * Converts a png file to gif.
         * This converts a png file to gif IF the FLAG $GLOBALS['TYPO3_CONF_VARS']['FE']['png_to_gif'] is set TRUE.
         *
-        * @param string $theFile the filename with path
-        * @return string new filename
+        * @param string $theFile The filename with path
+        * @return string New filename
         */
        public static function png_to_gif_by_imagemagick($theFile) {
                if ($GLOBALS['TYPO3_CONF_VARS']['FE']['png_to_gif']
@@ -351,7 +337,6 @@ final class t3lib_div {
                }
        }
 
-
        /*************************
         *
         * STRING FUNCTIONS
@@ -361,10 +346,10 @@ final class t3lib_div {
        /**
         * Truncates a string with appended/prepended "..." and takes current character set into consideration.
         *
-        * @param string $string string to truncate
-        * @param integer $chars must be an integer with an absolute value of at least 4. if negative the string is cropped from the right end.
-        * @param string $appendString appendix to the truncated string
-        * @return string cropped string
+        * @param string $string String to truncate
+        * @param integer $chars Must be an integer with an absolute value of at least 4. if negative the string is cropped from the right end.
+        * @param string $appendString Appendix to the truncated string
+        * @return string Cropped string
         */
        public static function fixed_lgd_cs($string, $chars, $appendString = '...') {
                if (is_object($GLOBALS['LANG'])) {
@@ -373,32 +358,18 @@ final class t3lib_div {
                        $charSet = ($GLOBALS['TSFE']->renderCharset != '' ? $GLOBALS['TSFE']->renderCharset : $GLOBALS['TSFE']->defaultCharSet);
                        return $GLOBALS['TSFE']->csConvObj->crop($charSet, $string, $chars, $appendString);
                } else {
-                               // this case should not happen
+                               // This case should not happen
                        $csConvObj = self::makeInstance('t3lib_cs');
-                       return $csConvObj->crop('iso-8859-1', $string, $chars, $appendString);
+                       return $csConvObj->crop('utf-8', $string, $chars, $appendString);
                }
        }
 
        /**
-        * Breaks up a single line of text for emails
-        *
-        * @param string $str The string to break up
-        * @param string $newlineChar The string to implode the broken lines with (default/typically \n)
-        * @param integer $lineWidth The line width
-        * @return string reformatted text
-        * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - Use t3lib_utility_Mail::breakLinesForPlainEmail()
-        */
-       public static function breakLinesForEmail($str, $newlineChar = LF, $lineWidth = 76) {
-               self::logDeprecatedFunction();
-               return t3lib_utility_Mail::breakLinesForPlainEmail($str, $newlineChar, $lineWidth);
-       }
-
-       /**
         * Match IP number with list of numbers with wildcard
         * Dispatcher method for switching into specialised IPv4 and IPv6 methods.
         *
-        * @param string $baseIP is the current remote IP address for instance, typ. REMOTE_ADDR
-        * @param string $list is a comma-list of IP-addresses to match with. *-wildcard allowed instead of number, plus leaving out parts in the IP number is accepted as wildcard (eg. 192.168.*.* equals 192.168). If list is "*" no check is done and the function returns TRUE immediately. An empty list always returns FALSE.
+        * @param string $baseIP Is the current remote IP address for instance, typ. REMOTE_ADDR
+        * @param string $list Is a comma-list of IP-addresses to match with. *-wildcard allowed instead of number, plus leaving out parts in the IP number is accepted as wildcard (eg. 192.168.*.* equals 192.168). If list is "*" no check is done and the function returns TRUE immediately. An empty list always returns FALSE.
         * @return boolean TRUE if an IP-mask from $list matches $baseIP
         */
        public static function cmpIP($baseIP, $list) {
@@ -418,8 +389,8 @@ final class t3lib_div {
        /**
         * Match IPv4 number with list of numbers with wildcard
         *
-        * @param string $baseIP is the current remote IP address for instance, typ. REMOTE_ADDR
-        * @param string $list is a comma-list of IP-addresses to match with. *-wildcard allowed instead of number, plus leaving out parts in the IP number is accepted as wildcard (eg. 192.168.*.* equals 192.168)
+        * @param string $baseIP Is the current remote IP address for instance, typ. REMOTE_ADDR
+        * @param string $list Is a comma-list of IP-addresses to match with. *-wildcard allowed instead of number, plus leaving out parts in the IP number is accepted as wildcard (eg. 192.168.*.* equals 192.168), could also contain IPv6 addresses
         * @return boolean TRUE if an IP-mask from $list matches $baseIP
         */
        public static function cmpIPv4($baseIP, $list) {
@@ -428,7 +399,12 @@ final class t3lib_div {
                        $values = self::trimExplode(',', $list, 1);
 
                        foreach ($values as $test) {
-                               list($test, $mask) = explode('/', $test);
+                               $testList = explode('/', $test);
+                               if (count($testList) == 2) {
+                                       list($test, $mask) = $testList;
+                               } else {
+                                       $mask = FALSE;
+                               }
 
                                if (intval($mask)) {
                                                // "192.168.3.0/24"
@@ -445,7 +421,7 @@ final class t3lib_div {
                                        $yes = 1;
                                        foreach ($IPparts as $index => $val) {
                                                $val = trim($val);
-                                               if (strcmp($val, '*') && strcmp($IPpartsReq[$index], $val)) {
+                                               if (($val !== '*') && ($IPpartsReq[$index] !== $val)) {
                                                        $yes = 0;
                                                }
                                        }
@@ -461,39 +437,50 @@ final class t3lib_div {
        /**
         * Match IPv6 address with a list of IPv6 prefixes
         *
-        * @param string $baseIP is the current remote IP address for instance
-        * @param string $list is a comma-list of IPv6 prefixes, could also contain IPv4 addresses
-        * @return boolean TRUE if an baseIP matches any prefix
+        * @param string $baseIP Is the current remote IP address for instance
+        * @param string $list Is a comma-list of IPv6 prefixes, could also contain IPv4 addresses
+        * @return boolean TRUE If an baseIP matches any prefix
         */
        public static function cmpIPv6($baseIP, $list) {
-               $success = FALSE; // Policy default: Deny connection
+                       // Policy default: Deny connection
+               $success = FALSE;
                $baseIP = self::normalizeIPv6($baseIP);
 
                $values = self::trimExplode(',', $list, 1);
                foreach ($values as $test) {
-                       list($test, $mask) = explode('/', $test);
+                       $testList = explode('/', $test);
+                       if (count($testList) == 2) {
+                               list($test, $mask) = $testList;
+                       } else {
+                               $mask = FALSE;
+                       }
+
                        if (self::validIPv6($test)) {
                                $test = self::normalizeIPv6($test);
-                               if (intval($mask)) {
-                                       switch ($mask) { // test on /48 /64
-                                               case '48':
-                                                       $testBin = substr(self::IPv6Hex2Bin($test), 0, 48);
-                                                       $baseIPBin = substr(self::IPv6Hex2Bin($baseIP), 0, 48);
-                                                       $success = strcmp($testBin, $baseIPBin) == 0 ? TRUE : FALSE;
-                                                       break;
-                                               case '64':
-                                                       $testBin = substr(self::IPv6Hex2Bin($test), 0, 64);
-                                                       $baseIPBin = substr(self::IPv6Hex2Bin($baseIP), 0, 64);
-                                                       $success = strcmp($testBin, $baseIPBin) == 0 ? TRUE : FALSE;
-                                                       break;
-                                               default:
-                                                       $success = FALSE;
-                                       }
+                               $maskInt = intval($mask) ? intval($mask) : 128;
+                                       // Special case; /0 is an allowed mask - equals a wildcard
+                               if ($mask === '0') {
+                                       $success = TRUE;
+                               } elseif ($maskInt == 128) {
+                                       $success = ($test === $baseIP);
                                } else {
-                                       if (self::validIPv6($test)) { // test on full ip address 128 bits
-                                               $testBin = self::IPv6Hex2Bin($test);
-                                               $baseIPBin = self::IPv6Hex2Bin($baseIP);
-                                               $success = strcmp($testBin, $baseIPBin) == 0 ? TRUE : FALSE;
+                                       $testBin = self::IPv6Hex2Bin($test);
+                                       $baseIPBin = self::IPv6Hex2Bin($baseIP);
+                                       $success = TRUE;
+
+                                               // Modulo is 0 if this is a 8-bit-boundary
+                                       $maskIntModulo = $maskInt % 8;
+                                       $numFullCharactersUntilBoundary = intval($maskInt / 8);
+
+                                       if (substr($testBin, 0, $numFullCharactersUntilBoundary) !== substr($baseIPBin, 0, $numFullCharactersUntilBoundary)) {
+                                               $success = FALSE;
+                                       } elseif ($maskIntModulo > 0) {
+                                                       // If not an 8-bit-boundary, check bits of last character
+                                               $testLastBits = str_pad(decbin(ord(substr($testBin, $numFullCharactersUntilBoundary, 1))), 8, '0', STR_PAD_LEFT);
+                                               $baseIPLastBits = str_pad(decbin(ord(substr($baseIPBin, $numFullCharactersUntilBoundary, 1))), 8, '0', STR_PAD_LEFT);
+                                               if (strncmp($testLastBits, $baseIPLastBits, $maskIntModulo) != 0) {
+                                                       $success = FALSE;
+                                               }
                                        }
                                }
                        }
@@ -505,31 +492,71 @@ final class t3lib_div {
        }
 
        /**
-        * Convert an IPv6 address to its binary representation
+        * Transform a regular IPv6 address from hex-representation into binary
         *
-        * @param string $hex IPv6 address in hexadecimal form
-        * @return integer
+        * @param string $hex IPv6 address in hex-presentation
+        * @return string Binary representation (16 characters, 128 characters)
+        * @see IPv6Bin2Hex()
         */
        public static function IPv6Hex2Bin($hex) {
-               $bin = '';
-               $hex = str_replace(':', '', $hex); // Replace colon to nothing
-               for ($i = 0; $i < strlen($hex); $i = $i + 2) {
-                       $bin .= chr(hexdec(substr($hex, $i, 2)));
+                       // Use PHP-function if PHP was compiled with IPv6-support
+               if (defined('AF_INET6')) {
+                       $bin = inet_pton($hex);
+               } else {
+                       $hex = self::normalizeIPv6($hex);
+                               // Replace colon to nothing
+                       $hex = str_replace(':', '', $hex);
+                       $bin = pack('H*', $hex);
                }
                return $bin;
        }
 
        /**
+        * Transform an IPv6 address from binary to hex-representation
+        *
+        * @param string $bin IPv6 address in hex-presentation
+        * @return string Binary representation (16 characters, 128 characters)
+        * @see IPv6Hex2Bin()
+        */
+       public static function IPv6Bin2Hex($bin) {
+                       // Use PHP-function if PHP was compiled with IPv6-support
+               if (defined('AF_INET6')) {
+                       $hex = inet_ntop($bin);
+               } else {
+                       $hex = unpack('H*', $bin);
+                       $hex = chunk_split($hex[1], 4, ':');
+                               // Strip last colon (from chunk_split)
+                       $hex = substr($hex, 0, -1);
+                               // IPv6 is now in normalized form
+                               // Compress it for easier handling and to match result from inet_ntop()
+                       $hex = self::compressIPv6($hex);
+               }
+               return $hex;
+
+       }
+
+       /**
         * Normalize an IPv6 address to full length
         *
         * @param string $address Given IPv6 address
         * @return string Normalized address
+        * @see compressIPv6()
         */
        public static function normalizeIPv6($address) {
                $normalizedAddress = '';
                $stageOneAddress = '';
 
-               $chunks = explode('::', $address); // Count 2 if if address has hidden zero blocks
+                       // 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) {
+                               // Already in full expanded form
+                       return $address;
+               }
+
+                       // Count 2 if if address has hidden zero blocks
+               $chunks = explode('::', $address);
                if (count($chunks) == 2) {
                        $chunksLeft = explode(':', $chunks[0]);
                        $chunksRight = explode(':', $chunks[1]);
@@ -558,7 +585,7 @@ final class t3lib_div {
                        $stageOneAddress = $address;
                }
 
-                       // normalize the blocks:
+                       // Normalize the blocks:
                $blocks = explode(':', $stageOneAddress);
                $divCounter = 0;
                foreach ($blocks as $block) {
@@ -578,6 +605,48 @@ final class t3lib_div {
                return $normalizedAddress;
        }
 
+
+       /**
+        * Compress an IPv6 address to the shortest notation
+        *
+        * @param string $address Given IPv6 address
+        * @return string Compressed address
+        * @see normalizeIPv6()
+        */
+       public static function compressIPv6($address) {
+                       // Use PHP-function if PHP was compiled with IPv6-support
+               if (defined('AF_INET6')) {
+                       $bin = inet_pton($address);
+                       $address = inet_ntop($bin);
+               } else {
+                       $address = self::normalizeIPv6($address);
+
+                               // Append one colon for easier handling
+                               // will be removed later
+                       $address .= ':';
+
+                               // According to IPv6-notation the longest match
+                               // of a package of '0000:' may be replaced with ':'
+                               // (resulting in something like '1234::abcd')
+                       for ($counter = 8; $counter > 1; $counter--) {
+                               $search = str_repeat('0000:', $counter);
+                               if (($pos = strpos($address, $search)) !== FALSE) {
+                                       $address = substr($address, 0, $pos) . ':' . substr($address, $pos + ($counter*5));
+                                       break;
+                               }
+                       }
+
+                               // Up to 3 zeros in the first part may be removed
+                       $address = preg_replace('/^0{1,3}/', '', $address);
+                               // Up to 3 zeros at the beginning of other parts may be removed
+                       $address = preg_replace('/:0{1,3}/', ':', $address);
+
+                               // Strip last colon (from chunk_split)
+                       $address = substr($address, 0, -1);
+               }
+               return $address;
+       }
+
        /**
         * Validate a given IP address.
         *
@@ -617,28 +686,69 @@ final class t3lib_div {
        /**
         * Match fully qualified domain name with list of strings with wildcard
         *
-        * @param string $baseIP The current remote IP address for instance, typ. REMOTE_ADDR
+        * @param string $baseHost A hostname or an IPv4/IPv6-address (will by reverse-resolved; typically REMOTE_ADDR)
         * @param string $list A comma-list of domain names to match with. *-wildcard allowed but cannot be part of a string, so it must match the full host name (eg. myhost.*.com => correct, myhost.*domain.com => wrong)
         * @return boolean TRUE if a domain name mask from $list matches $baseIP
         */
-       public static function cmpFQDN($baseIP, $list) {
-               if (count(explode('.', $baseIP)) == 4) {
-                       $resolvedHostName = explode('.', gethostbyaddr($baseIP));
-                       $values = self::trimExplode(',', $list, 1);
+       public static function cmpFQDN($baseHost, $list) {
+               $baseHost = trim($baseHost);
+               if (empty($baseHost)) {
+                       return FALSE;
+               }
+               if (self::validIPv4($baseHost) || self::validIPv6($baseHost)) {
+                               // Resolve hostname
+                               // Note: this is reverse-lookup and can be randomly set as soon as somebody is able to set
+                               // the reverse-DNS for his IP (security when for example used with REMOTE_ADDR)
+                       $baseHostName = gethostbyaddr($baseHost);
+                       if ($baseHostName === $baseHost) {
+                                       // Unable to resolve hostname
+                               return FALSE;
+                       }
+               } else {
+                       $baseHostName = $baseHost;
+               }
+               $baseHostNameParts = explode('.', $baseHostName);
 
-                       foreach ($values as $test) {
-                               $hostNameParts = explode('.', $test);
-                               $yes = 1;
+               $values = self::trimExplode(',', $list, 1);
+
+               foreach ($values as $test) {
+                       $hostNameParts = explode('.', $test);
+
+                               // To match hostNameParts can only be shorter (in case of wildcards) or equal
+                       if (count($hostNameParts) > count($baseHostNameParts)) {
+                               continue;
+                       }
 
-                               foreach ($hostNameParts as $index => $val) {
-                                       $val = trim($val);
-                                       if (strcmp($val, '*') && strcmp($resolvedHostName[$index], $val)) {
-                                               $yes = 0;
+                       $yes = TRUE;
+                       foreach ($hostNameParts as $index => $val) {
+                               $val = trim($val);
+                               if ($val === '*') {
+                                               // Wildcard valid for one or more hostname-parts
+
+                                       $wildcardStart = $index + 1;
+                                               // Wildcard as last/only part always matches, otherwise perform recursive checks
+                                       if ($wildcardStart < count($hostNameParts)) {
+                                               $wildcardMatched = FALSE;
+                                               $tempHostName = implode('.', array_slice($hostNameParts, $index + 1));
+                                               while (($wildcardStart < count($baseHostNameParts)) && (!$wildcardMatched)) {
+                                                       $tempBaseHostName = implode('.', array_slice($baseHostNameParts, $wildcardStart));
+                                                       $wildcardMatched = self::cmpFQDN($tempBaseHostName, $tempHostName);
+                                                       $wildcardStart++;
+                                               }
+                                               if ($wildcardMatched) {
+                                                               // Match found by recursive compare
+                                                       return TRUE;
+                                               } else {
+                                                       $yes = FALSE;
+                                               }
                                        }
+                               } elseif ($baseHostNameParts[$index] !== $val) {
+                                               // In case of no match
+                                       $yes = FALSE;
                                }
-                               if ($yes) {
-                                       return TRUE;
-                               }
+                       }
+                       if ($yes) {
+                               return TRUE;
                        }
                }
                return FALSE;
@@ -648,7 +758,7 @@ final class t3lib_div {
         * Checks if a given URL matches the host that currently handles this HTTP request.
         * Scheme, hostname and (optional) port of the given URL are compared.
         *
-        * @param string $url: URL to compare with the TYPO3 request host
+        * @param string $url URL to compare with the TYPO3 request host
         * @return boolean Whether the URL matches the TYPO3 request host
         */
        public static function isOnCurrentHost($url) {
@@ -659,8 +769,8 @@ final class t3lib_div {
         * Check for item in list
         * Check if an item exists in a comma-separated list of items.
         *
-        * @param string $list comma-separated list of items (string)
-        * @param string $item item to check for
+        * @param string $list Comma-separated list of items (string)
+        * @param string $item Item to check for
         * @return boolean TRUE if $item is in $list
         */
        public static function inList($list, $item) {
@@ -670,9 +780,9 @@ final class t3lib_div {
        /**
         * Removes an item from a comma-separated list of items.
         *
-        * @param string $element element to remove
-        * @param string $list comma-separated list of items (string)
-        * @return string new comma-separated list of items
+        * @param string $element Element to remove
+        * @param string $list Comma-separated list of items (string)
+        * @return string New comma-separated list of items
         */
        public static function rmFromList($element, $list) {
                $items = explode(',', $list);
@@ -688,9 +798,8 @@ final class t3lib_div {
         * Expand a comma-separated list of integers with ranges (eg 1,3-5,7 becomes 1,3,4,5,7).
         * Ranges are limited to 1000 values per range.
         *
-        * @param string $list comma-separated list of integers with ranges (string)
-        * @return string new comma-separated list of items
-        * @author Martin Kutschker <martin.kutschker@activesolution.at>
+        * @param string $list Comma-separated list of integers with ranges (string)
+        * @return string New comma-separated list of items
         */
        public static function expandList($list) {
                $items = explode(',', $list);
@@ -715,41 +824,17 @@ final class t3lib_div {
        }
 
        /**
-        * Forces the integer $theInt into the boundaries of $min and $max. If the $theInt is 'FALSE' then the $zeroValue is applied.
-        *
-        * @param integer $theInt Input value
-        * @param integer $min Lower limit
-        * @param integer $max Higher limit
-        * @param integer $zeroValue Default value if input is FALSE.
-        * @return integer The input value forced into the boundaries of $min and $max
-        * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - Use t3lib_utility_Math::forceIntegerInRange() instead
-        */
-       public static function intInRange($theInt, $min, $max = 2000000000, $zeroValue = 0) {
-               self::logDeprecatedFunction();
-               return t3lib_utility_Math::forceIntegerInRange($theInt, $min, $max, $zeroValue);
-       }
-
-       /**
-        * Returns the $integer if greater than zero, otherwise returns zero.
-        *
-        * @param integer $theInt Integer string to process
-        * @return integer
-        * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - Use t3lib_utility_Math::convertToPositiveInteger() instead
-        */
-       public static function intval_positive($theInt) {
-               self::logDeprecatedFunction();
-               return t3lib_utility_Math::convertToPositiveInteger($theInt);
-       }
-
-       /**
         * Returns an integer from a three part version number, eg '4.12.3' -> 4012003
         *
         * @param string $verNumberStr Version number on format x.x.x
         * @return integer Integer version of version number (where each part can count to 999)
-        * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - Use t3lib_utility_Math::convertVersionNumberToInteger() instead
+        * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.9 - Use t3lib_utility_VersionNumber::convertVersionNumberToInteger() instead
         */
        public static function int_from_ver($verNumberStr) {
-               self::logDeprecatedFunction();
+                       // Deprecation log is activated only for TYPO3 4.7 and above
+               if (t3lib_utility_VersionNumber::convertVersionNumberToInteger(TYPO3_version) >= 4007000) {
+                       self::logDeprecatedFunction();
+               }
                return t3lib_utility_VersionNumber::convertVersionNumberToInteger($verNumberStr);
        }
 
@@ -757,7 +842,7 @@ final class t3lib_div {
         * 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"!)
+        * @param string $verNumberStr Minimum branch number required (format x.y / e.g. "4.0" NOT "4.0.0"!)
         * @return boolean Returns TRUE if this setup is compatible with the provided version number
         * @todo Still needs a function to convert versions to branches
         */
@@ -806,15 +891,15 @@ final class t3lib_div {
                if (extension_loaded('hash') && function_exists('hash_hmac') && function_exists('hash_algos') && in_array($hashAlgorithm, hash_algos())) {
                        $hmac = hash_hmac($hashAlgorithm, $input, $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']);
                } else {
-                               // outer padding
+                               // Outer padding
                        $opad = str_repeat(chr(0x5C), $hashBlocksize);
-                               // innner padding
+                               // Inner padding
                        $ipad = str_repeat(chr(0x36), $hashBlocksize);
                        if (strlen($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']) > $hashBlocksize) {
-                                       // keys longer than blocksize are shorten
+                                       // Keys longer than block size are shorten
                                $key = str_pad(pack('H*', call_user_func($hashAlgorithm, $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])), $hashBlocksize, chr(0x00));
                        } else {
-                                       // keys shorter than blocksize are zero-padded
+                                       // Keys shorter than block size are zero-padded
                                $key = str_pad($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], $hashBlocksize, chr(0x00));
                        }
                        $hmac = call_user_func($hashAlgorithm, ($key ^ $opad) . pack('H*', call_user_func($hashAlgorithm, ($key ^ $ipad) . $input)));
@@ -826,8 +911,8 @@ final class t3lib_div {
         * Takes comma-separated lists and arrays and removes all duplicates
         * If a value in the list is trim(empty), the value is ignored.
         *
-        * @param string $in_list Accept multiple parameters wich can be comma-separated lists of values and arrays.
-        * @param mixed $secondParameter: Dummy field, which if set will show a warning!
+        * @param string $in_list Accept multiple parameters which can be comma-separated lists of values and arrays.
+        * @param mixed $secondParameter Dummy field, which if set will show a warning!
         * @return string Returns the list without any duplicates of values, space around values are trimmed
         */
        public static function uniqueList($in_list, $secondParameter = NULL) {
@@ -930,32 +1015,6 @@ final class t3lib_div {
        }
 
        /**
-        * Removes comma (if present) in the end of string
-        *
-        * @param string $string String from which the comma in the end (if any) will be removed.
-        * @return string
-        * @deprecated since TYPO3 4.5, will be removed in TYPO3 4.7 - Use rtrim() directly
-        */
-       public static function rm_endcomma($string) {
-               self::logDeprecatedFunction();
-
-               return rtrim($string, ',');
-       }
-
-       /**
-        * Tests if the input can be interpreted as integer.
-        *
-        * @param mixed $var Any input variable to test
-        * @return boolean Returns TRUE if string is an integer
-        * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - Use t3lib_utility_Math::canBeInterpretedAsInteger() instead
-        */
-       public static function testInt($var) {
-               self::logDeprecatedFunction();
-
-               return t3lib_utility_Math::canBeInterpretedAsInteger($var);
-       }
-
-       /**
         * Returns TRUE if the first part of $str matches the string $partStr
         *
         * @param string $str Full string to check
@@ -985,11 +1044,11 @@ final class t3lib_div {
 
                        // Find size:
                if ($sizeInBytes > 900) {
-                       if ($sizeInBytes > 900000000) { // GB
+                               // GB
+                       if ($sizeInBytes > 900000000) {
                                $val = $sizeInBytes / (1024 * 1024 * 1024);
                                return number_format($val, (($val < 20) ? 1 : 0), '.', '') . $labelArr[3];
-                       }
-                       elseif ($sizeInBytes > 900000) { // MB
+                       } elseif ($sizeInBytes > 900000) { // MB
                                $val = $sizeInBytes / (1024 * 1024);
                                return number_format($val, (($val < 20) ? 1 : 0), '.', '') . $labelArr[2];
                        } else { // KB
@@ -1035,34 +1094,6 @@ final class t3lib_div {
        }
 
        /**
-        * Calculates the input by +,-,*,/,%,^ with priority to + and -
-        *
-        * @param string $string Input string, eg "123 + 456 / 789 - 4"
-        * @return integer Calculated value. Or error string.
-        * @see calcParenthesis()
-        * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - Use t3lib_utility_Math::calculateWithPriorityToAdditionAndSubtraction() instead
-        */
-       public static function calcPriority($string) {
-               self::logDeprecatedFunction();
-
-               return t3lib_utility_Math::calculateWithPriorityToAdditionAndSubtraction($string);
-       }
-
-       /**
-        * Calculates the input with parenthesis levels
-        *
-        * @param string $string Input string, eg "(123 + 456) / 789 - 4"
-        * @return integer Calculated value. Or error string.
-        * @see calcPriority(), tslib_cObj::stdWrap()
-        * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - Use t3lib_utility_Math::calculateWithParentheses() instead
-        */
-       public static function calcParenthesis($string) {
-               self::logDeprecatedFunction();
-
-               return t3lib_utility_Math::calculateWithParentheses($string);
-       }
-
-       /**
         * Inverse version of htmlspecialchars()
         *
         * @param string $value Value where &gt;, &lt;, &quot; and &amp; should be converted to regular chars.
@@ -1096,9 +1127,9 @@ final class t3lib_div {
         */
        public static function slashJS($string, $extended = FALSE, $char = "'") {
                if ($extended) {
-                       $string = str_replace("\\", "\\\\", $string);
+                       $string = str_replace('\\', '\\\\', $string);
                }
-               return str_replace($char, "\\" . $char, $string);
+               return str_replace($char, '\\' . $char, $string);
        }
 
        /**
@@ -1114,7 +1145,7 @@ final class t3lib_div {
 
        /**
         * rawurlencode which preserves "/" chars
-        * Useful when filepaths should keep the "/" chars, but have all other special chars encoded.
+        * Useful when file paths should keep the "/" chars, but have all other special chars encoded.
         *
         * @param string $str Input string
         * @return string Output string
@@ -1130,12 +1161,15 @@ final class t3lib_div {
         * @return boolean Returns TRUE if the $email address (input string) is valid
         */
        public static function validEmail($email) {
-                       // enforce maximum length to prevent libpcre recursion crash bug #52929 in PHP
+                       // Enforce maximum length to prevent libpcre recursion crash bug #52929 in PHP
                        // fixed in PHP 5.3.4; length restriction per SMTP RFC 2821
                if (strlen($email) > 320) {
                        return FALSE;
                }
-               return (filter_var($email, FILTER_VALIDATE_EMAIL) !== FALSE);
+               require_once(PATH_typo3 . 'contrib/idna/idna_convert.class.php');
+               $IDN = new idna_convert(array('idn_version' => 2008));
+
+               return (filter_var($IDN->encode($email), FILTER_VALIDATE_EMAIL) !== FALSE);
        }
 
        /**
@@ -1210,57 +1244,118 @@ final class t3lib_div {
        /**
         * Returns a string of highly randomized bytes (over the full 8-bit range).
         *
-        * @copyright Drupal CMS
-        * @license GNU General Public License version 2
-        * @param integer $count Number of characters (bytes) to return
+        * Note: Returned values are not guaranteed to be crypto-safe,
+        * most likely they are not, depending on the used retrieval method.
+        *
+        * @param integer $bytesToReturn Number of characters (bytes) to return
         * @return string Random Bytes
-        */
-       public static function generateRandomBytes($count) {
-               $output = '';
-                       // /dev/urandom is available on many *nix systems and is considered
-                       // the best commonly available pseudo-random source.
-               if (TYPO3_OS != 'WIN' && ($fh = @fopen('/dev/urandom', 'rb'))) {
-                       $output = fread($fh, $count);
-                       fclose($fh);
-               } elseif (TYPO3_OS == 'WIN') {
-                       if (class_exists('COM')) {
-                               try {
-                                       $com = new COM('CAPICOM.Utilities.1');
-                                       $output = base64_decode($com->GetRandom($count, 0));
-                               } catch (Exception $e) {
-                                       // CAPICOM not installed
+        * @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
+                                       // Windows PHP versions have a bug when using urandom source (see #24410)
+                               $bytes .= self::generateRandomBytesMcrypt($bytesToGenerate, MCRYPT_RAND);
+                       } else {
+                                       // Try to use native PHP functions first, precedence has openssl
+                               $bytes .= self::generateRandomBytesOpenSsl($bytesToGenerate);
+
+                               if (!isset($bytes{$bytesToReturn - 1})) {
+                                       $bytes .= self::generateRandomBytesMcrypt($bytesToGenerate, MCRYPT_DEV_URANDOM);
                                }
-                       }
-                       if ($output === '') {
-                               if (function_exists('mcrypt_create_iv')) {
-                                       $output = mcrypt_create_iv($count, MCRYPT_DEV_URANDOM);
-                               } elseif (function_exists('openssl_random_pseudo_bytes')) {
-                                       $isStrong = NULL;
-                                       $output = openssl_random_pseudo_bytes($count, $isStrong);
-                                               // skip ssl since it wasn't using the strong algo
-                                       if ($isStrong !== TRUE) {
-                                               $output = '';
-                                       }
+
+                                       // If openssl and mcrypt failed, try /dev/urandom
+                               if (!isset($bytes{$bytesToReturn - 1})) {
+                                       $bytes .= self::generateRandomBytesUrandom($bytesToGenerate);
                                }
                        }
-               }
 
-                       // fallback if other random byte generation failed until now
-               if (!isset($output{$count - 1})) {
-                               // We initialize with the somewhat random.
-                       $randomState = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']
-                                       . base_convert(memory_get_usage() % pow(10, 6), 10, 2)
-                                       . microtime() . uniqid('') . getmypid();
-                       while (!isset($output{$count - 1})) {
-                               $randomState = sha1(microtime() . mt_rand() . $randomState);
-                               $output .= sha1(mt_rand() . $randomState, TRUE);
+                               // Fall back if other random byte generation failed until now
+                       if (!isset($bytes{$bytesToReturn - 1})) {
+                               $bytes .= self::generateRandomBytesFallback($bytesToReturn);
                        }
-                       $output = substr($output, strlen($output) - $count, $count);
                }
+
+                       // 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
+        * @param $randomSource
+        * @return string
+        */
+       protected static function generateRandomBytesMcrypt($bytesToGenerate, $randomSource) {
+               if (!function_exists('mcrypt_create_iv')) {
+                       return '';
+               }
+               return (string) @mcrypt_create_iv($bytesToGenerate, $randomSource);
+       }
+
+       /**
+        * 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() . uniqid('') . getmypid();
+               while (!isset($bytes{$bytesToReturn - 1})) {
+                       $randomState = sha1(microtime() . mt_rand() . $randomState);
+                       $bytes .= sha1(mt_rand() . $randomState, TRUE);
+               }
+               return $bytes;
+       }
+
+       /**
         * Returns a hex representation of a random byte string.
         *
         * @param integer $count Number of hex characters to return
@@ -1274,7 +1369,7 @@ final class t3lib_div {
         * Returns a given string with underscores as UpperCamelCase.
         * Example: Converts blog_example to BlogExample
         *
-        * @param string $string: String to be converted to camel case
+        * @param string $string String to be converted to camel case
         * @return string UpperCamelCasedWord
         */
        public static function underscoredToUpperCamelCase($string) {
@@ -1286,7 +1381,7 @@ final class t3lib_div {
         * Returns a given string with underscores as lowerCamelCase.
         * Example: Converts minimal_value to minimalValue
         *
-        * @param string $string: String to be converted to camel case
+        * @param string $string String to be converted to camel case
         * @return string lowerCamelCasedWord
         */
        public static function underscoredToLowerCamelCase($string) {
@@ -1324,9 +1419,11 @@ final class t3lib_div {
         * @return boolean Whether the given URL is valid
         */
        public static function isValidUrl($url) {
-               return (filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED) !== FALSE);
-       }
+               require_once(PATH_typo3 . 'contrib/idna/idna_convert.class.php');
+               $IDN = new idna_convert(array('idn_version' => 2008));
 
+               return (filter_var($IDN->encode($url), FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED) !== FALSE);
+       }
 
        /*************************
         *
@@ -1352,8 +1449,8 @@ final class t3lib_div {
         * | 0     | TRUE         | TRUE          | TRUE          |
         * +---------+-----------+-----------+-----------+
         *
-        * @param array $in_array one-dimensional array of items
-        * @param string $item item to check for
+        * @param array $in_array One-dimensional array of items
+        * @param string $item Item to check for
         * @return boolean TRUE if $item is in the one-dimensional array $in_array
         */
        public static function inArray(array $in_array, $item) {
@@ -1476,9 +1573,9 @@ final class t3lib_div {
         *               array('bb' => array('third', 'fourth'),
         * )
         *
-        * @param array $array: The initial array to be filtered/reduced
-        * @param mixed $keepItems: The items which are allowed/kept in the array - accepts array or csv string
-        * @param string $getValueFunc: (optional) Unique function name set by create_function() used to get the value to keep
+        * @param array $array The initial array to be filtered/reduced
+        * @param mixed $keepItems The items which are allowed/kept in the array - accepts array or csv string
+        * @param string $getValueFunc (optional) Unique function name set by create_function() used to get the value to keep
         * @return array The filtered/reduced array with the kept items
         */
        public static function keepItemsInArray(array $array, $keepItems, $getValueFunc = NULL) {
@@ -1509,7 +1606,7 @@ final class t3lib_div {
         * Implodes a multidim-array into GET-parameters (eg. &param[key][key2]=value2&param[key][key3]=value3)
         *
         * @param string $name Name prefix for entries. Set to blank if you wish none.
-        * @param array $theArray The (multidim) array to implode
+        * @param array $theArray The (multidimensional) array to implode
         * @param string $str (keep blank)
         * @param boolean $skipBlank If set, parameters which were blank strings would be removed.
         * @param boolean $rawurlencodeParamName If set, the param name itself (for example "param[key][key2]") would be rawurlencoded as well.
@@ -1579,7 +1676,7 @@ final class t3lib_div {
 
        /**
         * AddSlash array
-        * This function traverses a multidimentional array and adds slashes to the values.
+        * This function traverses a multidimensional array and adds slashes to the values.
         * NOTE that the input array is and argument by reference.!!
         * Twin-function to stripSlashesOnArray
         *
@@ -1600,7 +1697,7 @@ final class t3lib_div {
 
        /**
         * StripSlash array
-        * This function traverses a multidimentional array and strips slashes to the values.
+        * This function traverses a multidimensional array and strips slashes to the values.
         * NOTE that the input array is and argument by reference.!!
         * Twin-function to addSlashesOnArray
         *
@@ -1642,7 +1739,7 @@ final class t3lib_div {
         * @param array $array Array by reference which should be remapped
         * @param array $mappingTable Array with remap information, array/$oldKey => $newKey)
         */
-       function remapArrayKeys(&$array, $mappingTable) {
+       public static function remapArrayKeys(&$array, $mappingTable) {
                if (is_array($mappingTable)) {
                        foreach ($mappingTable as $old => $new) {
                                if ($new && isset($array[$old])) {
@@ -1664,28 +1761,30 @@ final class t3lib_div {
         * @param array $arr1 Second array, overruling the first array
         * @param boolean $notAddKeys If set, keys that are NOT found in $arr0 (first array) will not be set. Thus only existing value can/will be overruled from second array.
         * @param boolean $includeEmptyValues If set, values from $arr1 will overrule if they are empty or zero. Default: TRUE
+        * @param boolean $enableUnsetFeature If set, special values "__UNSET" can be used in the second array in order to unset array keys in the resulting array.
         * @return array Resulting array where $arr1 values has overruled $arr0 values
         */
-       public static function array_merge_recursive_overrule(array $arr0, array $arr1, $notAddKeys = FALSE, $includeEmptyValues = TRUE) {
+       public static function array_merge_recursive_overrule(array $arr0, array $arr1, $notAddKeys = FALSE, $includeEmptyValues = TRUE, $enableUnsetFeature = TRUE) {
                foreach ($arr1 as $key => $val) {
                        if (is_array($arr0[$key])) {
                                if (is_array($arr1[$key])) {
-                                       $arr0[$key] = self::array_merge_recursive_overrule($arr0[$key], $arr1[$key], $notAddKeys, $includeEmptyValues);
+                                       $arr0[$key] = self::array_merge_recursive_overrule(
+                                               $arr0[$key],
+                                               $arr1[$key],
+                                               $notAddKeys,
+                                               $includeEmptyValues,
+                                               $enableUnsetFeature
+                                       );
                                }
-                       } else {
-                               if ($notAddKeys) {
-                                       if (isset($arr0[$key])) {
-                                               if ($includeEmptyValues || $val) {
-                                                       $arr0[$key] = $val;
-                                               }
-                                       }
-                               } else {
-                                       if ($includeEmptyValues || $val) {
-                                               $arr0[$key] = $val;
-                                       }
+                       } elseif (!$notAddKeys || isset($arr0[$key])) {
+                               if ($enableUnsetFeature && $val === '__UNSET') {
+                                       unset($arr0[$key]);
+                               } elseif ($includeEmptyValues || $val) {
+                                       $arr0[$key] = $val;
                                }
                        }
                }
+
                reset($arr0);
                return $arr0;
        }
@@ -1702,7 +1801,7 @@ final class t3lib_div {
        }
 
        /**
-        * Filters keys off from first array that also exist in second array. Comparision is done by keys.
+        * Filters keys off from first array that also exist in second array. Comparison is done by keys.
         * This method is a recursive version of php array_diff_assoc()
         *
         * @param array $array1 Source array
@@ -1728,7 +1827,7 @@ final class t3lib_div {
         * 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 comman
+        * @param string $delim Delimited, default is comma
         * @param string $quote Quote-character to wrap around the values.
         * @return string A single line of CSV
         */
@@ -1745,7 +1844,7 @@ final class t3lib_div {
         * Removes dots "." from end of a key identifier of TypoScript styled array.
         * array('key.' => array('property.' => 'value')) --> array('key' => array('property' => 'value'))
         *
-        * @param array $ts: TypoScript configuration array
+        * @param array $ts TypoScript configuration array
         * @return array TypoScript configuration array without dots at the end of all keys
         */
        public static function removeDotsFromTS(array $ts) {
@@ -1778,7 +1877,6 @@ final class t3lib_div {
                return TRUE;
        }
 
-
        /*************************
         *
         * HTML/XML PROCESSING
@@ -1787,7 +1885,7 @@ final class t3lib_div {
 
        /**
         * Returns an array with all attributes of the input HTML tag as key/value pairs. Attributes are only lowercase a-z
-        * $tag is either a whole tag (eg '<TAG OPTION ATTRIB=VALUE>') or the parameterlist (ex ' OPTION ATTRIB=VALUE>')
+        * $tag is either a whole tag (eg '<TAG OPTION ATTRIB=VALUE>') or the parameter list (ex ' OPTION ATTRIB=VALUE>')
         * If an attribute is empty, then the value for the key is empty. You can check if it existed with isset()
         *
         * @param string $tag HTML-tag string (or attributes only)
@@ -1795,18 +1893,20 @@ final class t3lib_div {
         */
        public static function get_tag_attributes($tag) {
                $components = self::split_tag_attributes($tag);
-               $name = ''; // attribute name is stored here
+                       // Attribute name is stored here
+               $name = '';
                $valuemode = FALSE;
                $attributes = array();
                foreach ($components as $key => $val) {
-                       if ($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
+                               // 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 ($valuemode) {
                                        if ($name) {
                                                $attributes[$name] = $val;
                                                $name = '';
                                        }
                                } else {
-                                       if ($key = strtolower(preg_replace('/[^a-zA-Z0-9]/', '', $val))) {
+                                       if ($key = strtolower(preg_replace('/[^[:alnum:]_\:\-]/', '', $val))) {
                                                $attributes[$key] = '';
                                                $name = $key;
                                        }
@@ -1832,7 +1932,8 @@ final class t3lib_div {
                $tag_tmp = trim(rtrim($tag_tmp, '>'));
 
                $value = array();
-               while (strcmp($tag_tmp, '')) { // Compared with empty string instead , 030102
+                       // Compared with empty string instead , 030102
+               while (strcmp($tag_tmp, '')) {
                        $firstChar = substr($tag_tmp, 0, 1);
                        if (!strcmp($firstChar, '"') || !strcmp($firstChar, "'")) {
                                $reg = explode($firstChar, $tag_tmp, 3);
@@ -1840,7 +1941,8 @@ final class t3lib_div {
                                $tag_tmp = trim($reg[2]);
                        } elseif (!strcmp($firstChar, '=')) {
                                $value[] = '=';
-                               $tag_tmp = trim(substr($tag_tmp, 1)); // Removes = chars.
+                                       // Removes = chars.
+                               $tag_tmp = trim(substr($tag_tmp, 1));
                        } else {
                                        // There are '' around the value. We look for the next ' ' or '>'
                                $reg = preg_split('/[[:space:]=]/', $tag_tmp, 2);
@@ -1881,14 +1983,12 @@ final class t3lib_div {
 
        /**
         * Wraps JavaScript code XHTML ready with <script>-tags
-        * Automatic re-identing of the JS code is done by using the first line as ident reference.
-        * This is nice for identing JS code with PHP code on the same level.
+        * Automatic re-indenting of the JS code is done by using the first line as indent reference.
+        * This is nice for indenting JS code with PHP code on the same level.
         *
         * @param string $string JavaScript code
-        * @param boolean $linebreak Wrap script element in linebreaks? Default is TRUE.
+        * @param boolean $linebreak Wrap script element in line breaks? Default is TRUE.
         * @return string The wrapped JS code, ready to put into a XHTML page
-        * @author Ingmar Schlecht <ingmars@web.de>
-        * @author René Fritz <r.fritz@colorcube.de>
         */
        public static function wrapJS($string, $linebreak = TRUE) {
                if (trim($string)) {
@@ -1973,7 +2073,6 @@ final class t3lib_div {
                                                                $startPoint + 1,
                                                                $key - $startPoint - 1
                                                );
-                                               #$oldtagi=array('XMLvalue'=>self::xmlRecompileFromStructValArray($partArray));
                                                $oldtagi['XMLvalue'] = self::xmlRecompileFromStructValArray($partArray);
                                        } else {
                                                $oldtagi['XMLvalue'] = $oldtagi['values'][0];
@@ -2003,16 +2102,8 @@ final class t3lib_div {
         */
        public static function array2xml_cs(array $array, $docTag = 'phparray', array $options = array(), $charset = '') {
 
-                       // Figure out charset if not given explicitly:
-               if (!$charset) {
-                       if ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']) { // First priority: forceCharset! If set, this will be authoritative!
-                               $charset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'];
-                       } elseif (is_object($GLOBALS['LANG'])) {
-                               $charset = $GLOBALS['LANG']->charSet; // If "LANG" is around, that will hold the current charset
-                       } else {
-                               $charset = 'iso-8859-1'; // THIS is just a hopeful guess!
-                       }
-               }
+                       // Set default charset unless explicitly specified
+               $charset = $charset ? $charset : 'utf-8';
 
                        // Return XML:
                return '<?xml version="1.0" encoding="' . htmlspecialchars($charset) . '" standalone="yes" ?>' . LF .
@@ -2023,9 +2114,9 @@ final class t3lib_div {
         * 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 tagnames.
+        * 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.
-        * Numeric keys are stored with the default tagname "numIndex" but can be overridden to other formats)
+        * Numeric keys are stored with the default tag name "numIndex" but can be overridden to other formats)
         * The function handles input values from the PHP array in a binary-safe way; All characters below 32 (except 9,10,13) will trigger the content to be converted to a base64-string
         * The PHP variable type of the data IS preserved as long as the types are strings, arrays, integers and booleans. Strings are the default type unless the "type" attribute is set.
         * The output XML has been tested with the PHP XML-parser and parses OK under all tested circumstances with 4.x versions. However, with PHP5 there seems to be the need to add an XML prologue a la <?xml version="1.0" encoding="[charset]" standalone="yes" ?> - otherwise UTF-8 is assumed! Unfortunately, many times the output from this function is used without adding that prologue meaning that non-ASCII characters will break the parsing!! This suchs of course! Effectively it means that the prologue should always be prepended setting the right characterset, alternatively the system should always run as utf-8!
@@ -2061,10 +2152,11 @@ final class t3lib_div {
                        $tagName = $k;
 
                                // Construct the tag name.
-                       if (isset($options['grandParentTagMap'][$stackData['grandParentTagName'] . '/' . $stackData['parentTagName']])) { // Use tag based on grand-parent + parent tag name
+                               // Use tag based on grand-parent + parent tag name
+                       if (isset($options['grandParentTagMap'][$stackData['grandParentTagName'] . '/' . $stackData['parentTagName']])) {
                                $attr .= ' index="' . htmlspecialchars($tagName) . '"';
                                $tagName = (string) $options['grandParentTagMap'][$stackData['grandParentTagName'] . '/' . $stackData['parentTagName']];
-                       } elseif (isset($options['parentTagMap'][$stackData['parentTagName'] . ':_IS_NUM']) && self::testInt($tagName)) { // Use tag based on parent tag name + if current tag is numeric
+                       } elseif (isset($options['parentTagMap'][$stackData['parentTagName'] . ':_IS_NUM']) && t3lib_utility_Math::canBeInterpretedAsInteger($tagName)) { // Use tag based on parent tag name + if current tag is numeric
                                $attr .= ' index="' . htmlspecialchars($tagName) . '"';
                                $tagName = (string) $options['parentTagMap'][$stackData['parentTagName'] . ':_IS_NUM'];
                        } elseif (isset($options['parentTagMap'][$stackData['parentTagName'] . ':' . $tagName])) { // Use tag based on parent tag name + current tag
@@ -2115,14 +2207,17 @@ final class t3lib_div {
                                                        )
                                                ) .
                                                ($spaceInd >= 0 ? str_pad('', ($level + 1) * $indentN, $indentChar) : '');
-                               if ((int) $options['disableTypeAttrib'] != 2) { // Do not set "type = array". Makes prettier XML but means that empty arrays are not restored with xml2array
+                                       // Do not set "type = array". Makes prettier XML but means that empty arrays are not restored with xml2array
+                               if ((int) $options['disableTypeAttrib'] != 2) {
                                        $attr .= ' type="array"';
                                }
                        } else { // Just a value:
 
                                        // Look for binary chars:
-                               $vLen = strlen($v); // check for length, because PHP 5.2.0 may crash when first argument of strcspn is empty
-                               if ($vLen && strcspn($v, $binaryChars) != $vLen) { // Go for base64 encoding if the initial segment NOT matching any binary char has the same length as the whole string!
+                                       // Check for length, because PHP 5.2.0 may crash when first argument of strcspn is empty
+                               $vLen = strlen($v);
+                                       // Go for base64 encoding if the initial segment NOT matching any binary char has the same length as the whole string!
+                               if ($vLen && strcspn($v, $binaryChars) != $vLen) {
                                                // If the value contained binary chars then we base64-encode it an set an attribute to notify this situation:
                                        $content = $nl . chunk_split(base64_encode($v));
                                        $attr .= ' base64="1"';
@@ -2165,18 +2260,17 @@ final class t3lib_div {
         * @param boolean $reportDocTag If set, the document tag will be set in the key "_DOCUMENT_TAG" of the output array
         * @return mixed If the parsing had errors, a string with the error message is returned. Otherwise an array with the content.
         * @see array2xml(),xml2arrayProcess()
-        * @author Fabrizio Branca <typo3@fabrizio-branca.de> (added caching)
         */
        public static function xml2array($string, $NSprefix = '', $reportDocTag = FALSE) {
                static $firstLevelCache = array();
 
                $identifier = md5($string . $NSprefix . ($reportDocTag ? '1' : '0'));
 
-                       // look up in first level cache
+                       // Look up in first level cache
                if (!empty($firstLevelCache[$identifier])) {
                        $array = $firstLevelCache[$identifier];
                } else {
-                               // look up in second level cache
+                               // Look up in second level cache
                        $cacheContent = t3lib_pageSelect::getHash($identifier, 0);
                        $array = unserialize($cacheContent);
 
@@ -2184,7 +2278,7 @@ final class t3lib_div {
                                $array = self::xml2arrayProcess($string, $NSprefix, $reportDocTag);
                                t3lib_pageSelect::storeHash($identifier, serialize($array), 'ident_xml2array');
                        }
-                               // store content in first level cache
+                               // Store content in first level cache
                        $firstLevelCache[$identifier] = $array;
                }
                return $array;
@@ -2200,7 +2294,7 @@ final class t3lib_div {
         * @return mixed If the parsing had errors, a string with the error message is returned. Otherwise an array with the content.
         * @see array2xml()
         */
-       protected function xml2arrayProcess($string, $NSprefix = '', $reportDocTag = FALSE) {
+       protected static function xml2arrayProcess($string, $NSprefix = '', $reportDocTag = FALSE) {
                        // Create parser:
                $parser = xml_parser_create();
                $vals = array();
@@ -2209,11 +2303,12 @@ final class t3lib_div {
                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!!!
+                       // Default output charset is UTF-8, only ASCII, ISO-8859-1 and UTF-8 are supported!!!
                $match = array();
                preg_match('/^[[:space:]]*<\?xml[^>]*encoding[[:space:]]*=[[:space:]]*"([^"]*)"/', substr($string, 0, 200), $match);
-               $theCharset = $match[1] ? $match[1] : ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] ? $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] : 'iso-8859-1');
-               xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $theCharset); // us-ascii / utf-8 / iso-8859-1
+               $theCharset = $match[1] ? $match[1] : 'utf-8';
+                       // us-ascii / utf-8 / iso-8859-1
+               xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $theCharset);
 
                        // Parse content:
                xml_parse_into_struct($parser, $string, $vals, $index);
@@ -2255,14 +2350,16 @@ final class t3lib_div {
                                // Setting tag-values, manage stack:
                        switch ($val['type']) {
                                case 'open': // If open tag it means there is an array stored in sub-elements. Therefore increase the stackpointer and reset the accumulation array:
-                                       $current[$tagName] = array(); // Setting blank place holder
+                                               // Setting blank place holder
+                                       $current[$tagName] = array();
                                        $stack[$stacktop++] = $current;
                                        $current = array();
                                        break;
                                case 'close': // If the tag is "close" then it is an array which is closing and we decrease the stack pointer.
                                        $oldCurrent = $current;
                                        $current = $stack[--$stacktop];
-                                       end($current); // Going to the end of array to get placeholder key, key($current), and fill in array next:
+                                               // Going to the end of array to get placeholder key, key($current), and fill in array next:
+                                       end($current);
                                        $current[key($current)] = $oldCurrent;
                                        unset($oldCurrent);
                                        break;
@@ -2270,7 +2367,8 @@ final class t3lib_div {
                                        if ($val['attributes']['base64']) {
                                                $current[$tagName] = base64_decode($val['value']);
                                        } else {
-                                               $current[$tagName] = (string) $val['value']; // Had to cast it as a string - otherwise it would be evaluate FALSE if tested with isset()!!
+                                                       // Had to cast it as a string - otherwise it would be evaluate FALSE if tested with isset()!!
+                                               $current[$tagName] = (string) $val['value'];
 
                                                        // Cast type:
                                                switch ((string) $val['attributes']['type']) {
@@ -2284,7 +2382,8 @@ final class t3lib_div {
                                                                $current[$tagName] = (bool) $current[$tagName];
                                                                break;
                                                        case 'array':
-                                                               $current[$tagName] = 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...
+                                                                       // 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();
                                                                break;
                                                }
                                        }
@@ -2312,7 +2411,7 @@ final class t3lib_div {
                foreach ($vals as $val) {
                        $type = $val['type'];
 
-                               // open tag:
+                               // Open tag:
                        if ($type == 'open' || $type == 'complete') {
                                $XMLcontent .= '<' . $val['tag'];
                                if (isset($val['attributes'])) {
@@ -2334,11 +2433,11 @@ final class t3lib_div {
                                        $XMLcontent .= htmlspecialchars($val['value']);
                                }
                        }
-                               // finish tag:
+                               // Finish tag:
                        if ($type == 'close') {
                                $XMLcontent .= '</' . $val['tag'] . '>';
                        }
-                               // cdata
+                               // Cdata
                        if ($type == 'cdata') {
                                $XMLcontent .= htmlspecialchars($val['value']);
                        }
@@ -2381,7 +2480,6 @@ final class t3lib_div {
                return $script;
        }
 
-
        /*************************
         *
         * FILES FUNCTIONS
@@ -2396,7 +2494,7 @@ final class t3lib_div {
         * @param integer $includeHeader Whether the HTTP header should be fetched or not. 0=disable, 1=fetch header+content, 2=fetch header only
         * @param array $requestHeaders HTTP headers to be used in the request
         * @param array $report Error code/message and, if $includeHeader is 1, response meta data (HTTP status and content type)
-        * @return string The content from the resource given as input. FALSE if an error has occured.
+        * @return mixed The content from the resource given as input. FALSE if an error has occured.
         */
        public static function getUrl($url, $includeHeader = 0, $requestHeaders = FALSE, &$report = NULL) {
                $content = FALSE;
@@ -2406,15 +2504,14 @@ final class t3lib_div {
                        $report['message'] = '';
                }
 
-                       // use cURL for: http, https, ftp, ftps, sftp and scp
+                       // 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.
-                       $ch = curl_init();
-                       if (!$ch) {
+                       if (!function_exists('curl_init') || !($ch = curl_init())) {
                                if (isset($report)) {
                                        $report['error'] = -1;
                                        $report['message'] = 'Couldn\'t initialize cURL.';
@@ -2490,7 +2587,6 @@ final class t3lib_div {
                                }
                        }
                        $errno = 0;
-                               // $errstr = '';
                        $fp = @fsockopen($scheme . $parsedURL['host'], $port, $errno, $errstr, 2.0);
                        if (!$fp || $errno > 0) {
                                if (isset($report)) {
@@ -2522,7 +2618,8 @@ final class t3lib_div {
                                }
                                $content .= $line;
                                if (!strlen(trim($line))) {
-                                       break; // Stop at the first empty line (= end of header)
+                                               // Stop at the first empty line (= end of header)
+                                       break;
                                }
                        }
                        if ($includeHeader != 2) {
@@ -2548,26 +2645,23 @@ final class t3lib_div {
                                )
                        )
                        );
+
                        $content = @file_get_contents($url, FALSE, $ctx);
+
                        if ($content === FALSE && isset($report)) {
-                               $phpError = error_get_last();
-                               $report['error'] = $phpError['type'];
-                               $report['message'] = $phpError['message'];
+                               $report['error'] = -1;
+                               $report['message'] = 'Couldn\'t get URL: ' . implode(LF, $http_response_header);
                        }
                } else {
                        if (isset($report)) {
                                $report['lib'] = 'file';
                        }
+
                        $content = @file_get_contents($url);
+
                        if ($content === FALSE && isset($report)) {
-                               if (function_exists('error_get_last')) {
-                                       $phpError = error_get_last();
-                                       $report['error'] = $phpError['type'];
-                                       $report['message'] = $phpError['message'];
-                               } else {
-                                       $report['error'] = -1;
-                                       $report['message'] = 'Couldn\'t get URL.';
-                               }
+                               $report['error'] = -1;
+                               $report['message'] = 'Couldn\'t get URL: ' . implode(LF, $http_response_header);
                        }
                }
 
@@ -2594,7 +2688,8 @@ final class t3lib_div {
                                return FALSE;
                        }
 
-                       if ($changePermissions) { // Change the permissions only if the file has just been created
+                               // Change the permissions only if the file has just been created
+                       if ($changePermissions) {
                                self::fixPermissions($file);
                        }
 
@@ -2665,7 +2760,7 @@ final class t3lib_div {
         * Writes $content to a filename in the typo3temp/ folder (and possibly one or two subfolders...)
         * Accepts an additional subdirectory in the file path!
         *
-        * @param string $filepath Absolute filepath to write to inside "typo3temp/". First part of this string must match PATH_site."typo3temp/"
+        * @param string $filepath Absolute file path to write to inside "typo3temp/". First part of this string must match PATH_site."typo3temp/"
         * @param string $content Content string to write
         * @return string Returns NULL on success, otherwise an error string telling about the problem.
         */
@@ -2678,7 +2773,8 @@ final class t3lib_div {
                        // Check parts:
                if (self::validPathStr($filepath) && $fI['basename'] && strlen($fI['basename']) < 60) {
                        if (defined('PATH_site')) {
-                               $dirName = PATH_site . 'typo3temp/'; // Setting main temporary directory name (standard)
+                                       // Setting main temporary directory name (standard)
+                               $dirName = PATH_site . 'typo3temp/';
                                if (@is_dir($dirName)) {
                                        if (self::isFirstPartOfStr($fI['dirname'], $dirName)) {
 
@@ -2699,7 +2795,7 @@ final class t3lib_div {
                                                        if ($filepath == $dirName . $fI['basename']) {
                                                                self::writeFile($filepath, $content);
                                                                if (!@is_file($filepath)) {
-                                                                       return 'File not written to disk! Write permission error in filesystem?';
+                                                                       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!';
@@ -2768,18 +2864,41 @@ final class t3lib_div {
 
                $fullPath = $directory . $deepDirectory;
                if (!is_dir($fullPath) && strlen($fullPath) > 0) {
-                       @mkdir(
-                               $fullPath,
-                               octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']),
-                               TRUE
-                       );
-                       if (!is_dir($fullPath)) {
-                               throw new \RuntimeException(
-                                       'Could not create directory!',
-                                       1170251400
-                               );
+                       $firstCreatedPath = self::createDirectoryPath($fullPath);
+                       if ($firstCreatedPath !== '') {
+                               self::fixPermissions($firstCreatedPath, TRUE);
+                       }
+               }
+       }
+
+       /**
+        * Creates directories for the specified paths if they do not exist. This
+        * functions sets proper permission mask but does not set proper user and
+        * group.
+        *
+        * @static
+        * @param string $fullDirectoryPath
+        * @return string Path to the the first created directory in the hierarchy
+        * @see t3lib_div::mkdir_deep
+        * @throws \RuntimeException If directory could not be created
+        */
+       protected static function createDirectoryPath($fullDirectoryPath) {
+               $currentPath = $fullDirectoryPath;
+               $firstCreatedPath = '';
+               $permissionMask = octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']);
+               if (!@is_dir($currentPath)) {
+                       do {
+                               $firstCreatedPath = $currentPath;
+                               $separatorPosition = strrpos($currentPath, DIRECTORY_SEPARATOR);
+                               $currentPath = substr($currentPath, 0, $separatorPosition);
+                       } while (!is_dir($currentPath) && $separatorPosition !== FALSE);
+
+                       $result = @mkdir($fullDirectoryPath, $permissionMask, TRUE);
+                       if (!$result) {
+                               throw new \RuntimeException('Could not create directory!', 1170251400);
                        }
                }
+               return $firstCreatedPath;
        }
 
        /**
@@ -2791,7 +2910,8 @@ final class t3lib_div {
         */
        public static function rmdir($path, $removeNonEmpty = FALSE) {
                $OK = FALSE;
-               $path = preg_replace('|/$|', '', $path); // Remove trailing slash
+                       // Remove trailing slash
+               $path = preg_replace('|/$|', '', $path);
 
                if (file_exists($path)) {
                        $OK = TRUE;
@@ -2849,14 +2969,15 @@ final class t3lib_div {
         *
         * @param string $path Is the path to the file
         * @param string $extensionList is the comma list of extensions to read only (blank = all)
-        * @param boolean $prependPath If set, then the path is prepended the filenames. Otherwise only the filenames are returned in the array
+        * @param boolean $prependPath If set, then the path is prepended the file names. Otherwise only the file names are returned in the array
         * @param string $order is sorting: 1= sort alphabetically, 'mtime' = sort by modification time.
-        * @param string $excludePattern A comma seperated list of filenames to exclude, no wildcards
+        *
+        * @param string $excludePattern A comma separated list of file names to exclude, no wildcards
         * @return array Array of the files found
         */
        public static function getFilesInDir($path, $extensionList = '', $prependPath = FALSE, $order = '', $excludePattern = '') {
 
-                       // Initialize variabels:
+                       // Initialize variables:
                $filearray = array();
                $sortarray = array();
                $path = rtrim($path, '/');
@@ -2869,14 +2990,15 @@ final class t3lib_div {
                                while ($entry = $d->read()) {
                                        if (@is_file($path . '/' . $entry)) {
                                                $fI = pathinfo($entry);
-                                               $key = md5($path . '/' . $entry); // Don't change this ever - extensions may depend on the fact that the hash is an md5 of the path! (import/export extension)
+                                                       // Don't change this ever - extensions may depend on the fact that the hash is an md5 of the path! (import/export extension)
+                                               $key = md5($path . '/' . $entry);
                                                if ((!strlen($extensionList) || self::inList($extensionList, strtolower($fI['extension']))) && (!strlen($excludePattern) || !preg_match('/^' . $excludePattern . '$/', $entry))) {
                                                        $filearray[$key] = ($prependPath ? $path . '/' : '') . $entry;
                                                        if ($order == 'mtime') {
                                                                $sortarray[$key] = filemtime($path . '/' . $entry);
                                                        }
                                                        elseif ($order) {
-                                                               $sortarray[$key] = $entry;
+                                                               $sortarray[$key] = strtolower($entry);
                                                        }
                                                }
                                        }
@@ -2933,8 +3055,8 @@ final class t3lib_div {
        /**
         * Removes the absolute part of all files/folders in fileArr
         *
-        * @param array $fileArr: The file array to remove the prefix from
-        * @param string $prefixToRemove: The prefix path to remove (if found as first part of string!)
+        * @param array $fileArr The file array to remove the prefix from
+        * @param string $prefixToRemove The prefix path to remove (if found as first part of string!)
         * @return array The input $fileArr processed.
         */
        public static function removePrefixPathFromList(array $fileArr, $prefixToRemove) {
@@ -2997,7 +3119,8 @@ final class t3lib_div {
         */
        public static function locationHeaderUrl($path) {
                $uI = parse_url($path);
-               if (substr($path, 0, 1) == '/') { // relative to HOST
+                       // relative to HOST
+               if (substr($path, 0, 1) == '/') {
                        $path = self::getIndpEnv('TYPO3_REQUEST_HOST') . $path;
                } elseif (!$uI['scheme']) { // No scheme either
                        $path = self::getIndpEnv('TYPO3_REQUEST_DIR') . $path;
@@ -3011,47 +3134,42 @@ final class t3lib_div {
         * TYPO3 installation. The first parameter can be used to set something that overrides
         * the maxFileSize, usually for the TCA values.
         *
-        * @param integer $localLimit: the number of Kilobytes (!) that should be used as
+        * @param integer $localLimit the number of Kilobytes (!) that should be used as
         *                                              the initial Limit, otherwise $GLOBALS['TYPO3_CONF_VARS']['BE']['maxFileSize'] will be used
-        * @return integer the maximum size of uploads that are allowed (measuered in kilobytes)
+        * @return integer The maximum size of uploads that are allowed (measured in kilobytes)
         */
        public static function getMaxUploadFileSize($localLimit = 0) {
-                       // don't allow more than the global max file size at all
+                       // Don't allow more than the global max file size at all
                $t3Limit = (intval($localLimit > 0 ? $localLimit : $GLOBALS['TYPO3_CONF_VARS']['BE']['maxFileSize']));
-                       // as TYPO3 is handling the file size in KB, multiply by 1024 to get bytes
+                       // As TYPO3 is handling the file size in KB, multiply by 1024 to get bytes
                $t3Limit = $t3Limit * 1024;
 
-                       // check for PHP restrictions of the maximum size of one of the $_FILES
+                       // Check for PHP restrictions of the maximum size of one of the $_FILES
                $phpUploadLimit = self::getBytesFromSizeMeasurement(ini_get('upload_max_filesize'));
-                       // check for PHP restrictions of the maximum $_POST size
+                       // Check for PHP restrictions of the maximum $_POST size
                $phpPostLimit = self::getBytesFromSizeMeasurement(ini_get('post_max_size'));
-                       // if the total amount of post data is smaller (!) than the upload_max_filesize directive,
+                       // If the total amount of post data is smaller (!) than the upload_max_filesize directive,
                        // then this is the real limit in PHP
                $phpUploadLimit = ($phpPostLimit < $phpUploadLimit ? $phpPostLimit : $phpUploadLimit);
 
-                       // is the allowed PHP limit (upload_max_filesize) lower than the TYPO3 limit?, also: revert back to KB
+                       // Is the allowed PHP limit (upload_max_filesize) lower than the TYPO3 limit?, also: revert back to KB
                return floor($phpUploadLimit < $t3Limit ? $phpUploadLimit : $t3Limit) / 1024;
        }
 
        /**
         * Gets the bytes value from a measurement string like "100k".
         *
-        * @param string $measurement: The measurement (e.g. "100k")
+        * @param string $measurement The measurement (e.g. "100k")
         * @return integer The bytes value (e.g. 102400)
         */
        public static function getBytesFromSizeMeasurement($measurement) {
+               $bytes = doubleval($measurement);
                if (stripos($measurement, 'G')) {
-                       $bytes = doubleval($measurement) * 1024 * 1024 * 1024;
-               } else {
-                       if (stripos($measurement, 'M')) {
-                               $bytes = doubleval($measurement) * 1024 * 1024;
-                       } else {
-                               if (stripos($measurement, 'K')) {
-                                       $bytes = doubleval($measurement) * 1024;
-                               } else {
-                                       $bytes = doubleval($measurement);
-                               }
-                       }
+                       $bytes *= 1024 * 1024 * 1024;
+               } elseif (stripos($measurement, 'M')) {
+                       $bytes *= 1024 * 1024;
+               } elseif (stripos($measurement, 'K')) {
+                       $bytes *= 1024;
                }
                return $bytes;
        }
@@ -3060,13 +3178,11 @@ final class t3lib_div {
         * Retrieves the maximum path length that is valid in the current environment.
         *
         * @return integer The maximum available path length
-        * @author Ingo Renner <ingo@typo3.org>
         */
        public static function getMaximumPathLength() {
                return PHP_MAXPATHLEN;
        }
 
-
        /**
         * Function for static version numbers on files, based on the filemtime
         *
@@ -3083,7 +3199,6 @@ final class t3lib_div {
         * @param string $file Relative path to file including all potential query parameters (not htmlspecialchared yet)
         * @param boolean $forceQueryString If settings would suggest to embed in filename, this parameter allows us to force the versioning to occur in the query string. This is needed for scriptaculous.js which cannot have a different filename in order to load its modules (?load=...)
         * @return Relative path with version filename including the timestamp
-        * @author Lars Houmark <lars@houmark.com>
         */
        public static function createVersionNumberedFilename($file, $forceQueryString = FALSE) {
                $lookupFile = explode('?', $file);
@@ -3126,7 +3241,7 @@ final class t3lib_div {
 
                                array_push($name, filemtime($path), $extension);
                                $fullName = implode('.', $name);
-                                       // append potential query string
+                                       // Append potential query string
                                $fullName .= $lookupFile[1] ? '?' . $lookupFile[1] : '';
                        }
                }
@@ -3134,99 +3249,6 @@ final class t3lib_div {
                return $fullName;
        }
 
-
-       /*************************
-        *
-        * DEBUG helper FUNCTIONS
-        *
-        *************************/
-
-       /* Deprecated since 4.5, use t3lib_utility_Debug */
-
-
-       /**
-        * Returns a string with a list of ascii-values for the first $characters characters in $string
-        *
-        * @param string $string String to show ASCII value for
-        * @param integer $characters Number of characters to show
-        * @return string The string with ASCII values in separated by a space char.
-        * @deprecated since TYPO3 4.5 - Use t3lib_utility_Debug::ordinalValue instead
-        */
-       public static function debug_ordvalue($string, $characters = 100) {
-               self::logDeprecatedFunction();
-               return t3lib_utility_Debug::ordinalValue($string, $characters);
-       }
-
-       /**
-        * Returns HTML-code, which is a visual representation of a multidimensional array
-        * use t3lib_div::print_array() in order to print an array
-        * Returns FALSE if $array_in is not an array
-        *
-        * @param mixed $array_in Array to view
-        * @return string HTML output
-        * @deprecated since TYPO3 4.5 - Use t3lib_utility_Debug::viewArray instead
-        */
-       public static function view_array($array_in) {
-               self::logDeprecatedFunction();
-               return t3lib_utility_Debug::viewArray($array_in);
-       }
-
-       /**
-        * Prints an array
-        *
-        * @param mixed $array_in Array to print visually (in a table).
-        * @return void
-        * @see view_array()
-        * @deprecated since TYPO3 4.5 - Use t3lib_utility_Debug::printArray instead
-        */
-       public static function print_array($array_in) {
-               self::logDeprecatedFunction();
-               t3lib_utility_Debug::printArray($array_in);
-       }
-
-       /**
-        * Makes debug output
-        * Prints $var in bold between two vertical lines
-        * If not $var the word 'debug' is printed
-        * If $var is an array, the array is printed by t3lib_div::print_array()
-        *
-        * @param mixed $var Variable to print
-        * @param string $header The header.
-        * @param string $group Group for the debug console
-        * @return void
-        * @deprecated since TYPO3 4.5 - Use t3lib_utility_Debug::debug instead
-        */
-       public static function debug($var = '', $header = '', $group = 'Debug') {
-               self::logDeprecatedFunction();
-               t3lib_utility_Debug::debug($var, $header, $group);
-       }
-
-       /**
-        * Displays the "path" of the function call stack in a string, using debug_backtrace
-        *
-        * @return string
-        * @deprecated since TYPO3 4.5 - Use t3lib_utility_Debug::debugTrail instead
-        */
-       public static function debug_trail() {
-               self::logDeprecatedFunction();
-               return t3lib_utility_Debug::debugTrail();
-       }
-
-       /**
-        * Displays an array as rows in a table. Useful to debug output like an array of database records.
-        *
-        * @param mixed $rows Array of arrays with similar keys
-        * @param string $header Table header
-        * @param boolean $returnHTML If TRUE, will return content instead of echo'ing out.
-        * @return mixed Outputs to browser or returns an HTML string if $returnHTML is TRUE
-        * @deprecated since TYPO3 4.5 - Use t3lib_utility_Debug::debugRows instead
-        */
-       public static function debugRows($rows, $header = '', $returnHTML = FALSE) {
-               self::logDeprecatedFunction();
-               return t3lib_utility_Debug::debugRows($rows, $header, $returnHTML);
-       }
-
-
        /*************************
         *
         * SYSTEM INFORMATION
@@ -3239,7 +3261,8 @@ final class t3lib_div {
         * @return string
         */
        public static function getThisUrl() {
-               $p = parse_url(self::getIndpEnv('TYPO3_REQUEST_SCRIPT')); // Url of this script
+                       // Url of this script
+               $p = parse_url(self::getIndpEnv('TYPO3_REQUEST_SCRIPT'));
                $dir = self::dirname($p['path']) . '/'; // Strip file
                $url = str_replace('//', '/', $p['host'] . ($p['port'] ? ':' . $p['port'] : '') . $dir);
                return $url;
@@ -3319,7 +3342,6 @@ final class t3lib_div {
                                                                        [path_info] = '/arg1/arg2/arg3/'
                                                                        [path] = [path_script/path_dir][path_info]
 
-
                        Keys supported:
 
                        URI______:
@@ -3356,16 +3378,12 @@ final class t3lib_div {
 
                        Notice: [fragment] is apparently NEVER available to the script!
 
-
                        Testing suggestions:
                        - Output all the values.
                        - In the script, make a link to the script it self, maybe add some parameters and click the link a few times so HTTP_REFERER is seen
                        - ALSO TRY the script from the ROOT of a site (like 'http://www.mytest.com/' and not 'http://www.mytest.com/test/' !!)
-
                */
 
-               #               if ($getEnvName=='HTTP_REFERER')        return '';
-
                $retVal = '';
 
                switch ((string) $getEnvName) {
@@ -3374,7 +3392,7 @@ final class t3lib_div {
                                                ($_SERVER['ORIG_PATH_INFO'] ? $_SERVER['ORIG_PATH_INFO'] : $_SERVER['PATH_INFO']) ?
                                                ($_SERVER['ORIG_PATH_INFO'] ? $_SERVER['ORIG_PATH_INFO'] : $_SERVER['PATH_INFO']) :
                                                ($_SERVER['ORIG_SCRIPT_NAME'] ? $_SERVER['ORIG_SCRIPT_NAME'] : $_SERVER['SCRIPT_NAME']);
-                                       // add a prefix if TYPO3 is behind a proxy: ext-domain.com => int-server.com/prefix
+                                       // Add a prefix if TYPO3 is behind a proxy: ext-domain.com => int-server.com/prefix
                                if (self::cmpIP($_SERVER['REMOTE_ADDR'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP'])) {
                                        if (self::getIndpEnv('TYPO3_SSL') && $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyPrefixSSL']) {
                                                $retVal = $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyPrefixSSL'] . $retVal;
@@ -3384,12 +3402,7 @@ final class t3lib_div {
                                }
                                break;
                        case 'SCRIPT_FILENAME':
-                               $retVal = str_replace('//', '/', str_replace('\\', '/',
-                                       (PHP_SAPI == 'fpm-fcgi' || PHP_SAPI == 'cgi' || PHP_SAPI == 'isapi' || PHP_SAPI == 'cgi-fcgi') &&
-                                                       ($_SERVER['ORIG_PATH_TRANSLATED'] ? $_SERVER['ORIG_PATH_TRANSLATED'] : $_SERVER['PATH_TRANSLATED']) ?
-                                                       ($_SERVER['ORIG_PATH_TRANSLATED'] ? $_SERVER['ORIG_PATH_TRANSLATED'] : $_SERVER['PATH_TRANSLATED']) :
-                                                       ($_SERVER['ORIG_SCRIPT_FILENAME'] ? $_SERVER['ORIG_SCRIPT_FILENAME'] : $_SERVER['SCRIPT_FILENAME'])));
-
+                               $retVal = PATH_thisScript;
                                break;
                        case 'REQUEST_URI':
                                        // Typical application of REQUEST_URI is return urls, forms submitting to itself etc. Example: returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'))
@@ -3402,7 +3415,7 @@ final class t3lib_div {
                                } else {
                                        $retVal = $_SERVER['REQUEST_URI'];
                                }
-                                       // add a prefix if TYPO3 is behind a proxy: ext-domain.com => int-server.com/prefix
+                                       // Add a prefix if TYPO3 is behind a proxy: ext-domain.com => int-server.com/prefix
                                if (self::cmpIP($_SERVER['REMOTE_ADDR'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP'])) {
                                        if (self::getIndpEnv('TYPO3_SSL') && $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyPrefixSSL']) {
                                                $retVal = $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyPrefixSSL'] . $retVal;
@@ -3415,7 +3428,6 @@ final class t3lib_div {
                                        // $_SERVER['PATH_INFO']!=$_SERVER['SCRIPT_NAME'] is necessary because some servers (Windows/CGI) are seen to set PATH_INFO equal to script_name
                                        // Further, there must be at least one '/' in the path - else the PATH_INFO value does not make sense.
                                        // IF 'PATH_INFO' never works for our purpose in TYPO3 with CGI-servers, then 'PHP_SAPI=='cgi'' might be a better check. Right now strcmp($_SERVER['PATH_INFO'],t3lib_div::getIndpEnv('SCRIPT_NAME')) will always return FALSE for CGI-versions, but that is only as long as SCRIPT_NAME is set equal to PATH_INFO because of PHP_SAPI=='cgi' (see above)
-                                       //                              if (strcmp($_SERVER['PATH_INFO'],self::getIndpEnv('SCRIPT_NAME')) && count(explode('/',$_SERVER['PATH_INFO']))>1)       {
                                if (PHP_SAPI != 'cgi' && PHP_SAPI != 'cgi-fcgi' && PHP_SAPI != 'fpm-fcgi') {
                                        $retVal = $_SERVER['PATH_INFO'];
                                }
@@ -3427,7 +3439,7 @@ final class t3lib_div {
                                $retVal = $_SERVER['REMOTE_ADDR'];
                                if (self::cmpIP($_SERVER['REMOTE_ADDR'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP'])) {
                                        $ip = self::trimExplode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
-                                               // choose which IP in list to use
+                                               // Choose which IP in list to use
                                        if (count($ip)) {
                                                switch ($GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyHeaderMultiValue']) {
                                                        case 'last':
@@ -3451,7 +3463,7 @@ final class t3lib_div {
                                $retVal = $_SERVER['HTTP_HOST'];
                                if (self::cmpIP($_SERVER['REMOTE_ADDR'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP'])) {
                                        $host = self::trimExplode(',', $_SERVER['HTTP_X_FORWARDED_HOST']);
-                                               // choose which host in list to use
+                                               // Choose which host in list to use
                                        if (count($host)) {
                                                switch ($GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyHeaderMultiValue']) {
                                                        case 'last':
@@ -3478,7 +3490,10 @@ final class t3lib_div {
                        case 'HTTP_ACCEPT_LANGUAGE':
                        case 'REMOTE_HOST':
                        case 'QUERY_STRING':
-                               $retVal = $_SERVER[$getEnvName];
+                               $retVal = '';
+                               if (isset($_SERVER[$getEnvName])) {
+                                       $retVal = $_SERVER[$getEnvName];
+                               }
                                break;
                        case 'TYPO3_DOCUMENT_ROOT':
                                        // Get the web root (it is not the root of the TYPO3 installation)
@@ -3505,7 +3520,8 @@ final class t3lib_div {
                        case 'TYPO3_HOST_ONLY':
                                $httpHost = self::getIndpEnv('HTTP_HOST');
                                $httpHostBracketPosition = strpos($httpHost, ']');
-                               $retVal = ($httpHostBracketPosition !== FALSE) ? substr($httpHost, 0, ($httpHostBracketPosition + 1)) : array_shift(explode(':', $httpHost));
+                               $httpHostParts = explode(':', $httpHost);
+                               $retVal = ($httpHostBracketPosition !== FALSE) ? substr($httpHost, 0, ($httpHostBracketPosition + 1)) : array_shift($httpHostParts);
                                break;
                        case 'TYPO3_PORT':
                                $httpHost = self::getIndpEnv('HTTP_HOST');
@@ -3547,7 +3563,7 @@ final class t3lib_div {
                                if ($proxySSL == '*') {
                                        $proxySSL = $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP'];
                                }
-                               if (self::cmpIP($_SERVER['REMOTE_ADDR'], $proxySSL)) {
+                               if (self::cmpIP(self::getIndpEnv('REMOTE_ADDR'), $proxySSL)) {
                                        $retVal = TRUE;
                                } else {
                                        $retVal = $_SERVER['SSL_SESSION_ID'] || !strcasecmp($_SERVER['HTTPS'], 'on') || !strcmp($_SERVER['HTTPS'], '1') ? TRUE : FALSE; // see http://bugs.typo3.org/view.php?id=3909
@@ -3622,7 +3638,9 @@ final class t3lib_div {
                } elseif (strpos($useragent, 'Flash') !== FALSE) {
                        $bInfo['BROWSER'] = 'flash';
                }
-               if ($bInfo['BROWSER']) {
+
+               $bInfo['FORMSTYLE'] = FALSE;
+               if (isset($bInfo['BROWSER'])) {
                                // Browser version
                        switch ($bInfo['BROWSER']) {
                                case 'net':
@@ -3650,7 +3668,7 @@ final class t3lib_div {
                                        $bInfo['VERSION'] = doubleval(substr($tmp, 10));
                                        break;
                        }
-                       // Client system
+                               // Client system
                        if (strpos($useragent, 'Win') !== FALSE) {
                                $bInfo['SYSTEM'] = 'win';
                        } elseif (strpos($useragent, 'Mac') !== FALSE) {
@@ -3658,9 +3676,10 @@ final class t3lib_div {
                        } elseif (strpos($useragent, 'Linux') !== FALSE || strpos($useragent, 'X11') !== FALSE || strpos($useragent, 'SGI') !== FALSE || strpos($useragent, ' SunOS ') !== FALSE || strpos($useragent, ' HP-UX ') !== FALSE) {
                                $bInfo['SYSTEM'] = 'unix';
                        }
+
+                               // Is TRUE if the browser supports css to format forms, especially the width
+                       $bInfo['FORMSTYLE'] = ($bInfo['BROWSER'] == 'msie' || ($bInfo['BROWSER'] == 'net' && $bInfo['VERSION'] >= 5) || $bInfo['BROWSER'] == 'opera' || $bInfo['BROWSER'] == 'konqu');
                }
-               // Is TRUE if the browser supports css to format forms, especially the width
-               $bInfo['FORMSTYLE'] = ($bInfo['BROWSER'] == 'msie' || ($bInfo['BROWSER'] == 'net' && $bInfo['VERSION'] >= 5) || $bInfo['BROWSER'] == 'opera' || $bInfo['BROWSER'] == 'konqu');
 
                return $bInfo;
        }
@@ -3686,10 +3705,10 @@ final class t3lib_div {
                                $host = '';
                        }
                }
-                       // we have not found a FQDN yet
+                       // We have not found a FQDN yet
                if ($host && strpos($host, '.') === FALSE) {
                        $ip = gethostbyname($host);
-                               // we got an IP address
+                               // We got an IP address
                        if ($ip != $host) {
                                $fqdn = gethostbyaddr($ip);
                                if ($ip != $fqdn) {
@@ -3704,7 +3723,6 @@ final class t3lib_div {
                return $host;
        }
 
-
        /*************************
         *
         * TYPO3 SPECIFIC FUNCTIONS
@@ -3732,7 +3750,8 @@ final class t3lib_div {
                } else {
                        $relPathPrefix = PATH_site;
                }
-               if (substr($filename, 0, 4) == 'EXT:') { // extension
+                       // Extension
+               if (substr($filename, 0, 4) == 'EXT:') {
                        list($extKey, $local) = explode('/', substr($filename, 4), 2);
                        $filename = '';
                        if (strcmp($extKey, '') && t3lib_extMgm::isLoaded($extKey) && strcmp($local, '')) {
@@ -3755,31 +3774,39 @@ final class t3lib_div {
         * This should make sure that the path is not pointing 'backwards' and further doesn't contain double/back slashes.
         * So it's compatible with the UNIX style path strings valid for TYPO3 internally.
         *
-        * @param string $theFile Filepath to evaluate
-        * @return boolean TRUE, $theFile is allowed path string
+        * @param string $theFile File path to evaluate
+        * @return boolean 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 ?
+        * @todo Possible improvement: Should it rawurldecode the string first to check if any of these characters is encoded?
         */
        public static function validPathStr($theFile) {
-               if (strpos($theFile, '//') === FALSE && strpos($theFile, '\\') === FALSE && !preg_match('#(?:^\.\.|/\.\./|[[:cntrl:]])#', $theFile)) {
+               if (strpos($theFile, '//') === FALSE && strpos($theFile, '\\') === FALSE && !preg_match('#(?:^\.\.|/\.\./|[[:cntrl:]])#u', $theFile)) {
                        return TRUE;
                }
+
+               return FALSE;
        }
 
        /**
         * Checks if the $path is absolute or relative (detecting either '/' or 'x:/' as first part of string) and returns TRUE if so.
         *
-        * @param string $path Filepath to evaluate
+        * @param string $path File path to evaluate
         * @return boolean
         */
        public static function isAbsPath($path) {
-               return TYPO3_OS == 'WIN' ? substr($path, 1, 2) == ':/' : substr($path, 0, 1) == '/';
+                       // On Windows also a path starting with a drive letter is absolute: X:/
+               if (TYPO3_OS === 'WIN' && substr($path, 1, 2) === ':/') {
+                       return TRUE;
+               }
+
+                       // Path starting with a / is always absolute, on every system
+               return (substr($path, 0, 1) === '/');
        }
 
        /**
         * Returns TRUE if the path is absolute, without backpath '..' and within the PATH_site OR within the lockRootPath
         *
-        * @param string $path Filepath to evaluate
+        * @param string $path File path to evaluate
         * @return boolean
         */
        public static function isAllowedAbsPath($path) {
@@ -3795,9 +3822,9 @@ final class t3lib_div {
        }
 
        /**
-        * Verifies the input filename againts the 'fileDenyPattern'. Returns TRUE if OK.
+        * Verifies the input filename against the 'fileDenyPattern'. Returns TRUE if OK.
         *
-        * @param string $filename Filepath to evaluate
+        * @param string $filename File path to evaluate
         * @return boolean
         */
        public static function verifyFilenameAgainstDenyPattern($filename) {
@@ -3876,7 +3903,8 @@ final class t3lib_div {
                        @copy($source, $destination);
                }
 
-               self::fixPermissions($destination); // Change the permissions of the file
+                       // 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;
@@ -3918,7 +3946,7 @@ final class t3lib_div {
 
        /**
         * Create temporary filename (Create file with unique file name)
-        * This function should be used for getting temporary filenames - will make your applications safe for open_basedir = on
+        * This function should be used for getting temporary file names - will make your applications safe for open_basedir = on
         * REMEMBER to delete the temporary files after use! This is done by t3lib_div::unlink_tempfile()
         *
         * @param string $filePrefix Prefix to temp file (which will have no extension btw)
@@ -3966,18 +3994,16 @@ final class t3lib_div {
         * @param string $addQueryParams Query-parameters: "&xxx=yyy&zzz=uuu"
         * @return array Array with key/value pairs of query-parameters WITHOUT a certain list of variable names (like id, type, no_cache etc.) and WITH a variable, encryptionKey, specific for this server/installation
         * @see tslib_fe::makeCacheHash(), tslib_cObj::typoLink(), t3lib_div::calculateCHash()
+        * @deprecated since TYPO3 4.7 - will be removed in TYPO3 4.9 - use t3lib_cacheHash instead
         */
        public static function cHashParams($addQueryParams) {
-               $params = explode('&', substr($addQueryParams, 1)); // Splitting parameters up
+               self::logDeprecatedFunction();
+                       // Splitting parameters up
+               $params = explode('&', substr($addQueryParams, 1));
+               /* @var $cacheHash t3lib_cacheHash */
+               $cacheHash = self::makeInstance('t3lib_cacheHash');
+               $pA = $cacheHash->getRelevantParameters($addQueryParams);
 
-                       // Make array:
-               $pA = array();
-               foreach ($params as $theP) {
-                       $pKV = explode('=', $theP); // Splitting single param by '=' sign
-                       if (!self::inList('id,type,no_cache,cHash,MP,ftu', $pKV[0]) && !preg_match('/TSFE_ADMIN_PANEL\[.*?\]/', $pKV[0])) {
-                               $pA[rawurldecode($pKV[0])] = (string) rawurldecode($pKV[1]);
-                       }
-               }
                        // Hook: Allows to manipulate the parameters which are taken to build the chash:
                if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['cHashParamsHook'])) {
                        $cHashParamsHook =& $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['cHashParamsHook'];
@@ -3993,9 +4019,6 @@ final class t3lib_div {
                                }
                        }
                }
-                       // Finish and sort parameters array by keys:
-               $pA['encryptionKey'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'];
-               ksort($pA);
 
                return $pA;
        }
@@ -4006,11 +4029,13 @@ final class t3lib_div {
         * @param string $addQueryParams Query-parameters: "&xxx=yyy&zzz=uuu"
         * @return string Hash of all the values
         * @see t3lib_div::cHashParams(), t3lib_div::calculateCHash()
+        * @deprecated since TYPO3 4.7 - will be removed in TYPO3 6.1 - use t3lib_cacheHash instead
         */
        public static function generateCHash($addQueryParams) {
-               $cHashParams = self::cHashParams($addQueryParams);
-               $cHash = self::calculateCHash($cHashParams);
-               return $cHash;
+               self::logDeprecatedFunction();
+               /* @var $cacheHash t3lib_cacheHash */
+               $cacheHash = self::makeInstance('t3lib_cacheHash');
+               return $cacheHash->generateForParameters($addQueryParams);
        }
 
        /**
@@ -4018,10 +4043,13 @@ final class t3lib_div {
         *
         * @param array $params Array of key-value pairs
         * @return string Hash of all the values
+        * @deprecated since TYPO3 4.7 - will be removed in TYPO3 4.9 - use t3lib_cacheHash instead
         */
        public static function calculateCHash($params) {
-               $cHash = md5(serialize($params));
-               return $cHash;
+               self::logDeprecatedFunction();
+               /* @var $cacheHash t3lib_cacheHash */
+               $cacheHash = self::makeInstance('t3lib_cacheHash');
+               return $cacheHash->calculateCacheHash($params);
        }
 
        /**
@@ -4039,6 +4067,17 @@ final class t3lib_div {
        }
 
        /**
+        * Returns true if the "l18n_cfg" field value is not set to hide
+        * pages in the default language
+        *
+        * @param integer $localizationConfiguration
+        * @return boolean
+        */
+       public static function hideIfDefaultLanguage($localizationConfiguration) {
+               return ($localizationConfiguration & 1);
+       }
+
+       /**
         * Includes a locallang file and returns the $LOCAL_LANG array found inside.
         *
         * @param string $fileRef Input is a file-reference (see t3lib_div::getFileAbsFileName). That file is expected to be a 'locallang.php' file containing a $LOCAL_LANG array (will be included!) or a 'locallang.xml' file conataining a valid XML TYPO3 language structure.
@@ -4050,287 +4089,40 @@ final class t3lib_div {
         */
        public static function readLLfile($fileRef, $langKey, $charset = '', $errorMode = 0) {
                /** @var $languageFactory t3lib_l10n_Factory */
-               $languageFactory = t3lib_div::makeInstance('t3lib_l10n_Factory');
+               $languageFactory = self::makeInstance('t3lib_l10n_Factory');
                return $languageFactory->getParsedData($fileRef, $langKey, $charset, $errorMode);
        }
 
        /**
-        * Includes a locallang-php file and returns the $LOCAL_LANG array
-        * Works only when the frontend or backend has been initialized with a charset conversion object. See first code lines.
-        *
-        * @param string $fileRef Absolute reference to locallang-PHP file
-        * @param string $langKey TYPO3 language key, eg. "dk" or "de" or "default"
-        * @param string $charset Character set (optional)
-        * @return array LOCAL_LANG array in return.
-        * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - use tx_lang_parser_Llphp::getParsedData() from now on
-        */
-       public static function readLLPHPfile($fileRef, $langKey, $charset = '') {
-               t3lib_div::logDeprecatedFunction();
-
-               if (is_object($GLOBALS['LANG'])) {
-                       $csConvObj = $GLOBALS['LANG']->csConvObj;
-               } elseif (is_object($GLOBALS['TSFE'])) {
-                       $csConvObj = $GLOBALS['TSFE']->csConvObj;
-               } else {
-                       $csConvObj = self::makeInstance('t3lib_cs');
-               }
-
-               if (@is_file($fileRef) && $langKey) {
-
-                               // Set charsets:
-                       $sourceCharset = $csConvObj->parse_charset($csConvObj->charSetArray[$langKey] ? $csConvObj->charSetArray[$langKey] : 'iso-8859-1');
-                       if ($charset) {
-                               $targetCharset = $csConvObj->parse_charset($charset);
-                       } elseif ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']) {
-                                       // when forceCharset is set, we store ALL labels in this charset!!!
-                               $targetCharset = $csConvObj->parse_charset($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']);
-                       } else {
-                               $targetCharset = $csConvObj->parse_charset($csConvObj->charSetArray[$langKey] ? $csConvObj->charSetArray[$langKey] : 'iso-8859-1');
-                       }
-
-                               // Cache file name:
-                       $hashSource = substr($fileRef, strlen(PATH_site)) . '|' . date('d-m-Y H:i:s', filemtime($fileRef)) . '|version=2.3';
-                       $cacheFileName = PATH_site . 'typo3temp/llxml/' .
-                                       substr(basename($fileRef), 10, 15) .
-                                       '_' . self::shortMD5($hashSource) . '.' . $langKey . '.' . $targetCharset . '.cache';
-                               // Check if cache file exists...
-                       if (!@is_file($cacheFileName)) { // ... if it doesn't, create content and write it:
-                               $LOCAL_LANG = NULL;
-                                       // Get PHP data
-                               include($fileRef);
-                               if (!is_array($LOCAL_LANG)) {
-                                       $fileName = substr($fileRef, strlen(PATH_site));
-                                       throw new RuntimeException(
-                                               'TYPO3 Fatal Error: "' . $fileName . '" is no TYPO3 language file!',
-                                               1270853900
-                                       );
-                               }
-
-                                       // converting the default language (English)
-                                       // this needs to be done for a few accented loan words and extension names
-                               if (is_array($LOCAL_LANG['default']) && $targetCharset != 'iso-8859-1') {
-                                       foreach ($LOCAL_LANG['default'] as &$labelValue) {
-                                               $labelValue = $csConvObj->conv($labelValue, 'iso-8859-1', $targetCharset);
-                                       }
-                                       unset($labelValue);
-                               }
-
-                               if ($langKey != 'default' && is_array($LOCAL_LANG[$langKey]) && $sourceCharset != $targetCharset) {
-                                       foreach ($LOCAL_LANG[$langKey] as &$labelValue) {
-                                               $labelValue = $csConvObj->conv($labelValue, $sourceCharset, $targetCharset);
-                                       }
-                                       unset($labelValue);
-                               }
-
-                                       // Cache the content now:
-                               $serContent = array('origFile' => $hashSource, 'LOCAL_LANG' => array('default' => $LOCAL_LANG['default'], $langKey => $LOCAL_LANG[$langKey]));
-                               $res = self::writeFileToTypo3tempDir($cacheFileName, serialize($serContent));
-                               if ($res) {
-                                       throw new RuntimeException(
-                                               'TYPO3 Fatal Error: "' . $res,
-                                               1270853901
-                                       );
-                               }
-                       } else {
-                                       // Get content from cache:
-                               $serContent = unserialize(self::getUrl($cacheFileName));
-                               $LOCAL_LANG = $serContent['LOCAL_LANG'];
-                       }
-
-                       return $LOCAL_LANG;
-               }
-       }
-
-       /**
-        * Includes a locallang-xml file and returns the $LOCAL_LANG array
-        * Works only when the frontend or backend has been initialized with a charset conversion object. See first code lines.
-        *
-        * @param string $fileRef Absolute reference to locallang-XML file
-        * @param string $langKey TYPO3 language key, eg. "dk" or "de" or "default"
-        * @param string $charset Character set (optional)
-        * @return array LOCAL_LANG array in return.
-        * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - use tx_lang_parser_Llxml::getParsedData() from now on
-        */
-       public static function readLLXMLfile($fileRef, $langKey, $charset = '') {
-               t3lib_div::logDeprecatedFunction();
-
-               if (is_object($GLOBALS['LANG'])) {
-                       $csConvObj = $GLOBALS['LANG']->csConvObj;
-               } elseif (is_object($GLOBALS['TSFE'])) {
-                       $csConvObj = $GLOBALS['TSFE']->csConvObj;
-               } else {
-                       $csConvObj = self::makeInstance('t3lib_cs');
-               }
-
-               $LOCAL_LANG = NULL;
-               if (@is_file($fileRef) && $langKey) {
-
-                               // Set charset:
-                       if ($charset) {
-                               $targetCharset = $csConvObj->parse_charset($charset);
-                       } elseif ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']) {
-                                       // when forceCharset is set, we store ALL labels in this charset!!!
-                               $targetCharset = $csConvObj->parse_charset($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']);
-                       } else {
-                               $targetCharset = $csConvObj->parse_charset($csConvObj->charSetArray[$langKey] ? $csConvObj->charSetArray[$langKey] : 'iso-8859-1');
-                       }
-
-                               // Cache file name:
-                       $hashSource = substr($fileRef, strlen(PATH_site)) . '|' . date('d-m-Y H:i:s', filemtime($fileRef)) . '|version=2.3';
-                       $cacheFileName = PATH_site . 'typo3temp/llxml/' .
-                                       substr(basename($fileRef), 10, 15) .
-                                       '_' . self::shortMD5($hashSource) . '.' . $langKey . '.' . $targetCharset . '.cache';
-
-                               // Check if cache file exists...
-                       if (!@is_file($cacheFileName)) { // ... if it doesn't, create content and write it:
-
-                                       // Read XML, parse it.
-                               $xmlString = self::getUrl($fileRef);
-                               $xmlContent = self::xml2array($xmlString);
-                               if (!is_array($xmlContent)) {
-                                       $fileName = substr($fileRef, strlen(PATH_site));
-                                       throw new RuntimeException(
-                                               'TYPO3 Fatal Error: The file "' . $fileName . '" is no TYPO3 language file!',
-                                               1270853902
-                                       );
-                               }
-
-                                       // Set default LOCAL_LANG array content:
-                               $LOCAL_LANG = array();
-                               $LOCAL_LANG['default'] = $xmlContent['data']['default'];
-
-                                       // converting the default language (English)
-                                       // this needs to be done for a few accented loan words and extension names
-                                       // NOTE: no conversion is done when in UTF-8 mode!
-                               if (is_array($LOCAL_LANG['default']) && $targetCharset != 'utf-8') {
-                                       foreach ($LOCAL_LANG['default'] as &$labelValue) {
-                                               $labelValue = $csConvObj->utf8_decode($labelValue, $targetCharset);
-                                       }
-                                       unset($labelValue);
-                               }
-
-                                       // converting other languages to their "native" charsets
-                                       // NOTE: no conversion is done when in UTF-8 mode!
-                               if ($langKey != 'default') {
-
-                                               // If no entry is found for the language key, then force a value depending on meta-data setting. By default an automated filename will be used:
-                                       $LOCAL_LANG[$langKey] = self::llXmlAutoFileName($fileRef, $langKey);
-                                       $localized_file = self::getFileAbsFileName($LOCAL_LANG[$langKey]);
-                                       if (!@is_file($localized_file) && isset($xmlContent['data'][$langKey])) {
-                                               $LOCAL_LANG[$langKey] = $xmlContent['data'][$langKey];
-                                       }
-
-                                               // Checking if charset should be converted.
-                                       if (is_array($LOCAL_LANG[$langKey]) && $targetCharset != 'utf-8') {
-                                               foreach ($LOCAL_LANG[$langKey] as &$labelValue) {
-                                                       $labelValue = $csConvObj->utf8_decode($labelValue, $targetCharset);
-                                               }
-                                               unset($labelValue);
-                                       }
-                               }
-
-                                       // Cache the content now:
-                               $serContent = array('origFile' => $hashSource, 'LOCAL_LANG' => array('default' => $LOCAL_LANG['default'], $langKey => $LOCAL_LANG[$langKey]));
-                               $res = self::writeFileToTypo3tempDir($cacheFileName, serialize($serContent));
-                               if ($res) {
-                                       throw new RuntimeException(
-                                               'TYPO3 Fatal Error: ' . $res,
-                                               1270853903
-                                       );
-                               }
-                       } else {
-                                       // Get content from cache:
-                               $serContent = unserialize(self::getUrl($cacheFileName));
-                               $LOCAL_LANG = $serContent['LOCAL_LANG'];
-                       }
-
-                               // Checking for EXTERNAL file for non-default language:
-                       if ($langKey != 'default' && is_string($LOCAL_LANG[$langKey]) && strlen($LOCAL_LANG[$langKey])) {
-
-                                       // Look for localized file:
-                               $localized_file = self::getFileAbsFileName($LOCAL_LANG[$langKey]);
-                               if ($localized_file && @is_file($localized_file)) {
-
-                                               // Cache file name:
-                                       $hashSource = substr($localized_file, strlen(PATH_site)) . '|' . date('d-m-Y H:i:s', filemtime($localized_file)) . '|version=2.3';
-                                       $cacheFileName = PATH_site . 'typo3temp/llxml/EXT_' .
-                                                       substr(basename($localized_file), 10, 15) .
-                                                       '_' . self::shortMD5($hashSource) . '.' . $langKey . '.' . $targetCharset . '.cache';
-
-                                               // Check if cache file exists...
-                                       if (!@is_file($cacheFileName)) { // ... if it doesn't, create content and write it:
-
-                                                       // Read and parse XML content:
-                                               $local_xmlString = self::getUrl($localized_file);
-                                               $local_xmlContent = self::xml2array($local_xmlString);
-                                               if (!is_array($local_xmlContent)) {
-                                                       $fileName = substr($localized_file, strlen(PATH_site));
-                                                       throw new RuntimeException(
-                                                               'TYPO3 Fatal Error: The file "' . $fileName . '" is no TYPO3 language file!',
-                                                               1270853904
-                                                       );
-                                               }
-                                               $LOCAL_LANG[$langKey] = is_array($local_xmlContent['data'][$langKey]) ? $local_xmlContent['data'][$langKey] : array();
-
-                                                       // Checking if charset should be converted.
-                                               if (is_array($LOCAL_LANG[$langKey]) && $targetCharset != 'utf-8') {
-                                                       foreach ($LOCAL_LANG[$langKey] as &$labelValue) {
-                                                               $labelValue = $csConvObj->utf8_decode($labelValue, $targetCharset);
-                                                       }
-                                                       unset($labelValue);
-                                               }
-
-                                                       // Cache the content now:
-                                               $serContent = array('extlang' => $langKey, 'origFile' => $hashSource, 'EXT_DATA' => $LOCAL_LANG[$langKey]);
-                                               $res = self::writeFileToTypo3tempDir($cacheFileName, serialize($serContent));
-                                               if ($res) {
-                                                       throw new RuntimeException(
-                                                               'TYPO3 Fatal Error: ' . $res,
-                                                               1270853905
-                                                       );
-                                               }
-                                       } else {
-                                                       // Get content from cache:
-                                               $serContent = unserialize(self::getUrl($cacheFileName));
-                                               $LOCAL_LANG[$langKey] = $serContent['EXT_DATA'];
-                                       }
-                               } else {
-                                       $LOCAL_LANG[$langKey] = array();
-                               }
-                       }
-
-                               // Convert the $LOCAL_LANG array to XLIFF structure
-                       foreach ($LOCAL_LANG as &$keysLabels) {
-                               foreach ($keysLabels as &$label) {
-                                       $label = array(0 => array(
-                                               'target' => $label,
-                                       ));
-                               }
-                               unset($label);
-                       }
-                       unset($keysLabels);
-
-                       return $LOCAL_LANG;
-               }
-       }
-
-       /**
         * Returns auto-filename for locallang-XML localizations.
         *
         * @param string $fileRef Absolute file reference to locallang-XML file. Must be inside system/global/local extension
         * @param string $language Language key
-        * @return string Returns the filename reference for the language unless error occured (or local mode is used) in which case it will be NULL
+        * @param boolean $sameLocation if TRUE, then locallang-XML localization file name will be returned with same directory as $fileRef
+        * @return string Returns the filename reference for the language unless error occurred (or local mode is used) in which case it will be NULL
         */
-       public static function llXmlAutoFileName($fileRef, $language) {
+       public static function llXmlAutoFileName($fileRef, $language, $sameLocation = FALSE) {
+               if ($sameLocation) {
+                       $location = 'EXT:';
+               } else {
+                               // Default location of translations
+                       $location = 'typo3conf/l10n/' . $language . '/';
+               }
+
                        // Analyse file reference:
-               $location = 'typo3conf/l10n/' . $language . '/'; // Default location of translations
-               if (self::isFirstPartOfStr($fileRef, PATH_typo3 . 'sysext/')) { // Is system:
+                       // Is system:
+               if (self::isFirstPartOfStr($fileRef, PATH_typo3 . 'sysext/')) {
                        $validatedPrefix = PATH_typo3 . 'sysext/';
-                       #$location = 'EXT:csh_'.$language.'/';  // For system extensions translations are found in "csh_*" extensions (language packs)
                } elseif (self::isFirstPartOfStr($fileRef, PATH_typo3 . 'ext/')) { // Is global:
                        $validatedPrefix = PATH_typo3 . 'ext/';
                } elseif (self::isFirstPartOfStr($fileRef, PATH_typo3conf . 'ext/')) { // Is local:
                        $validatedPrefix = PATH_typo3conf . 'ext/';
+               } elseif (self::isFirstPartOfStr($fileRef, PATH_site . 'tests/')) { // Is test:
+                       $validatedPrefix = PATH_site . 'tests/';
+                       $location = $validatedPrefix;
+               } elseif (self::isFirstPartOfStr($fileRef, PATH_site . 'typo3_src/tests/')) { // Is test (typo3_src deprecated as ov TYPO3 6.0):
+                       $validatedPrefix = PATH_site . 'typo3_src/tests/';
+                       $location = $validatedPrefix;
                } else {
                        $validatedPrefix = '';
                }
@@ -4345,6 +4137,11 @@ final class t3lib_div {
                        } // Add empty first-entry if not there.
                        list($file_extPath, $file_fileName) = $temp;
 
+                               // If $fileRef is already prefix with "[language key]" then we should return it as this
+                       if (substr($file_fileName, 0, strlen($language) + 1) === $language . '.') {
+                               return $fileRef;
+                       }
+
                                // The filename is prefixed with "[language key]." because it prevents the llxmltranslate tool from detecting it.
                        return $location .
                                        $file_extKey . '/' .
@@ -4355,7 +4152,6 @@ final class t3lib_div {
                }
        }
 
-
        /**
         * Loads the $GLOBALS['TCA'] (Table Configuration Array) for the $table
         *
@@ -4371,7 +4167,7 @@ final class t3lib_div {
         * @return void
         */
        public static function loadTCA($table) {
-                       //needed for inclusion of the dynamic config files.
+                       // Needed for inclusion of the dynamic config files.
                global $TCA;
                if (isset($TCA[$table])) {
                        $tca = &$TCA[$table];
@@ -4396,7 +4192,7 @@ final class t3lib_div {
         *
         * @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 happend in which case an error string is returned (string). key1: The used sheet key value!
+        * @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)) {
@@ -4423,7 +4219,8 @@ final class t3lib_div {
                        if (isset($dataStruct['meta'])) {
                                unset($dataStruct['meta']);
                        } // Meta data should not appear there.
-                       $sheet = 'sDEF'; // Default sheet
+                               // Default sheet
+                       $sheet = 'sDEF';
                }
                return array($dataStruct, $sheet, $singleSheet);
        }
@@ -4452,13 +4249,13 @@ final class t3lib_div {
        }
 
        /**
-        * Calls a userdefined function/method in class
-        * Such a function/method should look like this: "function proc(&$params, &$ref)        {...}"
+        * 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, '[file-reference":"]["&"]class/function["->"method-name]'. You can prefix this reference with "[file-reference]:" and t3lib_div::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 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 Required prefix of class or function name
+        * @param string $checkPrefix Alternative allowed prefix of class or function name
         * @param integer $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()
@@ -4496,7 +4293,7 @@ final class t3lib_div {
 
                        // Check prefix is valid:
                if ($checkPrefix && !self::hasValidClassPrefix($funcRef, array($checkPrefix))) {
-                       $errorMsg = "Function/class '$funcRef' was not prepended with '$checkPrefix'";
+                       $errorMsg = 'Function/class \'' . $funcRef . '\' was not prepended with \'' . $checkPrefix . '\'';
                        if ($errorMode == 2) {
                                throw new InvalidArgumentException($errorMsg, 1294585864);
                        } elseif (!$errorMode) {
@@ -4622,7 +4419,7 @@ final class t3lib_div {
                                return $classObj;
                        } else {
                                if (!$silent) {
-                                       debug("<strong>ERROR:</strong> No class named: " . $class, 't3lib_div::getUserObj');
+                                       debug('<strong>ERROR:</strong> No class named: ' . $class, 't3lib_div::getUserObj');
                                }
                        }
                }
@@ -4636,16 +4433,21 @@ final class t3lib_div {
         * @return bool TRUE if name is allowed
         */
        public static function hasValidClassPrefix($classRef, array $additionalPrefixes = array()) {
+               if (empty($classRef)) {
+                       return FALSE;
+               }
+               if (!is_string($classRef)) {
+                       throw new InvalidArgumentException('$classRef has to be of type string', 1313917992);
+               }
                $hasValidPrefix = FALSE;
-               $validPrefixes = array('tx_', 'Tx_', $GLOBALS['TYPO3_CONF_VARS']['FE']['userFuncClassPrefix']);
+               $validPrefixes = self::getValidClassPrefixes();
                $classRef = trim($classRef);
 
                if (count($additionalPrefixes)) {
                        $validPrefixes = array_merge($validPrefixes, $additionalPrefixes);
                }
-
                foreach ($validPrefixes as $prefixToCheck) {
-                       if (self::isFirstPartOfStr($classRef, $prefixToCheck)) {
+                       if (self::isFirstPartOfStr($classRef, $prefixToCheck) || $prefixToCheck === '') {
                                $hasValidPrefix = TRUE;
                                break;
                        }
@@ -4655,6 +4457,25 @@ final class t3lib_div {
        }
 
        /**
+        * Returns all valid class prefixes.
+        *
+        * @return array Array of valid prefixed of class names
+        */
+       public static function getValidClassPrefixes() {
+               $validPrefixes = array('tx_', 'Tx_', 'user_', 'User_', 't3lib_');
+               if (
+                       isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['additionalAllowedClassPrefixes'])
+                       && is_string($GLOBALS['TYPO3_CONF_VARS']['SYS']['additionalAllowedClassPrefixes'])
+               ) {
+                       $validPrefixes = array_merge(
+                               $validPrefixes,
+                               self::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['SYS']['additionalAllowedClassPrefixes'])
+                       );
+               }
+               return $validPrefixes;
+       }
+
+       /**
         * Creates an instance of a class taking into account the class-extensions
         * API of TYPO3. USE THIS method instead of the PHP "new" keyword.
         * Eg. "$obj = new myclass;" should be "$obj = t3lib_div::makeInstance("myclass")" instead!
@@ -4663,21 +4484,15 @@ final class t3lib_div {
         *              t3lib_div::makeInstance('myClass', $arg1, $arg2, ..., $argN)
         *
         * @throws InvalidArgumentException if classname is an empty string
-        * @param string $className
-        *                      name of the class to instantiate, must not be empty
+        * @param string $className name of the class to instantiate, must not be empty
         * @return object the created instance
         */
        public static function makeInstance($className) {
-               if ($className === '') {
-                       throw new InvalidArgumentException('$classname must not be empty.', 1288965219);
+               if (!is_string($className) || empty($className)) {
+                       throw new InvalidArgumentException('$className must be a non empty string.', 1288965219);
                }
 
-                       // Determine final class name which must be instantiated, this takes XCLASS handling
-                       // into account. Cache in a local array to save some cycles for consecutive calls.
-               if (!isset(self::$finalClassNameRegister[$className])) {
-                       self::$finalClassNameRegister[$className] = self::getClassName($className);
-               }
-               $finalClassName = self::$finalClassNameRegister[$className];
+               $finalClassName = self::getClassName($className);
 
                        // Return singleton instance if it is already registered
                if (isset(self::$singletonInstances[$finalClassName])) {
@@ -4717,9 +4532,9 @@ final class t3lib_div {
         * @param string $className Base class name to evaluate
         * @return string Final class name to instantiate with "new [classname]"
         */
-       protected function getClassName($className) {
+       protected static function getClassName($className) {
                if (class_exists($className)) {
-                       while (class_exists('ux_' . $className, FALSE)) {
+                       while (t3lib_autoloader::getClassPathByRegistryLookup('ux_' . $className) !== NULL) {
                                $className = 'ux_' . $className;
                        }
                }
@@ -4733,7 +4548,7 @@ final class t3lib_div {
         * If this function is called multiple times for the same $className,
         * makeInstance will return the last set instance.
         *
-        * Warning: This is a helper method for unit tests. Do not call this directly in production code!
+        * Warning: This is _not_ a public API method and must not be used in own extensions!
         *
         * @see makeInstance
         * @param string $className
@@ -4741,6 +4556,7 @@ final class t3lib_div {
         * @param t3lib_Singleton $instance
         *        the instance to set, must be an instance of $className
         * @return void
+        * @internal
         */
        public static function setSingletonInstance($className, t3lib_Singleton $instance) {
                self::checkInstanceClassName($className, $instance);
@@ -4805,7 +4621,7 @@ final class t3lib_div {
        /**
         * Purge all instances returned by makeInstance.
         *
-        * This function is most useful when called from tearDown in a testcase
+        * This function is most useful when called from tearDown in a test case
         * to drop any instances that have been created by the tests.
         *
         * Warning: This is a helper method for unit tests. Do not call this directly in production code!
@@ -4824,9 +4640,8 @@ final class t3lib_div {
         *
         * @param string $serviceType Type of service (service key).
         * @param string $serviceSubType Sub type like file extensions or similar. Defined by the service.
-        * @param mixed $excludeServiceKeys List of service keys which should be exluded in the search for a service. Array or comma list.
+        * @param mixed $excludeServiceKeys List of service keys which should be excluded in the search for a service. Array or comma list.
         * @return object The service object or an array with error info's.
-        * @author René Fritz <r.fritz@colorcube.de>
         */
        public static function makeInstanceService($serviceType, $serviceSubType = '', $excludeServiceKeys = array()) {
                $error = FALSE;
@@ -4834,10 +4649,24 @@ final class t3lib_div {
                if (!is_array($excludeServiceKeys)) {
                        $excludeServiceKeys = self::trimExplode(',', $excludeServiceKeys, 1);
                }
+
+               $requestInfo = array(
+                       'requestedServiceType' => $serviceType,
+                       'requestedServiceSubType' => $serviceSubType,
+                       'requestedExcludeServiceKeys' => $excludeServiceKeys,
+               );
+
                while ($info = t3lib_extMgm::findService($serviceType, $serviceSubType, $excludeServiceKeys)) {
 
+                               // provide information about requested service to service object
+                       $info = array_merge($info, $requestInfo);
+
                                // Check persistent object and if found, call directly and exit.
                        if (is_object($GLOBALS['T3_VAR']['makeInstanceService'][$info['className']])) {
+
+                                       // update request info in persistent object
+                               $GLOBALS['T3_VAR']['makeInstanceService'][$info['className']]->info = $info;
+
                                        // reset service and return object
                                $GLOBALS['T3_VAR']['makeInstanceService'][$info['className']]->reset();
                                return $GLOBALS['T3_VAR']['makeInstanceService'][$info['className']];
@@ -4854,7 +4683,8 @@ final class t3lib_div {
                                                        die ('Broken service:' . t3lib_utility_Debug::viewArray($info));
                                                }
                                                $obj->info = $info;
-                                               if ($obj->init()) { // service available?
+                                                       // service available?
+                                               if ($obj->init()) {
 
                                                                // create persistent object
                                                        $GLOBALS['T3_VAR']['makeInstanceService'][$info['className']] = $obj;
@@ -4906,7 +4736,7 @@ final class t3lib_div {
        /**
         * Simple substitute for the PHP function mail() which allows you to specify encoding and character set
         * The fifth parameter ($encoding) will allow you to specify 'base64' encryption for the output (set $encoding=base64)
-        * Further the output has the charset set to ISO-8859-1 by default.
+        * Further the output has the charset set to UTF-8 by default.
         *
         * @param string $email Email address to send to. (see PHP function mail())
         * @param string $subject Subject line, non-encoded. (see PHP function mail())
@@ -4919,15 +4749,17 @@ final class t3lib_div {
         */
        public static function plainMailEncoded($email, $subject, $message, $headers = '', $encoding = 'quoted-printable', $charset = '', $dontEncodeHeader = FALSE) {
                if (!$charset) {
-                       $charset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] ? $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] : 'ISO-8859-1';
+                       $charset = 'utf-8';
                }
 
                $email = self::normalizeMailAddress($email);
                if (!$dontEncodeHeader) {
                                // Mail headers must be ASCII, therefore we convert the whole header to either base64 or quoted_printable
                        $newHeaders = array();
-                       foreach (explode(LF, $headers) as $line) { // Split the header in lines and convert each line separately
-                               $parts = explode(': ', $line, 2); // Field tags must not be encoded
+                               // Split the header in lines and convert each line separately
+                       foreach (explode(LF, $headers) as $line) {
+                                       // Field tags must not be encoded
+                               $parts = explode(': ', $line, 2);
                                if (count($parts) == 2) {
                                        if (0 == strcasecmp($parts[0], 'from')) {
                                                $parts[1] = self::normalizeMailAddress($parts[1]);
@@ -4935,13 +4767,15 @@ final class t3lib_div {
                                        $parts[1] = self::encodeHeader($parts[1], $encoding, $charset);
                                        $newHeaders[] = implode(': ', $parts);
                                } else {
-                                       $newHeaders[] = $line; // Should never happen - is such a mail header valid? Anyway, just add the unchanged line...
+                                               // Should never happen - is such a mail header valid? Anyway, just add the unchanged line...
+                                       $newHeaders[] = $line;
                                }
                        }
                        $headers = implode(LF, $newHeaders);
                        unset($newHeaders);
 
-                       $email = self::encodeHeader($email, $encoding, $charset); // Email address must not be encoded, but it could be appended by a name which should be so (e.g. "Kasper Skårhøj <kasperYYYY@typo3.com>")
+                               // Email address must not be encoded, but it could be appended by a name which should be so (e.g. "Kasper Skårhøj <kasperYYYY@typo3.com>")
+                       $email = self::encodeHeader($email, $encoding, $charset);
                        $subject = self::encodeHeader($subject, $encoding, $charset);
                }
 
@@ -4952,7 +4786,8 @@ final class t3lib_div {
                                                'Content-Type: text/plain; charset="' . $charset . '"' . LF .
                                                'Content-Transfer-Encoding: base64';
 
-                               $message = trim(chunk_split(base64_encode($message . LF))) . LF; // Adding LF because I think MS outlook 2002 wants it... may be removed later again.
+                                       // Adding LF because I think MS outlook 2002 wants it... may be removed later again.
+                               $message = trim(chunk_split(base64_encode($message . LF))) . LF;
                                break;
                        case '8bit':
                                $headers = trim($headers) . LF .
@@ -4972,17 +4807,16 @@ final class t3lib_div {
                }
 
                        // Headers must be separated by CRLF according to RFC 2822, not just LF.
-                       // But many servers (Gmail, for example) behave incorectly and want only LF.
+                       // But many servers (Gmail, for example) behave incorrectly and want only LF.
                        // So we stick to LF in all cases.
-               $headers = trim(implode(LF, self::trimExplode(LF, $headers, TRUE))); // Make sure no empty lines are there.
-
+                       // Make sure no empty lines are there.
+               $headers = trim(implode(LF, self::trimExplode(LF, $headers, TRUE)));
 
                return t3lib_utility_Mail::mail($email, $subject, $message, $headers);
        }
 
        /**
         * Implementation of quoted-printable encode.
-        * This functions is buggy. It seems that in the part where the lines are breaked every 76th character, that it fails if the break happens right in a quoted_printable encode character!
         * See RFC 1521, section 5.1 Quoted-Printable Content-Transfer-Encoding
         *
         * @param string $string Content to encode
@@ -4990,41 +4824,54 @@ final class t3lib_div {
         * @return string The QP encoded string
         */
        public static function quoted_printable($string, $maxlen = 76) {
-                       // Make sure the string contains only Unix linebreaks
-               $string = str_replace(CRLF, LF, $string); // Replace Windows breaks (\r\n)
-               $string = str_replace(CR, LF, $string); // Replace Mac breaks (\r)
-
-               $linebreak = LF; // Default line break for Unix systems.
+                       // Make sure the string contains only Unix line breaks
+                       // Replace Windows breaks (\r\n)
+               $string = str_replace(CRLF, LF, $string);
+                       // Replace Mac breaks (\r)
+               $string = str_replace(CR, LF, $string);
+
+                       // Default line break for Unix systems.
+               $linebreak = LF;
                if (TYPO3_OS == 'WIN') {
-                       $linebreak = CRLF; // Line break for Windows. This is needed because PHP on Windows systems send mails via SMTP instead of using sendmail, and thus the linebreak needs to be \r\n.
+                               // Line break for Windows. This is needed because PHP on Windows systems send mails via SMTP instead of using sendmail, and thus the line break needs to be \r\n.
+                       $linebreak = CRLF;
                }
 
                $newString = '';
-               $theLines = explode(LF, $string); // Split lines
+                       // Split lines
+               $theLines = explode(LF, $string);
                foreach ($theLines as $val) {
                        $newVal = '';
                        $theValLen = strlen($val);
                        $len = 0;
-                       for ($index = 0; $index < $theValLen; $index++) { // Walk through each character of this line
+                               // Walk through each character of this line
+                       for ($index = 0; $index < $theValLen; $index++) {
                                $char = substr($val, $index, 1);
                                $ordVal = ord($char);
                                if ($len > ($maxlen - 4) || ($len > ($maxlen - 14) && $ordVal == 32)) {
-                                       $newVal .= '=' . $linebreak; // Add a line break
-                                       $len = 0; // Reset the length counter
+                                               // Add a line break
+                                       $newVal .= '=' . $linebreak;
+                                               // Reset the length counter
+                                       $len = 0;
                                }
                                if (($ordVal >= 33 && $ordVal <= 60) || ($ordVal >= 62 && $ordVal <= 126) || $ordVal == 9 || $ordVal == 32) {
-                                       $newVal .= $char; // This character is ok, add it to the message
+                                               // This character is ok, add it to the message
+                                       $newVal .= $char;
                                        $len++;
                                } else {
-                                       $newVal .= sprintf('=%02X', $ordVal); // Special character, needs to be encoded
+                                               // Special character, needs to be encoded
+                                       $newVal .= sprintf('=%02X', $ordVal);
                                        $len += 3;
                                }
                        }
-                       $newVal = preg_replace('/' . chr(32) . '$/', '=20', $newVal); // Replaces a possible SPACE-character at the end of a line
-                       $newVal = preg_replace('/' . TAB . '$/', '=09', $newVal); // Replaces a possible TAB-character at the end of a line
+                               // Replaces a possible SPACE-character at the end of a line
+                       $newVal = preg_replace('/' . chr(32) . '$/', '=20', $newVal);
+                               // Replaces a possible TAB-character at the end of a line
+                       $newVal = preg_replace('/' . TAB . '$/', '=09', $newVal);
                        $newString .= $newVal . $linebreak;
                }
-               return preg_replace('/' . $linebreak . '$/', '', $newString); // Remove last newline
+                       // Remove last newline
+               return preg_replace('/' . $linebreak . '$/', '', $newString);
        }
 
        /**
@@ -5036,7 +4883,7 @@ final class t3lib_div {
         * @param string $charset Charset used for encoding
         * @return string The encoded string
         */
-       public static function encodeHeader($line, $enc = 'quoted-printable', $charset = 'iso-8859-1') {
+       public static function encodeHeader($line, $enc = 'quoted-printable', $charset = 'utf-8') {
                        // Avoid problems if "###" is found in $line (would conflict with the placeholder which is used below)
                if (strpos($line, '###') !== FALSE) {
                        return $line;
@@ -5051,6 +4898,8 @@ final class t3lib_div {
                $matches = preg_split('/(.?###.+###.?|\(|\))/', $line, -1, PREG_SPLIT_NO_EMPTY);
                foreach ($matches as $part) {
                        $oldPart = $part;
+                       $partWasQuoted = ($part{0} == '"');
+                       $part = trim($part, '"');
                        switch ((string) $enc) {
                                case 'base64':
                                        $part = '=?' . $charset . '?B?' . base64_encode($part) . '?=';
@@ -5069,9 +4918,13 @@ final class t3lib_div {
                                        }
                                        break;
                        }
+                       if ($partWasQuoted) {
+                               $part = '"' . $part . '"';
+                       }
                        $line = str_replace($oldPart, $part, $line);
                }
-               $line = preg_replace('/###(.+?)###/', '$1', $line); // Remove the wrappers
+                       // Remove the wrappers
+               $line = preg_replace('/###(.+?)###/', '$1', $line);
 
                return $line;
        }
@@ -5087,34 +4940,36 @@ final class t3lib_div {
         * @see makeRedirectUrl()
         */
        public static function substUrlsInPlainText($message, $urlmode = '76', $index_script_url = '') {
-                       // Substitute URLs with shorter links:
-               foreach (array('http', 'https') as $protocol) {
-                       $urlSplit = explode($protocol . '://', $message);
-                       foreach ($urlSplit as $c => &$v) {
-                               if ($c) {
-                                       $newParts = preg_split('/\s|[<>"{}|\\\^`()\']/', $v, 2);
-                                       $newURL = $protocol . '://' . $newParts[0];
-
-                                       switch ((string) $urlmode) {
-                                               case 'all':
-                                                       $newURL = self::makeRedirectUrl($newURL, 0, $index_script_url);
-                                                       break;
-                                               case '76':
-                                                       $newURL = self::makeRedirectUrl($newURL, 76, $index_script_url);
-                                                       break;
-                                       }
-                                       $v = $newURL . substr($v, strlen($newParts[0]));
-                               }
-                       }
-                       unset($v);
-                       $message = implode('', $urlSplit);
+               $lengthLimit = FALSE;
+
+               switch ((string) $urlmode) {
+                       case '':
+                               $lengthLimit = FALSE;
+                               break;
+                       case 'all':
+                               $lengthLimit = 0;
+                               break;
+                       case '76':
+                       default:
+                               $lengthLimit = (int) $urlmode;
+               }
+
+               if ($lengthLimit === FALSE) {
+                               // No processing
+                       $messageSubstituted = $message;
+               } else {
+                       $messageSubstituted = preg_replace(
+                               '/(http|https):\/\/.+(?=[\]\.\?]*([\! \'"()<>]+|$))/eiU',
+                               'self::makeRedirectUrl("\\0",' . $lengthLimit . ',"' . $index_script_url . '")',
+                               $message
+                       );
                }
 
-               return $message;
+               return $messageSubstituted;
        }
 
        /**
-        * Subfunction for substUrlsInPlainText() above.
+        * Sub-function for substUrlsInPlainText() above.
         *
         * @param string $inUrl Input URL
         * @param integer $l URL string length limit
@@ -5167,7 +5022,7 @@ final class t3lib_div {
         * @see sysLog()
         */
        public static function initSysLog() {
-                       // for CLI logging name is <fqdn-hostname>:<TYPO3-path>
+                       // 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 (defined('TYPO3_cliMode') && TYPO3_cliMode) {
                        $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'] = self::getHostname($requestHost = FALSE) . ':' . PATH_site;
@@ -5177,7 +5032,7 @@ final class t3lib_div {
                        $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'] = self::getIndpEnv('TYPO3_SITE_URL');
                }
 
-                       // init custom logging
+                       // Init custom logging
                if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog'])) {
                        $params = array('initLog' => TRUE);
                        $fakeThis = FALSE;
@@ -5186,7 +5041,7 @@ final class t3lib_div {
                        }
                }
 
-                       // init TYPO3 logging
+                       // Init TYPO3 logging
                foreach (explode(';', $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLog'], 2) as $log) {
                        list($type, $destination) = explode(',', $log, 3);
 
@@ -5212,23 +5067,23 @@ final class t3lib_div {
         *
         * @param string $msg Message (in English).
         * @param string $extKey Extension key (from which extension you are calling the log) or "Core"
-        * @param integer $severity Severity: 0 is info, 1 is notice, 2 is warning, 3 is error, 4 is fatal error
+        * @param integer $severity t3lib_div::SYSLOG_SEVERITY_* constant
         * @return void
         */
        public static function sysLog($msg, $extKey, $severity = 0) {
                $severity = t3lib_utility_Math::forceIntegerInRange($severity, 0, 4);
 
-                       // is message worth logging?
+                       // Is message worth logging?
                if (intval($GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLogLevel']) > $severity) {
                        return;
                }
 
-                       // initialize logging
+                       // Initialize logging
                if (!$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogInit']) {
                        self::initSysLog();
                }
 
-                       // do custom logging
+                       // 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);
@@ -5246,36 +5101,39 @@ final class t3lib_div {
                $dateFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'];
                $timeFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'];
 
-                       // use all configured logging options
+                       // Use all configured logging options
                foreach (explode(';', $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLog'], 2) as $log) {
                        list($type, $destination, $level) = explode(',', $log, 4);
 
-                               // is message worth logging for this log type?
+                               // Is message worth logging for this log type?
                        if (intval($level) > $severity) {
                                continue;
                        }
 
                        $msgLine = ' - ' . $extKey . ': ' . $msg;
 
-                               // write message to a file
+                               // Write message to a file
                        if ($type == 'file') {
+                               $lockObject = self::makeInstance('t3lib_lock', $destination, $GLOBALS['TYPO3_CONF_VARS']['SYS']['lockingMode']);
+                               /** @var t3lib_lock $lockObject */
+                               $lockObject->setEnableLogging(FALSE);
+                               $lockObject->acquire();
                                $file = fopen($destination, 'a');
                                if ($file) {
-                                       flock($file, LOCK_EX); // try locking, but ignore if not available (eg. on NFS and FAT)
                                        fwrite($file, date($dateFormat . ' ' . $timeFormat) . $msgLine . LF);
-                                       flock($file, LOCK_UN); // release the lock
                                        fclose($file);
                                        self::fixPermissions($destination);
                                }
+                               $lockObject->release();
                        }
-                               // send message per mail
+                               // Send message per mail
                        elseif ($type == 'mail') {
                                list($to, $from) = explode('/', $destination);
-                               if (!t3lib_div::validEmail($from)) {
+                               if (!self::validEmail($from)) {
                                        $from = t3lib_utility_Mail::getSystemFrom();
                                }
                                /** @var $mail t3lib_mail_Message */
-                               $mail = t3lib_div::makeInstance('t3lib_mail_Message');
+                               $mail = self::makeInstance('t3lib_mail_Message');
                                $mail->setTo($to)
                                                ->setFrom($from)
                                                ->setSubject('Warning - error in TYPO3 installation')
@@ -5286,11 +5144,11 @@ final class t3lib_div {
                                );
                                $mail->send();
                        }
-                               // use the PHP error log
+                               // Use the PHP error log
                        elseif ($type == 'error_log') {
                                error_log($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogHost'] . $msgLine, 0);
                        }
-                               // use the system log
+                               // Use the system log
                        elseif ($type == 'syslog') {
                                $priority = array(LOG_INFO, LOG_NOTICE, LOG_WARNING, LOG_ERR, LOG_CRIT);
                                syslog($priority[(int) $severity], $msgLine);
@@ -5336,30 +5194,37 @@ final class t3lib_div {
                $log = $GLOBALS['TYPO3_CONF_VARS']['SYS']['enableDeprecationLog'];
                $date = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] . ' ' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'] . ': ');
 
-                       // legacy values (no strict comparison, $log can be boolean, string or int)
+                       // Legacy values (no strict comparison, $log can be boolean, string or int)
                if ($log === TRUE || $log == '1') {
                        $log = 'file';
                }
 
                if (stripos($log, 'file') !== FALSE) {
-                               // write a longer message to the deprecation log
+                               // In case lock is acquired before autoloader was defined:
+                       if (class_exists('t3lib_lock') === FALSE) {
+                               require_once PATH_t3lib . 'class.t3lib_lock.php';
+                       }
+                               // Write a longer message to the deprecation log
                        $destination = self::getDeprecationLogFileName();
+                       $lockObject = self::makeInstance('t3lib_lock', $destination, $GLOBALS['TYPO3_CONF_VARS']['SYS']['lockingMode']);
+                       /** @var t3lib_lock $lockObject */
+                       $lockObject->setEnableLogging(FALSE);
+                       $lockObject->acquire();
                        $file = @fopen($destination, 'a');
                        if ($file) {
-                               flock($file, LOCK_EX); // try locking, but ignore if not available (eg. on NFS and FAT)
                                @fwrite($file, $date . $msg . LF);
-                               flock($file, LOCK_UN); // release the lock
                                @fclose($file);
                                self::fixPermissions($destination);
                        }
+                       $lockObject->release();
                }
 
                if (stripos($log, 'devlog') !== FALSE) {
-                               // copy message also to the developer log
+                               // Copy message also to the developer log
                        self::devLog($msg, 'Core', self::SYSLOG_SEVERITY_WARNING);
                }
 
-                       // do not use console in login screen
+                       // Do not use console in login screen
                if (stripos($log, 'console') !== FALSE && isset($GLOBALS['BE_USER']->user['uid'])) {
                        t3lib_utility_Debug::debug($msg, $date, 'Deprecation Log');
                }
@@ -5368,7 +5233,7 @@ final class t3lib_div {
        /**
         * Gets the absolute path to the deprecation log file.
         *
-        * @return string absolute path to the deprecation log file
+        * @return string Absolute path to the deprecation log file
         */
        public static function getDeprecationLogFileName() {
                return PATH_typo3conf .
@@ -5402,14 +5267,14 @@ final class t3lib_div {
                        $msg = $match[1];
                }
 
-                       // trigger PHP error with a short message: <function> is deprecated (called from <source>, defined in <source>)
+                       // Trigger PHP error with a short message: <function> is deprecated (called from <source>, defined in <source>)
                $errorMsg = 'Function ' . $trail[1]['function'];
                if ($trail[1]['class']) {
                        $errorMsg .= ' of class ' . $trail[1]['class'];
                }
                $errorMsg .= ' is deprecated (called from ' . $trail[1]['file'] . '#' . $trail[1]['line'] . ', defined in ' . $function->getFileName() . '#' . $function->getStartLine() . ')';
 
-                       // write a longer message to the deprecation log: <function> <annotion> - <trace> (<source>)
+                       // Write a longer message to the deprecation log: <function> <annotion> - <trace> (<source>)
                $logMsg = $trail[1]['class'] . $trail[1]['type'] . $trail[1]['function'];
                $logMsg .= '() - ' . $msg.' - ' . t3lib_utility_Debug::debugTrail();
                $logMsg .= ' (' . substr($function->getFileName(), strlen(PATH_site)) . '#' . $function->getStartLine() . ')';
@@ -5461,7 +5326,8 @@ final class t3lib_div {
        public static function unQuoteFilenames($parameters, $unQuote = FALSE) {
                $paramsArr = explode(' ', trim($parameters));
 
-               $quoteActive = -1; // Whenever a quote character (") is found, $quoteActive is set to the element number inside of $params. A value of -1 means that there are not open quotes at the current position.
+                       // Whenever a quote character (") is found, $quoteActive is set to the element number inside of $params. A value of -1 means that there are not open quotes at the current position.
+               $quoteActive = -1;
                foreach ($paramsArr as $k => $v) {
                        if ($quoteActive > -1) {
                                $paramsArr[$quoteActive] .= ' ' . $v;
@@ -5470,8 +5336,8 @@ final class t3lib_div {
                                        $quoteActive = -1;
                                }
                        } elseif (!trim($v)) {
-                               unset($paramsArr[$k]); // Remove empty elements
-
+                                       // Remove empty elements
+                               unset($paramsArr[$k]);
                        } elseif (preg_match('/^(["\'])/', $v) && substr($v, -1) !== $v[0]) {
                                $quoteActive = $k;
                        }
@@ -5485,11 +5351,10 @@ final class t3lib_div {
                        }
                        unset($val);
                }
-                       // return reindexed array
+                       // Return reindexed array
                return array_values($paramsArr);
        }
 
-
        /**
         * Quotes a string for usage as JS parameter. Depends whether the value is
         * used in script tags (it doesn't need/must not get htmlspecialchar'ed in
@@ -5513,7 +5378,6 @@ final class t3lib_div {
                return '\'' . $escapedValue . '\'';
        }
 
-
        /**
         * Ends and cleans all output buffers
         *
@@ -5521,12 +5385,10 @@ final class t3lib_div {
         */
        public static function cleanOutputBuffers() {
                while (ob_end_clean()) {
-                       ;
                }
                header('Content-Encoding: None', TRUE);
        }
 
-
        /**
         * Ends and flushes all output buffers
         *
@@ -5536,16 +5398,15 @@ final class t3lib_div {
                $obContent = '';
 
                while ($obContent .= ob_get_clean()) {
-                       ;
                }
 
-                       // if previously a "Content-Encoding: whatever" has been set, we have to unset it
+                       // 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 :
+                                       // Split it up at the :
                                list($key, $value) = self::trimExplode(':', $header, TRUE);
-                                       // check if we have a Content-Encoding other than 'None'
+                                       // Check if we have a Content-Encoding other than 'None'
                                if (strtolower($key) === 'content-encoding' && strtolower($value) !== 'none') {
                                        header('Content-Encoding: None');
                                        break;
@@ -5556,4 +5417,4 @@ final class t3lib_div {
        }
 }
 
-?>
+?>
\ No newline at end of file