/**
  * Renders a dump of the given variable
  *
  * @param mixed $variable
  * @param integer $level
  * @param boolean $plaintext
  * @param boolean $ansiColors
  * @return string
  */
 public static function renderDump($variable, $level, $plaintext = FALSE, $ansiColors = FALSE)
 {
     if ($level > 50) {
         return 'RECURSION ... ' . chr(10);
     }
     if (is_string($variable)) {
         $croppedValue = strlen($variable) > 2000 ? substr($variable, 0, 2000) . '…' : $variable;
         if ($plaintext) {
             $dump = 'string ' . self::ansiEscapeWrap('"' . $croppedValue . '"', '33', $ansiColors) . ' (' . strlen($variable) . ')';
         } else {
             $dump = sprintf('\'<span class="debug-string">%s</span>\' (%s)', htmlspecialchars($croppedValue), strlen($variable));
         }
     } elseif (is_numeric($variable)) {
         $dump = sprintf('%s %s', gettype($variable), self::ansiEscapeWrap($variable, '35', $ansiColors));
     } elseif (is_array($variable)) {
         $dump = \TYPO3\Flow\Error\Debugger::renderArrayDump($variable, $level + 1, $plaintext, $ansiColors);
     } elseif (is_object($variable)) {
         $dump = \TYPO3\Flow\Error\Debugger::renderObjectDump($variable, $level + 1, TRUE, $plaintext, $ansiColors);
     } elseif (is_bool($variable)) {
         $dump = $variable ? self::ansiEscapeWrap('TRUE', '32', $ansiColors) : self::ansiEscapeWrap('FALSE', '31', $ansiColors);
     } elseif (is_null($variable) || is_resource($variable)) {
         $dump = gettype($variable);
     } else {
         $dump = '[unhandled type]';
     }
     return $dump;
 }