diff --git a/ChangeLog b/ChangeLog
index 0841a1dbd165de68e53a4107683c2993f6d262e4..42ed81191976090d524dcdc64fd551c7ebd7af76 100755
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
 2010-05-02  Steffen Kamper  <info@sk-typo3.de>
 
+	* Fixed bug #14277: Improve t3lib_compressor (thanks to Steffen Gebert)
 	* Fixed bug #14279: Some non-XHTML tags in Backend (thanks to Steffen Gebert)
 
 2010-05-02  Sebastian Kurfuerst  <sebastian@typo3.org>
diff --git a/misc/advanced.htaccess b/misc/advanced.htaccess
index b49fc3f485900197ad46675ece0b2837f4825457..ef23b49af5c607e235fd3c83e23bce22b0565403 100644
--- a/misc/advanced.htaccess
+++ b/misc/advanced.htaccess
@@ -36,6 +36,20 @@
 # 
 ####
 
+##
+# Compressed .js and .css files
+##
+# uncomment the following lines if you use compression
+#
+#<FilesMatch "\.js\.gzip$">
+#  AddType "text/javascript" .gzip
+#</FilesMatch>
+#<FilesMatch "\.css\.gzip$">
+#  AddType "text/css" .gzip
+#</FilesMatch>
+#AddEncoding gzip .gzip
+
+
 ### Begin: Rewrite stuff ###
 
 # Enable URL rewriting
diff --git a/t3lib/class.t3lib_compressor.php b/t3lib/class.t3lib_compressor.php
index 74bf065e3aaf3d0f4c6953bfd89d8bf489973e12..06e26cc99e5ed948c57bd659bf03685800ddfba7 100644
--- a/t3lib/class.t3lib_compressor.php
+++ b/t3lib/class.t3lib_compressor.php
@@ -27,7 +27,7 @@
 
 /**
  * Compressor
- * This class can currently merge CSS files of the TYPO3 Backend.
+ * This merges and compresses CSS and JavaScript files of the TYPO3 Backend.
  *
  * @author	Steffen Gebert <steffen@steffen-gebert.de>
  * @package TYPO3
@@ -63,6 +63,17 @@ class t3lib_compressor {
 				$this->gzipCompressionLevel = $compressionLevel;
 			}
 		}
+
+			// decide whether we should create gzipped versions or not
+		$compressionLevel = $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['compressionLevel'];
+			// we need zlib for gzencode()
+		if (extension_loaded('zlib') && $compressionLevel) {
+			$this->createGzipped = TRUE;
+				// $compressionLevel can also be TRUE
+			if (t3lib_div::testInt($compressionLevel)) {
+				$this->gzipCompressionLevel = $compressionLevel;
+			}
+		}
 	}
 
 	/**
@@ -71,7 +82,7 @@ class t3lib_compressor {
 	 * Options:
 	 *   baseDirectories		If set, only include files below one of the base directories
 	 *
-	 * @param	array	$cssFiles		CSS files added to the PageRenderer
+	 * @param	array	$cssFiles		CSS files to process
 	 * @param	array	$options		Additional options
 	 * @return	array	CSS files
 	 */
@@ -144,8 +155,8 @@ class t3lib_compressor {
 	/**
 	 * Compress multiple css files
 	 *
-	 * @param array $cssFiles	The files to compress (array key = filename)
-	 * @return array 			The CSS files after compression (array key = new filename)
+	 * @param array $cssFiles	The files to compress (array key = filename), relative to requested page
+	 * @return array 			The CSS files after compression (array key = new filename), relative to requested page
 	 */
 	public function compressCssFiles(array $cssFiles) {
 		$filesAfterCompression = array();
@@ -154,7 +165,7 @@ class t3lib_compressor {
 			$filenameFromMainDir = substr($filename, strlen($GLOBALS['BACK_PATH']));
 				// if compression is enabled
 			if ($fileOptions['compress']) {
-				$filesAfterCompression[$GLOBALS['BACK_PATH'] . $this->compressCssFile($filename)] = $fileOptions;
+				$filesAfterCompression[$this->compressCssFile($filename)] = $fileOptions;
 			} else {
 				$filesAfterCompression[$filename] = $fileOptions;
 			}
@@ -171,8 +182,8 @@ class t3lib_compressor {
 	 * removes comments and whitespaces
 	 * Adopted from http://drupal.org/files/issues/minify_css.php__1.txt
 	 *
-	 * @param	string	$filename		Source filename
-	 * @return	string		Filename of the compressed file
+	 * @param	string	$filename		Source filename, relative to requested page
+	 * @return	string		Compressed filename, relative to requested page
 	 */
 	public function compressCssFile($filename) {
 			// generate the unique name of the file
@@ -218,7 +229,7 @@ class t3lib_compressor {
 			$this->writeFileAndCompressed($targetFile, $contents);
 		}
 
-		return '../' . $this->returnFileReference($targetFile);
+		return $GLOBALS['BACK_PATH'] . '../' . $this->returnFileReference($targetFile);
 	}
 
 	/**
@@ -255,6 +266,51 @@ class t3lib_compressor {
 		return $matches[0] . "\n/* ERROR! Unexpected _proccess_css_minify() parameter */\n"; // never get here
 	}
 
+	/**
+	 * Compress multiple javascript files
+	 *
+	 * @param	array	$jsFiles		The files to compress (array key = filename), relative to requested page
+	 * @return	array		The js files after compression (array key = new filename), relative to requested page
+		*/
+	public function compressJsFiles(array $jsFiles) {
+		$filesAfterCompression = array();
+		foreach ($jsFiles as $filename => $fileOptions) {
+				// we remove BACK_PATH from $filename, so make it relative to TYPO3_mainDir
+			$filenameFromMainDir = substr($filename, strlen($GLOBALS['BACK_PATH']));
+				// if compression is enabled
+			if ($fileOptions['compress']) {
+				$filesAfterCompression[$this->compressJsFile($filename)] = $fileOptions;
+			} else {
+				$filesAfterCompression[$filename] = $fileOptions;
+			}
+		}
+		return $filesAfterCompression;
+	}
+
+	/**
+	 * Compresses a javascript file
+	 *
+	 * Options:
+	 *   baseDirectories		If set, only include files below one of the base directories
+	 *
+	 * @param	string	$filename		Source filename, relative to requested page
+	 * @return	string		Filename of the compressed file, relative to requested page
+	 */
+	public function compressJsFile($filename) {
+			// generate the unique name of the file
+		$filenameAbsolute = t3lib_div::resolveBackPath(PATH_typo3 . substr($filename, strlen($GLOBALS['BACK_PATH'])));
+		$unique = $filenameAbsolute . filemtime($filenameAbsolute) . filesize($filenameAbsolute);
+
+		$pathinfo = pathinfo($filename);
+		$targetFile = $this->targetDirectory . $pathinfo['filename'] . '-' . md5($unique) . '.js';
+			// only create it, if it doesn't exist, yet
+		if (!file_exists(PATH_site . $targetFile) || ($this->createGzipped && !file_exists(PATH_site . $targetFile . '.gz'))) {
+			$contents = t3lib_div::getUrl($filenameAbsolute);
+			$this->writeFileAndCompressed($targetFile, $contents);
+		}
+		return $GLOBALS['BACK_PATH'] . '../' . $this->returnFileReference($targetFile);
+	}
+
 	/**
 	 * Decides whether a CSS file comes from one of the baseDirectories
 	 *
@@ -309,7 +365,7 @@ class t3lib_compressor {
 			if (isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['compressionLevel']) && is_numeric($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['compressionLevel'])) {
 				$compressionLevel = intval($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['compressionLevel']);
 			}
-			t3lib_div::writeFile(PATH_site . $filename . '.gz', gzencode($contents, $compressionLevel));
+			t3lib_div::writeFile(PATH_site . $filename . '.gzip', gzencode($contents, $compressionLevel));
 		}
 	}
 
@@ -323,7 +379,7 @@ class t3lib_compressor {
 	protected function returnFileReference($filename) {
 			// if the client accepts gzip and we can create gzipped files, we give him compressed versions
 		if ($this->createGzipped && strpos(t3lib_div::getIndpEnv('HTTP_ACCEPT_ENCODING'), 'gzip') !== FALSE) {
-			return $filename . '.gz';
+			return $filename . '.gzip';
 		} else {
 			return $filename;
 		}
diff --git a/t3lib/class.t3lib_pagerenderer.php b/t3lib/class.t3lib_pagerenderer.php
index b6ce14820e47f083e6dec95de5c44371968fbd29..97814303e8f8f03b2c37532d37f1f225085c90dc 100644
--- a/t3lib/class.t3lib_pagerenderer.php
+++ b/t3lib/class.t3lib_pagerenderer.php
@@ -47,6 +47,9 @@ class t3lib_PageRenderer implements t3lib_Singleton {
 	protected $csConvObj;
 	protected $lang;
 
+	/* @var t3lib_compressor Instance of t3lib_compressor */
+	protected $compressor;
+
 	// static array containing associative array for the included files
 	protected static $jsFiles = array ();
 	protected static $jsFooterFiles = array ();
@@ -1200,8 +1203,8 @@ class t3lib_PageRenderer implements t3lib_Singleton {
 		$out = '';
 
 		if ($this->addPrototype) {
-			$out .= '<script src="' . t3lib_div::createVersionNumberedFilename($this->backPath .
-				'contrib/prototype/prototype.js') . '" type="text/javascript"></script>' . LF;
+			$out .= '<script src="' . $this->processJsFile($this->backPath  . 'contrib/prototype/prototype.js') .
+				'" type="text/javascript"></script>' . LF;
 			unset($this->jsFiles[$this->backPath . 'contrib/prototype/prototype.js']);
 		}
 
@@ -1218,17 +1221,20 @@ class t3lib_PageRenderer implements t3lib_Singleton {
 			}
 
 			if (count($mods)) {
-				$moduleLoadString = '?load=' . implode(',', $mods);
+				foreach ($mods as $module) {
+					$out .= '<script src="' . $this->processJsFile($this->backPath .
+						'contrib/scriptaculous/' . $module . '.js') . '" type="text/javascript"></script>' . LF;
+					unset($this->jsFiles[$this->backPath . 'contrib/scriptaculous/' . $module . '.js']);
 			}
-			$out .= '<script src="' . t3lib_div::createVersionNumberedFilename($this->backPath .
-				'contrib/scriptaculous/scriptaculous.js' . $moduleLoadString, TRUE) .
-				'" type="text/javascript"></script>' . LF;
-			unset($this->jsFiles[$this->backPath . 'contrib/scriptaculous/scriptaculous.js' . $moduleLoadString]);
+		}
+			$out .= '<script src="' . $this->processJsFile($this->backPath .
+				'contrib/scriptaculous/scriptaculous.js') . '" type="text/javascript"></script>' . LF;
+			unset($this->jsFiles[$this->backPath . 'contrib/scriptaculous/scriptaculous.js']);
 		}
 
 			// include extCore
 		if ($this->addExtCore) {
-			$out .= '<script src="' . t3lib_div::createVersionNumberedFilename($this->backPath .
+			$out .= '<script src="' . $this->processJsFile($this->backPath .
 				'contrib/extjs/ext-core' . ($this->enableExtCoreDebug ? '-debug' : '') . '.js') .
 				'" type="text/javascript"></script>' . LF;
 			unset($this->jsFiles[$this->backPath . 'contrib/extjs/ext-core' . ($this->enableExtCoreDebug ? '-debug' : '') . '.js']);
@@ -1237,11 +1243,11 @@ class t3lib_PageRenderer implements t3lib_Singleton {
 			// include extJS
 		if ($this->addExtJS) {
 				// use the base adapter all the time
-			$out .= '<script src="' . t3lib_div::createVersionNumberedFilename($this->backPath .
+			$out .= '<script src="' . $this->processJsFile($this->backPath .
 				'contrib/extjs/adapter/' . ($this->enableExtJsDebug ?
 					str_replace('.js', '-debug.js', $this->extJSadapter) : $this->extJSadapter)) .
 				'" type="text/javascript"></script>' . LF;
-			$out .= '<script src="' . t3lib_div::createVersionNumberedFilename($this->backPath .
+			$out .= '<script src="' . $this->processJsFile($this->backPath .
 				'contrib/extjs/ext-all' . ($this->enableExtJsDebug ? '-debug' : '') . '.js') .
 				'" type="text/javascript"></script>' . LF;
 
@@ -1258,7 +1264,7 @@ class t3lib_PageRenderer implements t3lib_Singleton {
 				// TODO autoconvert file from UTF8 to current BE charset if necessary!!!!
 			$extJsLocaleFile = 'contrib/extjs/locale/ext-lang-' . $extJsLang . '.js';
 			if (file_exists(PATH_typo3 . $extJsLocaleFile)) {
-				$out .= '<script src="' . t3lib_div::createVersionNumberedFilename($this->backPath .
+				$out .= '<script src="' . $this->processJsFile($this->backPath .
 					$extJsLocaleFile) . '" type="text/javascript" charset="utf-8"></script>' . LF;
 			}
 
@@ -1302,16 +1308,16 @@ class t3lib_PageRenderer implements t3lib_Singleton {
 
 			if ($this->extJStheme) {
 				if (isset($GLOBALS['TBE_STYLES']['extJS']['theme'])) {
-					$this->addCssFile($this->backPath . $GLOBALS['TBE_STYLES']['extJS']['theme'], 'stylesheet', 'screen', '', FALSE, TRUE);
+					$this->addCssFile($this->backPath . $GLOBALS['TBE_STYLES']['extJS']['theme'], 'stylesheet', 'all', '', TRUE, TRUE);
 				} else {
-					$this->addCssFile($this->backPath . 'contrib/extjs/resources/css/xtheme-blue.css', 'stylesheet', 'screen', '', FALSE, TRUE);
+					$this->addCssFile($this->backPath . 'contrib/extjs/resources/css/xtheme-blue.css', 'stylesheet', 'all', '', TRUE, TRUE);
 				}
 			}
 			if ($this->extJScss) {
 				if (isset($GLOBALS['TBE_STYLES']['extJS']['all'])) {
-					$this->addCssFile($this->backPath . $GLOBALS['TBE_STYLES']['extJS']['all'], 'stylesheet', 'screen', '', FALSE, TRUE);
+					$this->addCssFile($this->backPath . $GLOBALS['TBE_STYLES']['extJS']['all'], 'stylesheet', 'all', '', TRUE, TRUE);
 				} else {
-					$this->addCssFile($this->backPath . 'contrib/extjs/resources/css/ext-all-notheme.css', 'stylesheet', 'screen', '', FALSE, TRUE);
+					$this->addCssFile($this->backPath . 'contrib/extjs/resources/css/ext-all-notheme.css', 'stylesheet', 'all', '', TRUE, TRUE);
 				}
 			}
 		} else {
@@ -1333,7 +1339,6 @@ class t3lib_PageRenderer implements t3lib_Singleton {
 	/**
 	 * concatenate files into one file
 	 * registered handler
-	 * TODO: implement own method
 	 *
 	 * @return void
 	 */
@@ -1355,9 +1360,8 @@ class t3lib_PageRenderer implements t3lib_Singleton {
 				// use extern concatenate routine
 				t3lib_div::callUserFunction($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['concatenateHandler'], $params, $this);
 			} elseif (TYPO3_MODE === 'BE') {
-				$compressor = t3lib_div::makeInstance('t3lib_compressor');
 				$cssOptions = array('baseDirectories' => $GLOBALS['TBE_TEMPLATE']->getSkinStylesheetDirectories());
-				$this->cssFiles = $compressor->concatenateCssFiles($this->cssFiles, $cssOptions);
+				$this->cssFiles = $this->getCompressor()->concatenateCssFiles($this->cssFiles, $cssOptions);
 			}
 		}
 	}
@@ -1396,8 +1400,12 @@ class t3lib_PageRenderer implements t3lib_Singleton {
 						}
 					}
 				}
+				if (TYPO3_MODE === 'BE') {
+					$this->jsFiles = $this->getCompressor()->compressJsFiles($this->jsFiles);
+					$this->jsFooterFiles = $this->getCompressor()->compressJsFiles($this->jsFooterFiles);
 			}
 		}
+		}
 		if ($this->compressCss) {
 				// use extern compress routine
 			$params = array (
@@ -1411,12 +1419,42 @@ class t3lib_PageRenderer implements t3lib_Singleton {
 				// use extern concatenate routine
 				t3lib_div::callUserFunction($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssCompressHandler'], $params, $this);
 			} elseif (TYPO3_MODE === 'BE') {
-				$compressor = t3lib_div::makeInstance('t3lib_compressor');
-				$this->cssFiles = $compressor->compressCssFiles($this->cssFiles);
+				$this->cssFiles = $this->getCompressor()->compressCssFiles($this->cssFiles);
 			}
 		}
 	}
 
+	/**
+	 * Returns instance of t3lib_compressor
+	 *
+	 * @return	t3lib_compressor		Instance of t3lib_compressor
+	 */
+	protected function getCompressor() {
+		if ($this->compressor === NULL) {
+			$this->compressor = t3lib_div::makeInstance('t3lib_compressor');
+}
+		return $this->compressor;
+	}
+
+	/**
+	 * Processes a Javascript file dependent on the current context
+	 *
+	 * Adds the version number for Frontend, compresses the file for Backend
+	 *
+	 * @param	string	$filename		Filename
+	 * @return	string		new filename
+	 */
+	protected function processJsFile($filename) {
+		switch (TYPO3_MODE) {
+			case 'FE':
+				$filename = t3lib_div::createVersionNumberedFilename($filename);
+				break;
+			case 'BE':
+				$filename = $this->getCompressor()->compressJsFile($filename);
+				break;
+		}
+		return $filename;
+	}
 }
 
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_pagerenderer.php']) {
diff --git a/typo3/backend.php b/typo3/backend.php
index 2676acb121f208dd6f003907991c29efb9610f5b..376241c4bb68ecb0dc6c27e663150056a2e913f6 100644
--- a/typo3/backend.php
+++ b/typo3/backend.php
@@ -127,7 +127,6 @@ class TYPO3backend {
 			'js/iecompatibility.js',
 			'js/flashupload.js',
 			'../t3lib/jsfunc.evalfield.js',
-			'ajax.php?ajaxID=ExtDirect::getAPI&namespace=TYPO3.Backend',
 			'../t3lib/js/extjs/ux/flashmessages.js',
 			'js/backend.js',
 			'js/loginrefresh.js',
@@ -238,6 +237,8 @@ class TYPO3backend {
 		foreach ($this->jsFiles as $jsFile) {
 			$this->pageRenderer->addJsFile($jsFile);
 		}
+			// we mustn't compress this file
+		$this->pageRenderer->addJsFile('ajax.php?ajaxID=ExtDirect::getAPI&namespace=TYPO3.Backend', NULL, FALSE);
 
 		$this->generateJavascript();
 		$this->pageRenderer->addJsInlineCode('BackendInlineJavascript', $this->js);
diff --git a/typo3/template.php b/typo3/template.php
index 9aa78af556be81777183ec2a48d1274bd82299c2..c431e5e67815ee6e0d312d852586f7d07030b03f 100644
--- a/typo3/template.php
+++ b/typo3/template.php
@@ -306,6 +306,7 @@ class template {
 			$this->pageRenderer->setLanguage($GLOBALS['LANG']->lang);
 			$this->pageRenderer->enableConcatenateFiles();
 			$this->pageRenderer->enableCompressCss();
+			$this->pageRenderer->enableCompressJavascript();
 		}
 		return $this->pageRenderer;
 	}