Index: typo3/sysext/em/classes/database/class.tx_em_database.php
===================================================================
--- typo3/sysext/em/classes/database/class.tx_em_database.php	(revision )
+++ typo3/sysext/em/classes/database/class.tx_em_database.php	(revision )
@@ -0,0 +1,396 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
+ *		   Steffen Kamper <info@sk-typo3.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * class.tx_em_database.php
+ *
+ * Module: Extension manager - DB access
+ *
+ * $Id: class.tx_em_database.php 2082 2010-03-21 17:19:42Z steffenk $
+ *
+ * @author  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author  Steffen Kamper <info@sk-typo3.de>
+ */
+
+/**
+ * DB access class for extension manager.
+ *
+ * Contains static methods for DB operations.
+ *
+ * @author	  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author	  Steffen Kamper <info@sk-typo3.de>
+ *
+ * @since	   2010-02-27
+ * @package	 TYPO3
+ * @subpackage  EM
+ */
+final class tx_em_Database {
+
+	const MULTI_LINEBREAKS = "\n\n\n";
+
+	const TABLE_REPOSITORY = 'sys_ter';
+
+	const TABLE_EXTENSION = 'cache_extensions';
+
+
+	/**
+	 * Get the count of extensions in cache_extensions from a repository.
+	 *
+	 * If $repository parameter is obmitted, sum of all extensions will be
+	 * returned.
+	 *
+	 * @access  public
+	 * @param   integer  $repository  (optional) repository uid of extensions to count
+	 * @return  integer  sum of extensions in database
+	 */
+	public function getExtensionCountFromRepository($repository = NULL) {
+		if (is_null($repository)) {
+			return $GLOBALS['TYPO3_DB']->exec_SELECTcountRows(
+				'DISTINCT(extkey)',
+				self::TABLE_EXTENSION
+			);
+		} else {
+			return $GLOBALS['TYPO3_DB']->exec_SELECTcountRows(
+				'DISTINCT(extkey)',
+				self::TABLE_EXTENSION,
+				'repository=' . intval($repository)
+			);
+		}
+	}
+
+	/**
+	 * Get extension list from cache_extensions
+	 *
+	 * @param int $repository
+	 * @param string $where
+	 * @param string $limit
+	 * @param string $orderBy
+	 * @param string $orderDir
+	 */
+	public function getExtensionListFromRepository($repository, $andWhere = '', $orderBy = '', $orderDir = 'ASC', $limit = '') {
+		$order = $orderBy ? $orderBy . ' ' . $orderDir : '';
+		$ret = array();
+
+		$temp = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
+			'count(*) count',
+			'cache_extensions',
+			'repository=' . intval($repository) . $andWhere,
+			'extkey'
+		);
+		$ret['count'] = count($temp);
+		$ret['results'] = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
+			'*, count(*) versions, max(intversion) maxintversion',
+			'cache_extensions',
+			'repository=' . intval($repository) . $andWhere,
+			'extkey',
+			$order,
+			$limit
+		);
+		return $ret;
+	}
+
+	/**
+	 *
+	 * @param int $repository
+	 * @param string $extKey
+	 */
+	public function getExtensionVersionsFromRepository($repository, $extKey) {
+
+	}
+
+	/**
+	 * Function inserts a repository object into database.
+	 *
+	 * @access  public
+	 * @param   tx_em_Repository $repository  repository object
+	 * @return  void
+	 */
+	public function updateRepository(tx_em_Repository $repository) {
+		$GLOBALS['TYPO3_DB']->exec_UPDATEquery(self::TABLE_REPOSITORY, $repository->getId(),
+			array(
+				'title' => $repository->getTitle(),
+				'description' => $repository->getDescription(),
+				'wsdl_url' => $repository->getWsdlUrl(),
+				'mirror_url' => $repository->getMirrorListUrl(),
+				'lastUpdated' => $repository->getLastUpdate(),
+				'extCount' => $repository->getExtensionCount(),
+			));
+
+	}
+
+
+	/**
+	 * Function inserts a repository object into database.
+	 *
+	 * @access  public
+	 * @param   tx_em_Repository $repository  repository object
+	 * @return  integer  UID of the newly inserted repository object
+	 */
+	public function insertRepository(tx_em_Repository $repository) {
+		$GLOBALS['TYPO3_DB']->exec_INSERTquery(self::TABLE_REPOSITORY,
+			array(
+				'title' => $repository->getId(),
+				'description' => $repository->getDescription(),
+				'wsdl_url' => $repository->getWsdlUrl(),
+				'mirror_url' => $repository->getMirrorListUrl(),
+				'lastUpdated' => $repository->getLastUpdate(),
+				'extCount' => $repository->getExtensionCount(),
+			));
+		return $GLOBALS['TYPO3_DB']->sql_insert_id();
+	}
+
+	/**
+	 * @param  $arrFields
+	 * @return void
+	 */
+	public function insertVersion(array $arrFields) {
+		$GLOBALS['TYPO3_DB']->exec_INSERTquery(self::TABLE_EXTENSION, $arrFields);
+	}
+
+	/**
+	 * Method finds and returns repository fields identified by its UID.
+	 *
+	 * @access  public
+	 * @param   int  $uid  repository UID
+	 */
+	public function getRepositoryByUID($uid) {
+		$row = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', self::TABLE_REPOSITORY, 'uid=' . intval($uid));
+
+		return $row[0];
+	}
+
+	/**
+	 * @param  $title
+	 * @return
+	 */
+	public function getRepositoryByTitle($title) {
+		return $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
+			'*',
+			self::TABLE_REPOSITORY,
+			'title=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($title,
+			self::TABLE_REPOSITORY)
+		);
+	}
+
+	/**
+	 * @param null $where
+	 * @return
+	 */
+	public function getRepositories($where = NULL) {
+		return $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
+			'*',
+			self::TABLE_REPOSITORY,
+			$where ? $where : ''
+		);
+	}
+
+	/**
+	 * Dump table content
+	 * Is DBAL compliant, but the dump format is written as MySQL standard. If the INSERT statements should be imported in a DBMS using other quoting than MySQL they must first be translated. t3lib_sqlengine can parse these queries correctly and translate them somehow.
+	 *
+	 * @param	string		Table name
+	 * @param	array		Field structure
+	 * @return	string		SQL Content of dump (INSERT statements)
+	 */
+	function dumpTableContent($table, $fieldStructure) {
+
+		// Substitution of certain characters (borrowed from phpMySQL):
+		$search = array('\\', '\'', "\x00", "\x0a", "\x0d", "\x1a");
+		$replace = array('\\\\', '\\\'', '\0', '\n', '\r', '\Z');
+
+		$lines = array();
+
+		// Select all rows from the table:
+		$result = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, '');
+
+		// Traverse the selected rows and dump each row as a line in the file:
+		while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
+			$values = array();
+			foreach ($fieldStructure as $field) {
+				$values[] = isset($row[$field]) ? "'" . str_replace($search, $replace, $row[$field]) . "'" : 'NULL';
+			}
+			$lines[] = 'INSERT INTO ' . $table . ' VALUES (' . implode(', ', $values) . ');';
+		}
+
+		// Free DB result:
+		$GLOBALS['TYPO3_DB']->sql_free_result($result);
+
+		// Implode lines and return:
+		return implode(LF, $lines);
+	}
+
+	/**
+	 * Gets the table and field structure from database.
+	 * Which fields and which tables are determined from the ext_tables.sql file
+	 *
+	 * @param	string		Array with table.field values
+	 * @return	array		Array of tables and fields splitted.
+	 */
+	function getTableAndFieldStructure($parts) {
+		// Instance of install tool
+		$instObj = new t3lib_install();
+		$dbFields = $instObj->getFieldDefinitions_database(TYPO3_db);
+
+		$outTables = array();
+		foreach ($parts as $table) {
+			$sub = explode('.', $table);
+			if ($sub[0] && isset($dbFields[$sub[0]])) {
+				if ($sub[1]) {
+					$key = explode('KEY:', $sub[1], 2);
+					if (count($key) == 2 && !$key[0]) { // key:
+						if (isset($dbFields[$sub[0]]['keys'][$key[1]])) {
+							$outTables[$sub[0]]['keys'][$key[1]] = $dbFields[$sub[0]]['keys'][$key[1]];
+						}
+					} else {
+						if (isset($dbFields[$sub[0]]['fields'][$sub[1]])) {
+							$outTables[$sub[0]]['fields'][$sub[1]] = $dbFields[$sub[0]]['fields'][$sub[1]];
+						}
+					}
+				} else {
+					$outTables[$sub[0]] = $dbFields[$sub[0]];
+				}
+			}
+		}
+
+		return $outTables;
+	}
+
+
+	/**
+	 * Makes a dump of the tables/fields definitions for an extension
+	 *
+	 * @param	array		Array with table => field/key definition arrays in
+	 * @return	string		SQL for the table definitions
+	 * @see dumpStaticTables()
+	 */
+	function dumpTableAndFieldStructure($arr) {
+		$tables = array();
+
+		if (count($arr)) {
+
+			// Get file header comment:
+			$tables[] = self::dumpHeader();
+
+			// Traverse tables, write each table/field definition:
+			foreach ($arr as $table => $fieldKeyInfo) {
+				$tables[] = self::dumpTableHeader($table, $fieldKeyInfo);
+			}
+		}
+
+		// Return result:
+		return implode(LF . LF . LF, $tables);
+	}
+
+	/**
+	 * Dump content for static tables
+	 *
+	 * @param	string		Comma list of tables from which to dump content
+	 * @return	string		Returns the content
+	 * @see dumpTableAndFieldStructure()
+	 */
+	function dumpStaticTables($tableList) {
+		$instObj = t3lib_div::makeInstance('t3lib_install');
+		$dbFields = $instObj->getFieldDefinitions_database(TYPO3_db);
+
+		$out = '';
+		$parts = t3lib_div::trimExplode(',', $tableList, TRUE);
+
+		// Traverse the table list and dump each:
+		foreach ($parts as $table) {
+			if (is_array($dbFields[$table]['fields'])) {
+				$header = self::dumpHeader();
+				$tableHeader = self::dumpTableHeader($table, $dbFields[$table], TRUE);
+				$insertStatements = self::dumpTableContent($table, $dbFields[$table]['fields']);
+				$out .= $header . self::MULTI_LINEBREAKS .
+						$tableHeader . self::MULTI_LINEBREAKS .
+						$insertStatements . self::MULTI_LINEBREAKS;
+			} else {
+				throw new RuntimeException(
+					'TYPO3 Fatal Error: ' . $GLOBALS['LANG']->getLL('dumpStaticTables_table_not_found'),
+					1270853983
+				);
+			}
+		}
+		unset($instObj);
+		return $out;
+	}
+
+	/**
+	 * Header comments of the SQL dump file
+	 *
+	 * @return	string		Table header
+	 */
+	function dumpHeader() {
+		return trim('
+# TYPO3 Extension Manager dump 1.1
+#
+# Host: ' . TYPO3_db_host . '    Database: ' . TYPO3_db . '
+#--------------------------------------------------------
+');
+	}
+
+	/**
+	 * Dump CREATE TABLE definition
+	 *
+	 * @param	string		Table name
+	 * @param	array		Field and key information (as provided from Install Tool class!)
+	 * @param	boolean		If true, add "DROP TABLE IF EXISTS"
+	 * @return	string		Table definition SQL
+	 */
+	function dumpTableHeader($table, $fieldKeyInfo, $dropTableIfExists = 0) {
+		$lines = array();
+		$dump = '';
+
+		// Create field definitions
+		if (is_array($fieldKeyInfo['fields'])) {
+			foreach ($fieldKeyInfo['fields'] as $fieldN => $data) {
+				$lines[] = '  ' . $fieldN . ' ' . $data;
+			}
+		}
+
+		// Create index key definitions
+		if (is_array($fieldKeyInfo['keys'])) {
+			foreach ($fieldKeyInfo['keys'] as $fieldN => $data) {
+				$lines[] = '  ' . $data;
+			}
+		}
+
+		// Compile final output:
+		if (count($lines)) {
+			$dump = trim('
+#
+# Table structure for table "' . $table . '"
+#
+' . ($dropTableIfExists ? 'DROP TABLE IF EXISTS ' . $table . ';
+' : '') . 'CREATE TABLE ' . $table . ' (
+' . implode(',' . LF, $lines) . '
+);');
+		}
+
+		return $dump;
+	}
+
+}
+
+?>
\ No newline at end of file
Index: t3lib/core_autoload.php
===================================================================
--- t3lib/core_autoload.php	(revision 9253)
+++ t3lib/core_autoload.php	(revision )
@@ -176,8 +176,5 @@
 
 $tslibClasses = require(PATH_typo3 . 'sysext/cms/ext_autoload.php');
 
-$emClasses = array();
-$emClasses = require(PATH_typo3 . 'sysext/em/ext_autoload.php');
-
-return array_merge($t3libClasses, $tslibClasses, $emClasses);
+return array_merge($t3libClasses, $tslibClasses);
 ?>
Index: typo3/sysext/em/ext_emconf.php
===================================================================
--- typo3/sysext/em/ext_emconf.php	(revision 8676)
+++ typo3/sysext/em/ext_emconf.php	(revision )
@@ -34,7 +34,7 @@
 	'CGLcompliance' => '',
 	'CGLcompliance_note' => '',
 	'version' => '1.1.0',
-	'_md5_values_when_last_written' => 'a:16:{s:12:"ext_icon.gif";s:4:"3a30";s:14:"ext_tables.php";s:4:"6e0d";s:23:"mod1/class.em_index.php";s:4:"4966";s:22:"mod1/class.em_soap.php";s:4:"67b6";s:31:"mod1/class.em_terconnection.php";s:4:"630f";s:23:"mod1/class.em_unzip.php";s:4:"e3a9";s:28:"mod1/class.em_xmlhandler.php";s:4:"8445";s:21:"mod1/class.nusoap.php";s:4:"dfa8";s:14:"mod1/clear.gif";s:4:"cc11";s:13:"mod1/conf.php";s:4:"6ea9";s:17:"mod1/download.png";s:4:"c5b2";s:11:"mod1/em.gif";s:4:"3a30";s:14:"mod1/index.php";s:4:"e8e5";s:16:"mod1/install.gif";s:4:"8d57";s:14:"mod1/oodoc.gif";s:4:"744b";s:18:"mod1/uninstall.gif";s:4:"a77f";}',
+	'_md5_values_when_last_written' => 'a:16:{s:12:"ext_icon.gif";s:4:"3a30";s:14:"ext_tables.php";s:4:"6e0d";s:23:"mod1/index.php";s:4:"4966";s:22:"mod1/class.tx_em_Connection_Soap.php";s:4:"67b6";s:31:"mod1/class.tx_em_Connection_Ter.php";s:4:"630f";s:23:"mod1/class.tx_em_tools_unzip.php";s:4:"e3a9";s:28:"mod1/class.tx_em_tools_xmlhandler.php";s:4:"8445";s:21:"mod1/class.nusoap.php";s:4:"dfa8";s:14:"mod1/clear.gif";s:4:"cc11";s:13:"mod1/conf.php";s:4:"6ea9";s:17:"mod1/download.png";s:4:"c5b2";s:11:"mod1/em.gif";s:4:"3a30";s:14:"mod1/index.php";s:4:"e8e5";s:16:"mod1/install.gif";s:4:"8d57";s:14:"mod1/oodoc.gif";s:4:"744b";s:18:"mod1/uninstall.gif";s:4:"a77f";}',
 	'constraints' => array(
 		'depends' => array(
 			'cms' => '',
Index: typo3/sysext/em/classes/connection/class.tx_em_connection_extdirectserver.php
===================================================================
--- typo3/sysext/em/classes/connection/class.tx_em_connection_extdirectserver.php	(revision )
+++ typo3/sysext/em/classes/connection/class.tx_em_connection_extdirectserver.php	(revision )
@@ -0,0 +1,679 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Steffen Kamper (info@sk-typo3.de)
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * Module: Extension manager, developer module
+ *
+ * This class handles all Ajax calls coming from ExtJS
+ *
+ * $Id: class.tx_em_Connection_ExtDirectServer.php 2083 2010-03-22 00:48:31Z steffenk $
+ *
+ * @author	Steffen Kamper <info@sk-typo3.de>
+ */
+
+
+class tx_em_Connection_ExtDirectServer {
+	/**
+	 * @var tx_em_Tools_XmlHandler
+	 */
+	var $xmlhandler;
+
+	/**
+	 * Keeps instance of settings class.
+	 *
+	 * @var tx_em_Settings
+	 */
+	static protected $objSettings;
+
+
+	/*********************************************************************/
+	/* General                                                           */
+	/*********************************************************************/
+
+	public function __construct() {
+		$GLOBALS['TBE_TEMPLATE'] = t3lib_div::makeInstance('template');
+	}
+
+
+	/**
+	 * Method returns instance of settings class.
+	 *
+	 * @access  protected
+	 * @return  em_settings  instance of settings class
+	 */
+	protected function getSettingsObject() {
+		if (!is_object(self::$objSettings) && !(self::$objSettings instanceof tx_em_Settings)) {
+			self::$objSettings = t3lib_div::makeInstance('tx_em_Settings');
+		}
+		return self::$objSettings;
+	}
+
+
+	/*********************************************************************/
+	/* Local Extension List                                              */
+	/*********************************************************************/
+
+
+	/**
+	 * Render local extension list
+	 *
+	 * @return string $content
+	 */
+	public function getExtensionList() {
+		$list = t3lib_div::makeInstance('tx_em_Extensions_List');
+		$extList = $list->getInstalledExtensions(TRUE);
+
+
+		return array(
+			'length' => count($extList),
+			'data' => $extList
+		);
+
+	}
+
+	/**
+	 * Enter description here...
+	 *
+	 * @return unknown
+	 */
+	public function getInstalledExtkeys() {
+		$list = t3lib_div::makeInstance('tx_em_Extensions_List');
+		$extList = $list->getInstalledExtensions(TRUE);
+
+
+		$temp = $this->getSettings();
+		$selectedLanguage = unserialize($temp['selectedLanguages']);
+
+
+		$keys = array();
+		$i = 0;
+		foreach ($extList as $ext) {
+			if ($ext['installed']) {
+				$keys[$i] = array(
+					'extkey' => $ext['extkey'],
+					'icon' => $ext['icon'],
+					'stype' => $ext['typeShort'],
+				);
+				foreach ($selectedLanguage as $language) {
+					$keys[$i]['lang'][] = $GLOBALS['LANG']->sL('LLL:EXT:setup/mod/locallang.xml:lang_' . $language);
+				}
+				$i++;
+			}
+		}
+
+		return array(
+			'length' => count($keys),
+			'data' => $keys,
+		);
+	}
+
+	/**
+	 * Render module content
+	 *
+	 * @return string $content
+	 */
+	public function getExtensionDetails() {
+		$list = t3lib_div::makeInstance('tx_em_Extensions_List');
+		$extList = $list->getInstalledExtensions(TRUE);
+
+
+		return array(
+			'length' => count($extList),
+			'data' => $extList
+		);
+
+	}
+
+	/**
+	 * Render extension update
+	 *
+	 * @car string $extKey
+	 * @return string $content
+	 */
+	public function getExtensionUpdate($extKey) {
+		if (isset($GLOBALS['TYPO3_LOADED_EXT'][$extKey])) {
+			$path = t3lib_extMgm::extPath($extKey);
+			$ext = array();
+
+			$install = t3lib_div::makeInstance('tx_em_Install');
+			$extension = t3lib_div::makeInstance('tx_em_Extensions_List');
+			$extension->singleExtInfo($extKey, $path, $ext);
+			$ext = $ext[0];
+			$update = $install->checkDBupdates($extKey, $ext);
+			return $update ? $update : 'Extension is up to date.';
+		} else {
+			return 'Extension "' . htmlspecialchars($extKey) . '" is not installed.';
+		}
+	}
+
+
+	/**
+	 * Render extension configuration
+	 *
+	 * @car string $extKey
+	 * @return string $content
+	 */
+	public function getExtensionConfiguration($extKey) {
+		$extensionList = t3lib_div::makeInstance('tx_em_Extensions_List', $this);
+		list($list,) = $extensionList->getInstalledExtensions();
+		$install = t3lib_div::makeInstance('tx_em_Install');
+		$form = $install->updatesForm($extKey, $list[$extKey], 1);
+		if (!$form) {
+			return '<p>' . 'This extension has no configuration.' . '</p>';
+		} else {
+			return $form;
+		}
+	}
+
+	/**
+	 * Save extension configuration
+	 *
+	 * @formHandler
+	 * @param array $parameter
+	 */
+	public function saveExtensionConfiguration($parameter) {
+		return array(
+			'success' => true,
+			'data' => $parameter
+		);
+	}
+
+	/**
+	 * Enter description here...
+	 *
+	 * @param unknown_type $parameter
+	 * @return unknown
+	 */
+	public function getExtFileTree($parameter) {
+		$ext = array();
+		$extKey = $parameter->extkey;
+		$type = $parameter->typeShort;
+		$node = strpos($parameter->node, '/') !== FALSE ? $parameter->node : $parameter->baseNode;
+
+		$path = PATH_site . $node;
+		$fileArray = array();
+
+		$dirs = t3lib_div::get_dirs($path);
+		$files = t3lib_div::getFilesInDir($path, '', FALSE, '', '');
+
+		$editTypes = explode(',', $GLOBALS['TYPO3_CONF_VARS']['SYS']['textfile_ext']);
+		$imageTypes = array('gif', 'jpg', 'png');
+
+		if (!is_array($files) || !count($files)) {
+			return array();
+		}
+
+		foreach ($dirs as $dir) {
+			if ($dir{0} !== '.') {
+				$fileArray[] = array(
+					'id' => $node . '/' . $dir,
+					'text' => htmlspecialchars($dir),
+					'leaf' => false,
+					'qtip' => ''
+				);
+			}
+		}
+
+
+		foreach ($files as $key => $file) {
+			$fileExt = strtolower(substr($file, strrpos($file, '.') + 1));
+			if (in_array($fileExt, $imageTypes)) {
+				$cls = 'tree-image';
+			} elseif (in_array($fileExt, $editTypes)) {
+				$cls = 'tree-edit';
+			} else {
+				$cls = 'tree-unknown';
+			}
+			$fileArray[] = array(
+				'id' => $node . '/' . $file,
+				'text' => htmlspecialchars($file),
+				'leaf' => true,
+				'qtip' => $fileExt . ' - file',
+				'iconCls' => $cls
+			);
+		}
+		return $fileArray;
+	}
+
+	/**
+	 * Read extension file and send content
+	 *
+	 * @param string $path
+	 * @return string file content
+	 */
+	public function readExtFile($path) {
+		$path = PATH_site . $path;
+		if (@file_exists($path)) {
+			//TODO: charset conversion
+			return t3lib_div::getURL($path);
+		}
+		return '';
+	}
+
+	/**
+	 * Save extension file
+	 *
+	 * @param unknown_type $file
+	 * @param unknown_type $content
+	 * @return boolean success
+	 */
+	public function saveExtFile($file, $content) {
+		$path = PATH_site . $path;
+		if (@file_exists($path)) {
+			//TODO: save only if saving was enabled
+			#return t3lib_div::writeFile($path, $content);
+			return TRUE;
+		}
+		return FALSE;
+	}
+
+
+	/**
+	 * Load upload form for extension upload to TER
+	 *
+	 * @formcHandler
+	 * return array
+	 */
+	public function loadUploadExtToTer() {
+		$settings = $this->getSettings();
+		return array(
+			'success' => TRUE,
+			'data' => array(
+				'fe_u' => $settings['fe_u'],
+				'fe_p' => $settings['fe_p']
+			)
+		);
+	}
+
+	/**
+	 * Upload extension to TER
+	 *
+	 * @formHandler
+	 *
+	 * @param string $parameter
+	 * return array
+	 */
+	public function uploadExtToTer($parameter) {
+		return array(
+			'success' => TRUE,
+			'fe_p' => $parameter['fe_p'],
+			'fe_u' => $parameter['fe_u'],
+			'newversion' => $parameter['newversion'],
+			'uploadcomment' => $parameter['uploadcomment']
+		);
+	}
+
+	/**
+	 * Prints developer information
+	 *
+	 * @param string $parameter
+	 * return array
+	 */
+	public function getExtensionDevelopInfo($extKey) {
+		$extensionList = t3lib_div::makeInstance('tx_em_Extensions_List', $this);
+		list($list,) = $extensionList->getInstalledExtensions();
+		$extensionDetails = t3lib_div::makeInstance('tx_em_Extensions_Details', $this);
+		return $extensionDetails->extInformationarray($extKey, $list[$extKey]);
+	}
+
+	/*********************************************************************/
+	/* Remote Extension List                                             */
+	/*********************************************************************/
+
+
+	/**
+	 * Render remote extension list
+	 *
+	 * @return string $content
+	 */
+	public function getRemoteExtensionList($parameters) {
+		/* @var $repoUtility em_repository_utility */
+		$repoUtility = t3lib_div::makeInstance('tx_em_Repository_Utility');
+		$repoUtility->setRepository($this->getSettingsObject()->getSelectedRepository());
+
+		$search = $parameters->query;
+		$limit = $parameters->start . ', ' . $parameters->limit;
+		$orderBy = $parameters->sort;
+		$orderDir = $parameters->dir;
+
+		if ($search == '*') {
+			$where = '';
+		} else {
+			$quotedSearch = $GLOBALS['TYPO3_DB']->escapeStrForLike(
+				$GLOBALS['TYPO3_DB']->quoteStr($search, 'cache_extensions'),
+				'cache_extensions'
+			);
+			$where = ' AND (extkey LIKE \'%' . $quotedSearch . '%\' OR title LIKE \'%' . $quotedSearch . '%\')';
+		}
+
+		$list = tx_em_Database::getExtensionListFromRepository(
+			$repoUtility->getRepositoryUID(),
+			$where,
+			$orderBy,
+			$orderDir,
+			$limit
+		);
+
+
+		return array(
+			'length' => $list['count'],
+			'data' => $list['results']
+		);
+
+	}
+
+
+	/**
+	 * Loads repositories
+	 *
+	 *
+	 * @return array
+	 */
+	public function repositoryUpdateLoad() {
+		$settings = $this->getSettings();
+		$repositories = tx_em_Database::getRepositories();
+		foreach ($repositories as $uid => $repository) {
+			$data[] = array(
+				'title' => $repository['title'],
+				'value' => $repository['uid'],
+				'description' => $repository['description'],
+				'wsdl_url' => $repository['wsdl_url'],
+				'mirror_url' => $repository['mirror_url'],
+				'count' => $repository['extCount'],
+				'updated' => $repository['lastUpdated'] ? date('d/m/Y H:i', $repository['lastUpdated']) : 'never',
+				'selected' => $repository['uid'] === $settings['selectedRepository'],
+			);
+		}
+
+		return array(
+			'length' => count($data),
+			'data' => $data,
+		);
+	}
+
+	/**
+	 * Edit / Create repository
+	 *
+	 * @formHandler
+	 * @param array $parameter
+	 * @return array
+	 */
+	public function repositoryEditFormSubmit($parameter) {
+
+
+		return array(
+			'success' => TRUE,
+			'data' => array(
+				'params' => $parameter
+			),
+		);
+	}
+
+	/**
+	 * Update repository
+	 *
+	 * @formHandler
+	 *
+	 * @param array $parameter
+	 * @return array
+	 */
+	public function repositoryUpdate($parameter) {
+		if (!intval($parameter['rep'])) {
+			return array(
+				'success' => FALSE,
+				'errors' => 'no repository choosen'
+			);
+		}
+
+		$objRepository = t3lib_div::makeInstance('tx_em_Repository', intval($parameter['rep']));
+		$objRepositoryUtility = t3lib_div::makeInstance('tx_em_Repository_Utility', $objRepository);
+		$count = $objRepositoryUtility->updateExtList();
+
+
+		if ($count) {
+			#$objRepository->setExtensionCount($count);
+			#$objRepository->setLastUpdate(time());
+			#tx_em_Database::updateRepository($objRepository);
+			return array(
+				'success' => TRUE,
+				'data' => array(
+					'count' => $count
+				)
+			);
+		} else {
+			return array(
+				'success' => FALSE,
+				'errormsg' => 'Your repository is up to date.'
+			);
+		}
+	}
+
+
+	/*********************************************************************/
+	/* Translation Handling                                              */
+	/*********************************************************************/
+
+
+	/**
+	 * Enter description here...
+	 *
+	 * @return unknown
+	 */
+	public function getLanguages() {
+
+		$temp = $this->getSettings();
+		$selected = unserialize($temp['selectedLanguages']);
+		$theLanguages = t3lib_div::trimExplode('|', TYPO3_languages);
+		//drop default
+		array_shift($theLanguages);
+		$lang = array();
+		foreach ($theLanguages as $language) {
+			$label = htmlspecialchars($GLOBALS['LANG']->sL('LLL:EXT:setup/mod/locallang.xml:lang_' . $language));
+			$flag = @is_file(PATH_typo3 . 'gfx/flags/' . $language . '.gif') ? 'gfx/flags/' . $language . '.gif' : 'gfx/flags/unknown.gif';
+			$lang[] = array(
+				'label' => $label,
+				'lang' => $language,
+				'flag' => $flag,
+				'selected' => in_array($language, $selected) ? 1 : 0
+			);
+		}
+		return array(
+			'length' => count($lang),
+			'data' => $lang,
+		);
+
+	}
+
+	/**
+	 * Enter description here...
+	 *
+	 * @param unknown_type $parameter
+	 * @return unknown
+	 */
+	public function saveLanguageSelection($parameter) {
+		$settings = $this->getSettings();
+		$this->saveSetting('selectedLanguages', serialize($parameter));
+		return 'Saved languages: ' . implode(', ', $parameter);
+	}
+
+
+	/**
+	 * Enter description here...
+	 *
+	 * @param unknown_type $extkey
+	 * @param unknown_type $type
+	 * @param unknown_type $selection
+	 * @return unknown
+	 */
+	public function fetchTranslations($extkey, $type, $selection) {
+		$result = array();
+		if (is_array($selection) && count($selection)) {
+			$terConnection = t3lib_div::makeInstance('tx_em_Connection_Ter', $this);
+			$this->xmlhandler = t3lib_div::makeInstance('tx_em_Tools_XmlHandler');
+			$this->xmlhandler->emObj = $this;
+			$mirrorURL = $this->getSettingsObject()->getMirrorURL();
+
+			foreach ($selection as $lang) {
+				$fetch = $terConnection->fetchTranslationStatus($extkey, $mirrorURL);
+				$localmd5 = '';
+				if (!isset($fetch[$lang])) {
+					//no translation available
+					$result[0][$lang] = 'N/A';
+				} else {
+					$localmd5 = '';
+					if (is_file(PATH_site . 'typo3temp/' . $extkey . '-l10n-' . $lang . '.zip')) {
+						$localmd5 = md5_file(PATH_site . 'typo3temp/' . $extkey . '-l10n-' . $lang . '.zip');
+					}
+					if ($localmd5 !== $fetch[$lang]['md5']) {
+						if ($type) {
+							//fetch translation
+							$ret = $terConnection->updateTranslation($extkey, $lang, $mirrorURL);
+							$result[0][$lang] = $ret ? 'updated' : 'failed';
+						} else {
+							//translation status
+							$result[0][$lang] = $localmd5 !== '' ? 'update' : 'new';
+						}
+					} else {
+						//translation is up to date
+						$result[0][$lang] = 'ok';
+					}
+				}
+
+
+			}
+		}
+		return $result;
+	}
+
+
+	/*********************************************************************/
+	/* Settings                                                          */
+	/*********************************************************************/
+
+	/**
+	 * Returns settings object.
+	 *
+	 * @access  public
+	 * @return  em_settings  instance of settings object
+	 */
+	public function getSettings() {
+		return $this->getSettingsObject()->getSettings();
+	}
+
+	/**
+	 * Enter description here...
+	 *
+	 * @param unknown_type $name
+	 * @param unknown_type $value
+	 * @return unknown
+	 */
+	public function saveSetting($name, $value) {
+		$this->getSettingsObject()->saveSetting($name, $value);
+		return TRUE;
+	}
+
+	/**
+	 * Load form values for settings form
+	 *
+	 *
+	 * @return array FormValues
+	 */
+	public function settingsFormLoad() {
+		$settings = $this->getSettings();
+
+		return array(
+			'success' => TRUE,
+			'data' => array(
+				'display_unchecked' => $settings['display_unchecked'],
+				'fe_u' => $settings['fe_u'],
+				'fe_p' => $settings['fe_p'],
+				'selectedMirror' => $settings['selectedMirror'],
+				'selectedRepository' => $settings['selectedRepository'],
+			)
+		);
+	}
+
+	/**
+	 * Enter description here...
+	 *
+	 * @formHandler
+	 * @param array $parameter
+	 */
+	public function settingsFormSubmit($parameter) {
+		$settings = $this->getSettingsObject()->saveSettings(array(
+			'display_unchecked' => isset($parameter['display_unchecked']),
+			'fe_u' => $parameter['fe_u'],
+			'fe_p' => $parameter['fe_p'],
+			'selectedMirror' => $parameter['selectedMirror'],
+			'selectedRepository' => $parameter['selectedRepository'],
+		));
+		return array(
+			'success' => TRUE,
+			'data' => $parameter,
+			'settings' => $settings
+		);
+	}
+
+
+	/*********************************************************************/
+	/* EM Tools                                                          */
+	/*********************************************************************/
+
+	/**
+	 * Upload an extension
+	 *
+	 * @formHandler
+	 *
+	 * @access  public
+	 * @param $parameter composed parameter from $POST and $_FILES
+	 * @return  array status
+	 */
+	public function uploadExtension($parameter) {
+		$uploadedTempFile = t3lib_div::upload_to_tempfile($parameter['extupload-path']['tmp_name']);
+		$location = ($parameter['loc'] === 'G' || $parameter['loc'] === 'S') ? $parameter['loc'] : 'L';
+		$uploadOverwrite = $parameter['uploadOverwrite'] ? TRUE : FALSE;
+
+		$install = t3lib_div::makeInstance('tx_em_Install', $this);
+		$upload = $install->uploadExtensionFile($uploadedTempFile, $location, $uploadOverwrite);
+
+		if ($upload[0] === FALSE) {
+			return array(
+				'success' => FALSE,
+				'error' => $upload[1]
+			);
+		}
+		$extKey = $upload[1][0]['extKey'];
+		$result = $install->installExtension($upload[1], $location);
+		return array(
+			'success' => TRUE,
+			'data' => $result,
+			'extKey' => $extKey
+		);
+
+	}
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/parser/class.tx_em_parser_mirrorxmlabstractparser.php
===================================================================
--- typo3/sysext/em/classes/parser/class.tx_em_parser_mirrorxmlabstractparser.php	(revision )
+++ typo3/sysext/em/classes/parser/class.tx_em_parser_mirrorxmlabstractparser.php	(revision )
@@ -0,0 +1,225 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
+ *		   Steffen Kamper <info@sk-typo3.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * class.tx_em_parser_mirrorxmlabstractparser.php
+ *
+ * Module: Extension manager - mirror.xml abstract parser
+ *
+ * $Id: class.tx_em_parser_mirrorxmlabstractparser.php 1913 2010-02-21 15:47:37Z mkrause $
+ *
+ * @author  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author  Steffen Kamper <info@sk-typo3.de>
+ */
+
+
+/**
+ * Abstract parser for TYPO3's mirror.xml file.
+ *
+ * @author	  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author	  Steffen Kamper <info@sk-typo3.de>
+ *
+ * @since	   2010-02-09
+ * @package	 TYPO3
+ * @subpackage  EM
+ */
+abstract class tx_em_Parser_MirrorXmlAbstractParser extends tx_em_Parser_XmlAbstractParser {
+
+
+	/**
+	 * Keeps country of currently processed mirror.
+	 *
+	 * @var  string
+	 */
+	protected $country = NULL;
+
+	/**
+	 * Keeps hostname of currently processed mirror.
+	 *
+	 * @var  string
+	 */
+	protected $host = NULL;
+
+	/**
+	 * Keeps path to mirrored TER of currently processed mirror.
+	 *
+	 * @var  string
+	 */
+	protected $path = NULL;
+
+	/**
+	 * Keeps sponsor link of currently processed mirror.
+	 *
+	 * @var  string
+	 */
+	protected $sponsorlink = NULL;
+
+	/**
+	 * Keeps sponsor logo location of currently processed mirror.
+	 *
+	 * @var  string
+	 */
+	protected $sponsorlogo = NULL;
+
+	/**
+	 * Keeps sponsor name of currently processed mirror.
+	 *
+	 * @var  string
+	 */
+	protected $sponsorname = NULL;
+
+	/**
+	 * Keeps title of currently processed mirror.
+	 *
+	 * @var  string
+	 */
+	protected $title = NULL;
+
+
+	/**
+	 * Returns an assoziative array of all mirror properties.
+	 *
+	 * Valid array keys of returned array are:
+	 * country, host, path, sponsorlink, sponsorlogo, sponsorname, title
+	 *
+	 * @access  public
+	 * @return  array  assoziative array of a mirror's properties
+	 * @see	 $country, $host, $path, $sponsorlink, $sponsorlogo, $sponsorname, $title
+	 */
+	public function getAll() {
+		$mirrorProperties = array();
+		$mirrorProperties['title'] = $this->title;
+		$mirrorProperties['host'] = $this->host;
+		$mirrorProperties['path'] = $this->path;
+		$mirrorProperties['country'] = $this->country;
+		$mirrorProperties['sponsorname'] = $this->sponsorname;
+		$mirrorProperties['sponsorlink'] = $this->sponsorlink;
+		$mirrorProperties['sponsorlogo'] = $this->sponsorlogo;
+		return $mirrorProperties;
+	}
+
+	/**
+	 * Returns country of currently processed mirror.
+	 *
+	 * @access  public
+	 * @return  string  name of country a mirror is located in
+	 * @see	 $country, getAll()
+	 */
+	public function getCountry() {
+		return $this->country;
+	}
+
+	/**
+	 * Returns host of currently processed mirror.
+	 *
+	 * @access  public
+	 * @return  string  host name
+	 * @see	 $host, getAll()
+	 */
+	public function getHost() {
+		return $this->host;
+	}
+
+	/**
+	 * Returns path to mirrored TER of currently processed mirror.
+	 *
+	 * @access  public
+	 * @return  string  path name
+	 * @see	 $path, getAll()
+	 */
+	public function getPath() {
+		return $this->path;
+	}
+
+	/**
+	 * Returns sponsor link of currently processed mirror.
+	 *
+	 * @access  public
+	 * @return  string  URL of a sponsor's website
+	 * @see	 $sponsorlink, getAll()
+	 */
+	public function getSponsorlink() {
+		return $this->sponsorlink;
+	}
+
+	/**
+	 * Returns sponsor logo location of currently processed mirror.
+	 *
+	 * @access  public
+	 * @return  string  a sponsor's logo location
+	 * @see	 $sponsorlogo, getAll()
+	 */
+	public function getSponsorlogo() {
+		return $this->sponsorlogo;
+	}
+
+	/**
+	 * Returns sponsor name of currently processed mirror.
+	 *
+	 * @access  public
+	 * @return  string  name of sponsor
+	 * @see	 $sponsorname, getAll()
+	 */
+	public function getSponsorname() {
+		return $this->sponsorname;
+	}
+
+	/**
+	 * Returns title of currently processed mirror.
+	 *
+	 * @access  public
+	 * @return  string  title of mirror
+	 * @see	 $title, get All()
+	 */
+	public function getTitle() {
+		return $this->title;
+	}
+
+	/**
+	 * Method resets version class properties.
+	 *
+	 * @access  protected
+	 * @return  void
+	 * @see	 $country, $host, $path, $sponsorlink, $sponsorlogo, $sponsorname, $title
+	 */
+	protected function resetProperties() {
+		$this->title = $this->host = $this->path =
+				$this->country = $this->sponsorname = $this->sponsorlink =
+						$this->sponsorlogo;
+	}
+
+	/**
+	 * Method provides a wrapper for an exception call
+	 *
+	 * @access  protected
+	 * @param   string	 $message  the exception message to throw.
+	 * @param   integer	$code  the exception code.
+	 * @return  void
+	 */
+	protected function throwException($message = "", $code = 0) {
+		throw new tx_em_MirrorXmlException(get_class($this) . ': ' . $message, $code);
+	}
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/import/class.tx_em_import_extensionlistimporter.php
===================================================================
--- typo3/sysext/em/classes/import/class.tx_em_import_extensionlistimporter.php	(revision )
+++ typo3/sysext/em/classes/import/class.tx_em_import_extensionlistimporter.php	(revision )
@@ -0,0 +1,207 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
+ *		   Steffen Kamper <info@sk-typo3.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * class.tx_em_import_extensionlistimporter.php
+ *
+ * Module: Extension manager - Extension list importer
+ *
+ * $Id: class.tx_em_import_extensionlistimporter.php 2016 2010-03-14 04:01:47Z mkrause $
+ *
+ * @author  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author  Steffen Kamper <info@sk-typo3.de>
+ */
+
+/**
+ * Importer object for extension list
+ *
+ * @author	  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author	  Steffen Kamper <info@sk-typo3.de>
+ *
+ * @since	   2010-02-10
+ * @package	 TYPO3
+ * @subpackage  EM
+ */
+class tx_em_Import_ExtensionListImporter implements SplObserver {
+
+	/**
+	 * Keeps instance of a XML parser.
+	 *
+	 * @var em_xml_abstract_parser
+	 */
+	protected $parser;
+
+	/**
+	 * Keeps number of processed version records.
+	 *
+	 * @var integer
+	 */
+	protected $sumRecords = 0;
+
+	/**
+	 * Keeps record values to be inserted into database.
+	 *
+	 * @var  array
+	 */
+	protected $arrRows = array();
+
+	/**
+	 * Keeps fieldnames of cache_extension table.
+	 *
+	 * @var  array
+	 */
+	static protected $fieldNames = array('extkey', 'version', 'intversion', 'alldownloadcounter', 'downloadcounter', 'title', 'ownerusername', 'authorname', 'authoremail', 'authorcompany', 'lastuploaddate', 't3xfilemd5', 'repository', 'state', 'reviewstate', 'category', 'description', 'dependencies', 'uploadcomment' /*, 'lastversion', 'lastreviewedversion'*/);
+
+	/**
+	 * Keeps indexes of fields that should not be quoted.
+	 *
+	 * @var  array
+	 */
+	static protected $fieldIndicesNoQuote = array(2, 3, 4, 10, 12, 13, 14, 15);
+
+
+	/**
+	 * Keeps repository UID.
+	 *
+	 * The UID is necessary for inserting records.
+	 *
+	 * @var  integer
+	 */
+	protected $repositoryUID = 1;
+
+
+	/**
+	 * Class constructor.
+	 *
+	 * Method retrieves and initializes extension XML parser instance.
+	 *
+	 * @access  public
+	 * @return  void
+	 * @throws  em_xml_Exception in case no valid parser instance is available
+	 */
+	function __construct() {
+		// TODO catch parser exception
+		//$this->parser = em_xml_parser_factory::getParserInstance('extension');
+		if (!is_object(tx_em_XmlParserFactory::getParserInstance('extension'))) {
+			throw new tx_em_XmlException(get_class($this) . ': ' . 'No XML parser available.');
+		}
+	}
+
+	/**
+	 *
+	 * @return em_extensionxml_abstract_parser
+	 */
+	protected function getParser() {
+		$parser = tx_em_XmlParserFactory::getParserInstance('extension');
+		$parser->attach($this);
+		return $parser;
+	}
+
+	/**
+	 * Method initializes parsing of extension.xml.gz file.
+	 *
+	 * @access  public
+	 * @param   string   $localExtListFile  absolute path to (gzipped) local extension list xml file
+	 * @param   integer  $repositoryUID	 UID of repository to be used when inserting records into DB
+	 * @return  integer  total number of imported extension versions
+	 */
+	public function import($localExtListFile, $repositoryUID = NULL) {
+		if (!is_null($repositoryUID) && is_int($repositoryUID)) {
+			$this->repositoryUID = $repositoryUID;
+		}
+		$zlibStream = 'compress.zlib://';
+		$this->sumRecords = 0;
+
+		$this->getParser()->parseXML($zlibStream . $localExtListFile);
+
+		// flush last rows to database if existing
+		if (count($this->arrRows)) {
+			$GLOBALS['TYPO3_DB']->exec_INSERTmultipleRows(
+				'cache_extensions',
+				self::$fieldNames,
+				$this->arrRows,
+				self::$fieldIndicesNoQuote
+			);
+		}
+		return $this->sumRecords;
+	}
+
+	/**
+	 * Method collects and stores extension version details into the database.
+	 *
+	 * @access  protected
+	 * @param   SplSubject  $subject  a subject notifying this observer
+	 * @return  void
+	 */
+	protected function loadIntoDB(SplSubject &$subject) {
+		// flush every 50 rows to database
+		if ($this->sumRecords !== 0 && $this->sumRecords % 50 === 0) {
+			$GLOBALS['TYPO3_DB']->exec_INSERTmultipleRows(
+				'cache_extensions',
+				self::$fieldNames,
+				$this->arrRows,
+				self::$fieldIndicesNoQuote
+			);
+			$this->arrRows = array();
+		}
+		// order must match that of self::$fieldNamses!
+		$this->arrRows[] = array(
+			$subject->getExtkey(),
+			$subject->getVersion(),
+			tx_em_Tools::makeVersion($subject->getVersion(), 'int'),
+			intval($subject->getAlldownloadcounter()),
+			intval($subject->getDownloadcounter()),
+			!is_null($subject->getTitle()) ? $subject->getTitle() : '',
+			$subject->getOwnerusername(),
+			!is_null($subject->getAuthorname()) ? $subject->getAuthorname() : '',
+			!is_null($subject->getAuthoremail()) ? $subject->getAuthoremail() : '',
+			!is_null($subject->getAuthorcompany()) ? $subject->getAuthorcompany() : '',
+			intval($subject->getLastuploaddate()),
+			$subject->getT3xfilemd5(),
+			$this->repositoryUID,
+			tx_em_Tools::getDefaultState($subject->getState() ? $subject->getState() : ''),
+			intval($subject->getReviewstate()),
+			tx_em_Tools::getDefaultCategory($subject->getCategory() ? $subject->getCategory() : ''),
+			$subject->getDescription() ? $subject->getDescription() : '',
+			$subject->getDependencies() ? $subject->getDependencies() : '',
+			$subject->getUploadcomment() ? $subject->getUploadcomment() : '',
+		);
+		++$this->sumRecords;
+	}
+
+	/**
+	 * Method receives an update from a subject.
+	 *
+	 * @access  public
+	 * @param   SplSubject  $subject  a subject notifying this observer
+	 * @return  void
+	 */
+	public function update(SplSubject $subject) {
+		if (is_subclass_of($subject, 'tx_em_ExtensionXmlAbstractParser')) {
+			$this->loadIntoDB($subject);
+		}
+	}
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/exception/class.tx_em_xml_exception.php
===================================================================
--- typo3/sysext/em/classes/exception/class.tx_em_xml_exception.php	(revision )
+++ typo3/sysext/em/classes/exception/class.tx_em_xml_exception.php	(revision )
@@ -0,0 +1,44 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
+*           Steffen Kamper <info@sk-typo3.de>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+/**
+ * Module: Extension manager - XML exception
+ *
+ * $Id: class.tx_em_xml_exception.php 1870 2010-02-18 12:55:17Z mkrause $
+ */
+
+/**
+ * Exception for XML handling.
+ *
+ * @author      Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author      Steffen Kamper <info@sk-typo3.de>
+ *
+ * @since       2010-02-18
+ * @package     TYPO3
+ * @subpackage  EM
+ */
+class tx_em_XmlException extends Exception {
+
+}
+?>
\ No newline at end of file
Index: typo3/sysext/em/ext_autoload.php
===================================================================
--- typo3/sysext/em/ext_autoload.php	(revision 9241)
+++ typo3/sysext/em/ext_autoload.php	(revision )
@@ -2,9 +2,55 @@
 $emClassesPath = PATH_site . 'typo3/sysext/em/classes/';
 $emInterfacesPath = PATH_site . 'typo3/sysext/em/interfaces/';
 return array(
-	'sc_mod_tools_em_index' => $emClassesPath . '../mod1/class.em_index.php',
-	'em_connection_exception' => $emClassesPath . 'exception/class.em_connection_exception.php',
-	'em_tasks_updateextensionlist' => $emClassesPath . 'tasks/class.em_tasks_updateextensionlist.php',
-	'em_index_checkdatabaseupdateshook' => $emInterfacesPath . 'interface.em_index_checkdatabaseupdateshook.php',
+	'tx_em_index_checkdatabaseupdateshook' => $emInterfacesPath . 'interface.tx_em_index_checkdatabaseupdateshook.php',
+
+	'sc_mod_tools_em_index' => $emClassesPath . '../classes/index.php',
+
+	'tx_em_connection_ter' => $emClassesPath . 'connection/class.tx_em_connection_ter.php',
+	'tx_em_connection_soap' => $emClassesPath . 'connection/class.tx_em_connection_soap.php',
+	'tx_em_connection_extdirectserver' => $emClassesPath . 'connection/class.tx_em_connection_extdirectserver.php',
+
+	'tx_em_database' => $emClassesPath . 'database/class.tx_em_database.php',
+
+	'tx_em_xml_exception' => $emClassesPath . 'exception/class.tx_em_xml_exception.php',
+	'tx_em_connection_exception' => $emClassesPath . 'exception/class.tx_em_connection_exception.php',
+	'tx_em_extensionxml_exception' => $emClassesPath . 'exception/class.tx_em_extensionxml_exception.php',
+	'tx_em_extensionimport_exception' => $emClassesPath . 'exception/class.tx_em_extensionimport_exception.php',
+	'tx_em_mirrorxml_exception' => $emClassesPath . 'exception/class.tx_em_mirrorxml_exception.php',
+
+	'tx_em_extensions_list' => $emClassesPath . 'extensions/class.tx_em_extensions_list.php',
+	'tx_em_extensions_details' => $emClassesPath . 'extensions/class.tx_em_extensions_details.php',
+
+	'tx_em_import_extensionlistimporter' => $emClassesPath . 'import/class.tx_em_import_extensionlistimporter.php',
+	'tx_em_import_mirrorlistimporter' => $emClassesPath . 'import/class.tx_em_import_mirrorlistimporter.php',
+
+	'tx_em_install' => $emClassesPath . 'install/class.tx_em_install.php',
+
+	'tx_em_parser_xmlabstractparser' => $emClassesPath . 'parser/class.tx_em_parser_xmlabstractparser.php',
+	'tx_em_parser_extensionxmlabstractparser' => $emClassesPath . 'parser/class.tx_em_parser_extensionxmlabstractparser.php',
+	'tx_em_parser_mirrorxmlabstractparser' => $emClassesPath . 'parser/class.tx_em_parser_mirrorxmlabstractparser.php',
+	'tx_em_parser_xmlparserfactory' => $emClassesPath . 'parser/class.tx_em_parser_xmlparserfactory.php',
+	'tx_em_parser_mirrorxmlpullparser' => $emClassesPath . 'parser/class.tx_em_parser_mirrorxmlpullparser.php',
+	'tx_em_parser_extensionxmlpullparser' => $emClassesPath . 'parser/class.tx_em_parser_extensionxmlpullparser.php',
+	'tx_em_parser_extensionxmlpushparser' => $emClassesPath . 'parser/class.tx_em_parser_extensionxmlpushparser.php',
+
+	'tx_em_repository' => $emClassesPath . 'repository/class.tx_em_repository.php',
+	'tx_em_repository_mirrors' => $emClassesPath . 'repository/class.tx_em_repository_mirrors.php',
+	'tx_em_repository_utility' => $emClassesPath . 'repository/class.tx_em_repository_utility.php',
+
+	'tx_em_settings' => $emClassesPath . 'settings/class.tx_em_settings.php',
+
+	'tx_em_tasks_updateextensionlist' => $emClassesPath . 'tasks/class.tx_em_tasks_updateextensionlist.php',
+
+	'tx_em_tools' => $emClassesPath . 'tools/class.tx_em_tools.php',
+	'tx_em_tools_unzip' => $emClassesPath . 'tools/class.tx_em_tools_unzip.php',
+	'tx_em_tools_xmlhandler' => $emClassesPath . 'tools/class.tx_em_tools_xmlhandler.php',
+
+	'tx_em_translations' => $emClassesPath . 'translations/class.tx_em_translations.php',
+
+
+	'tx_em_develop' => $emClassesPath . 'class.tx_em_develop.php',
+	'tx_em_extensionmanager' => $emClassesPath . 'class.tx_em_extensionmanager.php',
+
 );
 ?>
\ No newline at end of file
Index: typo3/sysext/em/classes/translations/class.tx_em_translations.php
===================================================================
--- typo3/sysext/em/classes/translations/class.tx_em_translations.php	(revision )
+++ typo3/sysext/em/classes/translations/class.tx_em_translations.php	(revision )
@@ -0,0 +1,397 @@
+<?php
+/* **************************************************************
+*  Copyright notice
+*
+*  (c) webservices.nl
+*  (c) 2006-2010 Karsten Dambekalns <karsten@typo3.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+/* $Id: class.tx_em_translations.php 2018 2010-03-14 12:25:58Z steffenk $ */
+
+/**
+ * Enter description here...
+ *
+ */
+class tx_em_Translations {
+
+
+	protected $parentObject;
+	protected $terConnection;
+
+
+	/**
+	 *
+	 * @param unknown_type $parentObject
+	 */
+	public function __construct($parentObject) {
+		$this->parentObject = $parentObject;
+		$this->terConnection = t3lib_div::makeInstance('tx_em_Connection_Ter', $this);
+		$this->terConnection->wsdlURL = $GLOBALS['TYPO3_CONF_VARS']['EXT']['em_wsdlURL'];
+	}
+
+
+	/**
+	 * Install translations for all selected languages for an extension
+	 *
+	 * @param string $extKey		The extension key to install the translations for
+	 * @param string $mirrorURL		Mirror URL to fetch data from
+	 * @return mixed	true on success, error string on fauilure
+	 */
+	function installTranslationsForExtension($extKey, $mirrorURL) {
+		$selectedLanguages = unserialize($this->parentObject->MOD_SETTINGS['selectedLanguages']);
+		if (!is_array($selectedLanguages)) {
+			$selectedLanguages = array();
+		}
+		foreach ($selectedLanguages as $lang) {
+			$l10n = $this->parentObject->terConnection->fetchTranslation($extKey, $lang, $mirrorURL);
+			if (is_array($l10n)) {
+				$file = PATH_typo3conf . 'l10n/' . $extKey . '-l10n-' . $lang . '.zip';
+				$path = 'l10n/' . $lang . '/' . $extKey;
+				t3lib_div::writeFile($file, $l10n[0]);
+				if (!is_dir(PATH_typo3conf . $path)) {
+					t3lib_div::mkdir_deep(PATH_typo3conf, $path);
+				}
+				if (tx_em_Tools::unzip($file, PATH_typo3conf . $path)) {
+					return true;
+				} else {
+					return $GLOBALS['LANG']->getLL('translation_unpacking_failed');
+				}
+			} else {
+				return $l10n;
+			}
+		}
+	}
+
+	/**
+	 * Install translations for all selected languages for an extension
+	 *
+	 * @param string $extKey		The extension key to install the translations for
+	 * @param string $lang		Language code of translation to fetch
+	 * @param string $mirrorURL		Mirror URL to fetch data from
+	 * @return mixed	true on success, error string on fauilure
+	 */
+	function updateTranslation($extKey, $lang, $mirrorURL) {
+		$l10n = $this->parentObject->terConnection->fetchTranslation($extKey, $lang, $mirrorURL);
+		if (is_array($l10n)) {
+			$file = PATH_site . 'typo3temp/' . $extKey . '-l10n-' . $lang . '.zip';
+			$path = 'l10n/' . $lang . '/';
+			if (!is_dir(PATH_typo3conf . $path)) {
+				t3lib_div::mkdir_deep(PATH_typo3conf, $path);
+			}
+			t3lib_div::writeFile($file, $l10n[0]);
+			if (tx_em_Tools::unzip($file, PATH_typo3conf . $path)) {
+				return true;
+			} else {
+				return $GLOBALS['LANG']->getLL('translation_unpacking_failed');
+			}
+		} else {
+			return $l10n;
+		}
+	}
+
+	/**
+	 * @return void
+	 */
+	public function translationHandling() {
+		global $LANG, $TYPO3_LOADED_EXT;
+		$LANG->includeLLFile('EXT:setup/mod/locallang.xml');
+
+		//prepare docheader
+		$docHeaderButtons = $this->parentObject->getButtons();
+		$markers = array(
+			'CSH' => $docHeaderButtons['csh'],
+			'FUNC_MENU' => $this->parentObject->getFuncMenu(),
+		);
+
+
+		$incoming = t3lib_div::_POST('SET');
+		if (isset($incoming['selectedLanguages']) && is_array($incoming['selectedLanguages'])) {
+			t3lib_BEfunc::getModuleData($this->parentObject->MOD_MENU, array('selectedLanguages' => serialize($incoming['selectedLanguages'])), $this->parentObject->MCONF['name'], '', 'selectedLanguages');
+			$this->parentObject->MOD_SETTINGS['selectedLanguages'] = serialize($incoming['selectedLanguages']);
+		}
+
+		$selectedLanguages = unserialize($this->parentObject->MOD_SETTINGS['selectedLanguages']);
+		if (count($selectedLanguages) == 1 && empty($selectedLanguages[0])) {
+			$selectedLanguages = array();
+		}
+		$theLanguages = t3lib_div::trimExplode('|', TYPO3_languages);
+		foreach ($theLanguages as $val) {
+			if ($val != 'default') {
+				$localLabel = '  -  [' . htmlspecialchars($GLOBALS['LOCAL_LANG']['default']['lang_' . $val]) . ']';
+				$selected = (is_array($selectedLanguages) && in_array($val, $selectedLanguages)) ? ' selected="selected"' : '';
+				$opt[$GLOBALS['LANG']->getLL('lang_' . $val, 1) . '--' . $val] = '
+			 <option value="' . $val . '"' . $selected . '>' . $LANG->getLL('lang_' . $val, 1) . $localLabel . '</option>';
+			}
+		}
+		ksort($opt);
+
+		$headline = $GLOBALS['LANG']->getLL('translation_settings');
+		$headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'translation', $headline);
+
+		// Prepare the HTML output:
+		$content .= '
+			<form action="' . $this->parentObject->script . '" method="post" name="translationform">
+			<fieldset><legend>' . $GLOBALS['LANG']->getLL('translation_settings') . '</legend>
+			<table border="0" cellpadding="2" cellspacing="2">
+				<tr class="bgColor4">
+					<td>' . $GLOBALS['LANG']->getLL('languages_to_fetch') . '</td>
+					<td>
+					  <select name="SET[selectedLanguages][]" multiple="multiple" size="10">
+					  <option>&nbsp;</option>' .
+				implode('', $opt) . '
+			</select>
+		  </td>
+				</tr>
+			</table>
+			<br />
+			<p>' . $GLOBALS['LANG']->getLL('translation_info') . '<br />
+			<br />' . $GLOBALS['LANG']->getLL('translation_loaded_exts') . '</p>
+			</fieldset>
+			<br />
+			<input type="submit" value="' . $GLOBALS['LANG']->getLL('translation_save_selection') . '" />
+			<br />
+			</form>';
+
+		$this->parentObject->content .= $this->parentObject->doc->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
+
+		if (count($selectedLanguages) > 0) {
+			$mirrorURL = $this->parentObject->getMirrorURL();
+			$content = '<input type="button" value="' . $GLOBALS['LANG']->getLL('translation_check_status_button') .
+					'" onclick="document.location.href=\'' . htmlspecialchars(t3lib_div::linkThisScript(array('l10n' => 'check'))) .
+					'\'" />&nbsp;<input type="button" value="' . $GLOBALS['LANG']->getLL('translation_update_button') .
+					'" onclick="document.location.href=\'' . htmlspecialchars(t3lib_div::linkThisScript(array('l10n' => 'update'))) .
+					'\'" />';
+
+			// as this page loads dynamically, quit output buffering caused by ob_gzhandler
+			t3lib_div::cleanOutputBuffers();
+
+			if (t3lib_div::_GET('l10n') == 'check') {
+				$loadedExtensions = array_keys($TYPO3_LOADED_EXT);
+				$loadedExtensions = array_diff($loadedExtensions, array('_CACHEFILE'));
+
+				// Override content output - we now do that ourselves:
+				$this->parentObject->content .= $this->parentObject->doc->section($GLOBALS['LANG']->getLL('translation_status'), $content, 0, 1);
+				// Setting up the buttons and markers for docheader
+				$content = $this->parentObject->doc->startPage('Extension Manager');
+				$content .= $this->parentObject->doc->moduleBody($this->parentObject->pageinfo, $docHeaderButtons, $markers);
+				$contentParts = explode('###CONTENT###', $content);
+
+				echo $contentParts[0] . $this->parentObject->content;
+
+				$this->parentObject->doPrintContent = FALSE;
+				flush();
+
+				echo '
+				<br />
+				<br />
+				<p id="progress-message">
+					' . $GLOBALS['LANG']->getLL('translation_check_status') . '
+				</p>
+				<br />
+				<div style="width:100%; height:20px; border: 1px solid black;">
+					<div id="progress-bar" style="float: left; width: 0%; height: 20px; background-color:green;">&nbsp;</div>
+					<div id="transparent-bar" style="float: left; width: 100%; height: 20px; background-color:' . $this->parentObject->doc->bgColor2 . ';">&nbsp;</div>
+				</div>
+				<br />
+				<br /><p>' . $GLOBALS['LANG']->getLL('translation_table_check') . '</p><br />
+				<table border="0" cellpadding="2" cellspacing="2">
+					<tr class="t3-row-header"><td>' . $GLOBALS['LANG']->getLL('translation_extension_key') . '</td>
+				';
+
+				foreach ($selectedLanguages as $lang) {
+					echo ('<td>' . $LANG->getLL('lang_' . $lang, 1) . '</td>');
+				}
+				echo ('</tr>');
+
+				$counter = 1;
+				foreach ($loadedExtensions as $extKey) {
+
+					$percentDone = intval(($counter / count($loadedExtensions)) * 100);
+					echo ('
+					<script type="text/javascript">
+						document.getElementById("progress-bar").style.width = "' . $percentDone . '%";
+						document.getElementById("transparent-bar").style.width = "' . (100 - $percentDone) . '%";
+						document.getElementById("progress-message").firstChild.data="' .
+							sprintf($GLOBALS['LANG']->getLL('translation_checking_extension'), $extKey) . '";
+					</script>
+					');
+
+					flush();
+					$translationStatusArr = $this->parentObject->terConnection->fetchTranslationStatus($extKey, $mirrorURL);
+
+					echo ('<tr class="bgColor4"><td>' . $extKey . '</td>');
+					foreach ($selectedLanguages as $lang) {
+						// remote unknown -> no l10n available
+						if (!isset($translationStatusArr[$lang])) {
+							echo ('<td title="' . $GLOBALS['LANG']->getLL('translation_no_translation') . '">' .
+									$GLOBALS['LANG']->getLL('translation_n_a') . '</td>');
+							continue;
+						}
+						// determine local md5 from zip
+						if (is_file(PATH_site . 'typo3temp/' . $extKey . '-l10n-' . $lang . '.zip')) {
+							$localmd5 = md5_file(PATH_site . 'typo3temp/' . $extKey . '-l10n-' . $lang . '.zip');
+						} else {
+							echo ('<td title="' . $GLOBALS['LANG']->getLL('translation_not_installed') .
+									'" style="background-color:#ff0">' . $GLOBALS['LANG']->getLL('translation_status_unknown') .
+									'</td>');
+							continue;
+						}
+						// local!=remote -> needs update
+						if ($localmd5 != $translationStatusArr[$lang]['md5']) {
+							echo ('<td title="' . $GLOBALS['LANG']->getLL('translation_needs_update') .
+									'" style="background-color:#ff0">' . $GLOBALS['LANG']->getLL('translation_status_update') .
+									'</td>');
+							continue;
+						}
+						echo ('<td title="' . $GLOBALS['LANG']->getLL('translation_is_ok') .
+								'" style="background-color:#69a550">' . $GLOBALS['LANG']->getLL('translation_status_ok') .
+								'</td>');
+					}
+					echo ('</tr>');
+
+					$counter++;
+				}
+				echo '</table>
+					<script type="text/javascript">
+						document.getElementById("progress-message").firstChild.data="' .
+						$GLOBALS['LANG']->getLL('translation_check_done') . '";
+					</script>
+				';
+				echo $contentParts[1] . $this->parentObject->doc->endPage();
+				exit;
+
+			} elseif (t3lib_div::_GET('l10n') == 'update') {
+				$loadedExtensions = array_keys($TYPO3_LOADED_EXT);
+				$loadedExtensions = array_diff($loadedExtensions, array('_CACHEFILE'));
+
+				// Override content output - we now do that ourselves:
+				$this->parentObject->content .= $this->parentObject->doc->section($GLOBALS['LANG']->getLL('translation_status'), $content, 0, 1);
+				// Setting up the buttons and markers for docheader
+				$content = $this->parentObject->doc->startPage('Extension Manager');
+				$content .= $this->parentObject->doc->moduleBody($this->parentObject->pageinfo, $docHeaderButtons, $markers);
+				$contentParts = explode('###CONTENT###', $content);
+
+				echo $contentParts[0] . $this->parentObject->content;
+
+				$this->parentObject->doPrintContent = FALSE;
+				flush();
+
+				echo ('
+				<br />
+				<br />
+				<p id="progress-message">
+					' . $GLOBALS['LANG']->getLL('translation_update_status') . '
+				</p>
+				<br />
+				<div style="width:100%; height:20px; border: 1px solid black;">
+					<div id="progress-bar" style="float: left; width: 0%; height: 20px; background-color:green;">&nbsp;</div>
+					<div id="transparent-bar" style="float: left; width: 100%; height: 20px; background-color:' . $this->parentObject->doc->bgColor2 . ';">&nbsp;</div>
+				</div>
+				<br />
+				<br /><p>' . $GLOBALS['LANG']->getLL('translation_table_update') . '<br />
+				<em>' . $GLOBALS['LANG']->getLL('translation_full_check_update') . '</em></p><br />
+				<table border="0" cellpadding="2" cellspacing="2">
+					<tr class="t3-row-header"><td>' . $GLOBALS['LANG']->getLL('translation_extension_key') . '</td>
+				');
+
+				foreach ($selectedLanguages as $lang) {
+					echo '<td>' . $LANG->getLL('lang_' . $lang, 1) . '</td>';
+				}
+				echo '</tr>';
+
+				$counter = 1;
+				foreach ($loadedExtensions as $extKey) {
+					$percentDone = intval(($counter / count($loadedExtensions)) * 100);
+					echo ('
+					<script type="text/javascript">
+						document.getElementById("progress-bar").style.width = "' . $percentDone . '%";
+						document.getElementById("transparent-bar").style.width = "' . (100 - $percentDone) . '%";
+						document.getElementById("progress-message").firstChild.data="' .
+							sprintf($GLOBALS['LANG']->getLL('translation_updating_extension'), $extKey) . '";
+					</script>
+					');
+
+					flush();
+					$translationStatusArr = $this->parentObject->terConnection->fetchTranslationStatus($extKey, $mirrorURL);
+
+					echo ('<tr class="bgColor4"><td>' . $extKey . '</td>');
+					if (is_array($translationStatusArr)) {
+						foreach ($selectedLanguages as $lang) {
+							// remote unknown -> no l10n available
+							if (!isset($translationStatusArr[$lang])) {
+								echo ('<td title="' . $GLOBALS['LANG']->getLL('translation_no_translation') .
+										'">' . $GLOBALS['LANG']->getLL('translation_n_a') . '</td>');
+								continue;
+							}
+							// determine local md5 from zip
+							if (is_file(PATH_site . 'typo3temp/' . $extKey . '-l10n-' . $lang . '.zip')) {
+								$localmd5 = md5_file(PATH_site . 'typo3temp/' . $extKey . '-l10n-' . $lang . '.zip');
+							} else {
+								$localmd5 = 'zzz';
+							}
+							// local!=remote or not installed -> needs update
+							if ($localmd5 != $translationStatusArr[$lang]['md5']) {
+								$ret = $this->updateTranslation($extKey, $lang, $mirrorURL);
+								if ($ret === true) {
+									echo ('<td title="' . $GLOBALS['LANG']->getLL('translation_has_been_updated') .
+											'" style="background-color:#69a550">' . $GLOBALS['LANG']->getLL('translation_status_update') .
+											'</td>');
+								} else {
+									echo ('<td title="' . htmlspecialchars($ret) .
+											'" style="background-color:#cb3352">' . $GLOBALS['LANG']->getLL('translation_status_error') .
+											'</td>');
+								}
+								continue;
+							}
+							echo ('<td title="' . $GLOBALS['LANG']->getLL('translation_is_ok') .
+									'" style="background-color:#69a550">' . $GLOBALS['LANG']->getLL('translation_status_ok') . '</td>');
+						}
+					} else {
+						echo ('<td colspan="' . count($selectedLanguages) .
+								'" title="' . $GLOBALS['LANG']->getLL('translation_problems') .
+								'">' . $GLOBALS['LANG']->getLL('translation_status_could_not_fetch') . '</td>');
+					}
+					echo ('</tr>');
+					$counter++;
+				}
+				echo '</table>
+					<script type="text/javascript">
+						document.getElementById("progress-message").firstChild.data="' .
+						$GLOBALS['LANG']->getLL('translation_update_done') . '";
+					</script>
+				';
+
+				// Fix permissions on unzipped language xml files in the entire l10n folder and all subfolders
+				t3lib_div::fixPermissions(PATH_typo3conf . 'l10n', TRUE);
+
+				echo $contentParts[1] . $this->parentObject->doc->endPage();
+				exit;
+			}
+
+			$this->parentObject->content .= $this->parentObject->doc->section($GLOBALS['LANG']->getLL('translation_status'), $content, 0, 1);
+		}
+	}
+
+
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/import/class.tx_em_import_mirrorlistimporter.php
===================================================================
--- typo3/sysext/em/classes/import/class.tx_em_import_mirrorlistimporter.php	(revision )
+++ typo3/sysext/em/classes/import/class.tx_em_import_mirrorlistimporter.php	(revision )
@@ -0,0 +1,116 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
+ *		   Steffen Kamper <info@sk-typo3.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * class.tx_em_import_mirrorlistimporter.php
+ *
+ * Module: Extension manager - Mirror list importer
+ *
+ * $Id: class.tx_em_import_mirrorlistimporter.php 1982 2010-03-09 06:29:55Z mkrause $
+ *
+ * @author  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author  Steffen Kamper <info@sk-typo3.de>
+ */
+
+
+/**
+ * Importer object for mirror list.
+ *
+ * @author	  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author	  Steffen Kamper <info@sk-typo3.de>
+ *
+ * @since	   2010-02-10
+ * @package	 TYPO3
+ * @subpackage  EM
+ */
+class tx_em_Import_MirrorListImporter implements SplObserver {
+
+	/**
+	 * Keeps instance of a XML parser.
+	 *
+	 * @var  em_xml_abstract_parser
+	 */
+	protected $parser;
+
+	/**
+	 * Keeps mirrors' details.
+	 *
+	 * @var  array
+	 */
+	protected $arrTmpMirrors = array();
+
+
+	/**
+	 * Class constructor.
+	 *
+	 * Method retrieves and initializes extension XML parser instance.
+	 *
+	 * @access  public
+	 * @return  void
+	 * @throws  em_xml_Exception in case no valid parser instance is available
+	 */
+	function __construct() {
+		// TODO catch parser exception
+		$this->parser = tx_em_Parser_XmlParserFactory::getParserInstance('mirror');
+		if (is_object($this->parser)) {
+			$this->parser->attach($this);
+		} else {
+			throw new tx_em_XmlException(get_class($this) . ': ' . 'No XML parser available.');
+		}
+	}
+
+	/**
+	 * Method collects mirrors' details and returns instance of em_repository_mirrors
+	 * with retrieved details.
+	 *
+	 * @access  public
+	 * @param   string  $localMirrorListFile  bsolute path to (gzipped) local mirror list xml file
+	 * @return  em_repository_mirrors
+	 */
+	public function getMirrors($localMirrorListFile) {
+		$zlibStream = 'compress.zlib://';
+
+		$this->parser->parseXML($zlibStream . $localMirrorListFile);
+		$objRepositoryMirrors = t3lib_div::makeInstance('tx_em_Repository_Mirrors');
+		$objRepositoryMirrors->setMirrors($this->arrTmpMirrors);
+		$this->arrTmpMirrors = array();
+		return $objRepositoryMirrors;
+	}
+
+	/**
+	 * Method receives an update from a subject.
+	 *
+	 * @access  public
+	 * @param   SplSubject  $subject  a subject notifying this observer
+	 * @return  void
+	 */
+	public function update(SplSubject $subject) {
+		// TODO mirrorxml_abstract_parser
+		if (is_subclass_of($subject, 'tx_em_Parser_XmlAbstractParser')) {
+			$this->arrTmpMirrors[] = $subject->getAll();
+		}
+	}
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/parser/class.tx_em_parser_xmlparserfactory.php
===================================================================
--- typo3/sysext/em/classes/parser/class.tx_em_parser_xmlparserfactory.php	(revision )
+++ typo3/sysext/em/classes/parser/class.tx_em_parser_xmlparserfactory.php	(revision )
@@ -0,0 +1,107 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
+ *		   Steffen Kamper <info@sk-typo3.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * class.tx_em_parser_xmlparserfactory.php
+ *
+ * Module: Extension manager - XML parser factory
+ *
+ * $Id: class.tx_em_parser_xmlparserfactory.php 1911 2010-02-21 14:50:40Z mkrause $
+ *
+ * @author  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author  Steffen Kamper <info@sk-typo3.de>
+ */
+
+/**
+ * Factory for XML parsers.
+ *
+ * @author	  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author	  Steffen Kamper <info@sk-typo3.de>
+ *
+ * @since	   2010-02-10
+ * @package	 TYPO3
+ * @subpackage  EM
+ */
+class tx_em_Parser_XmlParserFactory {
+
+	/**
+	 * An array with instances of xml parsers.
+	 * This member is set in the getParserInstance() function.
+	 *
+	 * @var	array
+	 */
+	static protected $instance = array();
+
+	/**
+	 * Keeps array of all available parsers.
+	 *
+	 * TODO: This would better be moved to
+	 * a global configuration array like
+	 * $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'].
+	 * (might require EM to be moved in a sysext)
+	 *
+	 * @var array
+	 */
+	static protected $parsers = array('extension' => array(
+		'tx_em_parser_extensionxmlpullparser' => 'class.tx_em_parser_extensionxmlpullparser.php',
+		'tx_em_parser_extensionxmlpushparser' => 'class.tx_em_parser_extensionxmlpushparser.php',),
+		'mirror' => array(
+			'tx_em_parser_mirrorxmlpullparser' => 'class.tx_em_parser_mirrorxmlpullparser.php',
+			'tx_em_parser_mirrorxmlpushparser' => 'class.tx_em_parser_mirrorxmlpushparser.php',));
+
+
+	/**
+	 * Obtains a xml parser instance.
+	 *
+	 * This function will return an instance of a class that implements
+	 * em_extensionxml_abstract_parser.
+	 *
+	 * TODO use autoload if possible (might require EM to be moved in a sysext)
+	 *
+	 * @access  public
+	 * @param   string	  $parserType: type of parser, one of extension and mirror
+	 * @param	string		$excludeClassNames: (optional) comma-separated list of class names
+	 * @return	em_extensionxml_abstract_parser	an instance of an extension.xml parser
+	 */
+	static public function getParserInstance($parserType, $excludeClassNames = '') {
+		if (!isset(self::$instance[$parserType]) || !is_object(self::$instance[$parserType]) || !empty($excludeClassNames)) {
+			// reset instance
+			self::$instance[$parserType] = $objParser = NULL;
+			foreach (self::$parsers[$parserType] as $className => $file) {
+				if (!t3lib_div::inList($excludeClassNames, $className)) {
+					//require_once(dirname(__FILE__) . '/' . $file);
+					$objParser = t3lib_div::makeInstance($className);
+					if ($objParser->isAvailable()) {
+						self::$instance[$parserType] = &$objParser;
+						break;
+					}
+					$objParser = NULL;
+				}
+			}
+		}
+		return self::$instance[$parserType];
+	}
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/ext_tables.php
===================================================================
--- typo3/sysext/em/ext_tables.php	(revision 8231)
+++ typo3/sysext/em/ext_tables.php	(revision )
@@ -4,6 +4,9 @@
 }
 
 if (TYPO3_MODE === 'BE') {
-	t3lib_extMgm::addModule('tools', 'em', 'after:layout', t3lib_extMgm::extPath($_EXTKEY) . 'mod1/');
+	t3lib_extMgm::addModule('tools', 'em', 'after:layout', t3lib_extMgm::extPath($_EXTKEY) . 'classes/');
+		// register Ext.Direct
+	$TYPO3_CONF_VARS['SC_OPTIONS']['ExtDirect']['TYPO3.EM.ExtDirect'] = t3lib_extMgm::extPath($_EXTKEY) . 'classes/connection/class.tx_em_connection_extdirectserver.php:tx_em_Connection_ExtDirectServer';
+
 }
 ?>
\ No newline at end of file
Index: typo3/sysext/em/classes/tools/class.tx_em_tools.php
===================================================================
--- typo3/sysext/em/classes/tools/class.tx_em_tools.php	(revision )
+++ typo3/sysext/em/classes/tools/class.tx_em_tools.php	(revision )
@@ -0,0 +1,937 @@
+<?php
+/* **************************************************************
+*  Copyright notice
+*
+*  (c) webservices.nl
+*  (c) 2006-2010 Karsten Dambekalns <karsten@typo3.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+/**
+ * class.tx_em_tools.php
+ *
+ * $Id: class.tx_em_tools.php 2084 2010-03-22 01:46:37Z steffenk $
+ */
+
+/**
+ * Enter description here...
+ *
+ */
+final class tx_em_Tools {
+
+	/**
+	 * Keeps default categories.
+	 *
+	 * @var  array
+	 */
+	static protected $defaultCategories = array('be' => 0,
+		'module' => 1,
+		'fe' => 2,
+		'plugin' => 3,
+		'misc' => 4,
+		'services' => 5,
+		'templates' => 6,
+		'example' => 9,
+		'doc' => 8,
+	);
+	/**
+	 * Keeps default states.
+	 *
+	 * @var  array
+	 */
+	static protected $defaultStates = array('alpha' => 0,
+		'beta' => 1,
+		'stable' => 2,
+		'experimental' => 3,
+		'test' => 4,
+		'obsolete' => 5,
+		'excludeFromUpdates' => 6,
+		'n/a' => 999,
+	);
+
+	/**
+	 * Unzips a zip file in the given path.
+	 *
+	 * Uses unzip binary if available, otherwise a pure PHP unzip is used.
+	 *
+	 * @param string $file		Full path to zip file
+	 * @param string $path		Path to change to before extracting
+	 * @return boolean	True on success, false in failure
+	 */
+	public function unzip($file, $path) {
+		if (strlen($GLOBALS['TYPO3_CONF_VARS']['BE']['unzip_path'])) {
+			chdir($path);
+			$cmd = $GLOBALS['TYPO3_CONF_VARS']['BE']['unzip_path'] . ' -o ' . escapeshellarg($file);
+			exec($cmd, $list, $ret);
+			return ($ret === 0);
+		} else {
+			// we use a pure PHP unzip
+			$unzip = t3lib_div::makeInstance('tx_em_Tools_Unzip', $file);
+			$ret = $unzip->extract(array('add_path' => $path));
+			return (is_array($ret));
+		}
+	}
+
+
+	/**
+	 * Set category array entries for extension
+	 *
+	 * @param	array		Category index array
+	 * @param	array		Part of list array for extension.
+	 * @param	string		Extension key
+	 * @return	array		Modified category index array
+	 */
+	public function setCat(&$cat, $listArrayPart, $extKey) {
+
+		// Getting extension title:
+		$extTitle = $listArrayPart['EM_CONF']['title'];
+
+		// Category index:
+		$index = $listArrayPart['EM_CONF']['category'];
+		$cat['cat'][$index][$extKey] = $extTitle;
+
+		// Author index:
+		$index = $listArrayPart['EM_CONF']['author'] . ($listArrayPart['EM_CONF']['author_company'] ? ', ' . $listArrayPart['EM_CONF']['author_company'] : '');
+		$cat['author_company'][$index][$extKey] = $extTitle;
+
+		// State index:
+		$index = $listArrayPart['EM_CONF']['state'];
+		$cat['state'][$index][$extKey] = $extTitle;
+
+		// Type index:
+		$index = $listArrayPart['type'];
+		$cat['type'][$index][$extKey] = $extTitle;
+
+		// Return categories:
+		return $cat;
+	}
+
+	/**
+	 * Returns upload folder for extension
+	 *
+	 * @param	string		Extension key
+	 * @return	string		Upload folder for extension
+	 */
+	public function uploadFolder($extKey) {
+		return 'uploads/tx_' . str_replace('_', '', $extKey) . '/';
+	}
+
+
+	/**
+	 * Returns image tag for "uninstall"
+	 *
+	 * @return	string		<img> tag
+	 */
+	public function removeButton() {
+		return t3lib_iconWorks::getSpriteIcon('actions-system-extension-uninstall', array('title' => $GLOBALS['LANG']->getLL('ext_details_remove_ext')));
+	}
+
+	/**
+	 * Returns image for "install"
+	 *
+	 * @return	string		<img> tag
+	 */
+	public function installButton() {
+		return t3lib_iconWorks::getSpriteIcon('actions-system-extension-install', array('title' => $GLOBALS['LANG']->getLL('helperFunction_install_extension')));
+	}
+
+	/**
+	 * Warning (<img> + text string) message about the impossibility to import extensions (both local and global locations are disabled...)
+	 *
+	 * @return	string		<img> + text string.
+	 */
+	public function noImportMsg() {
+		return t3lib_iconWorks::getSpriteIcon('status-dialog-warning') .
+				'<strong>' . $GLOBALS['LANG']->getLL('helperFunction_import_not_possible') . '</strong>';
+	}
+
+
+	/**
+	 * Fixes an old style ext_emconf.php array by adding constraints if needed and removing deprecated keys
+	 *
+	 * @param	array		$emConf
+	 * @return	array
+	 */
+	public function fixEMCONF($emConf) {
+		if (!isset($emConf['constraints']) || !isset($emConf['constraints']['depends']) || !isset($emConf['constraints']['conflicts']) || !isset($emConf['constraints']['suggests'])) {
+			if (!isset($emConf['constraints']) || !isset($emConf['constraints']['depends'])) {
+				$emConf['constraints']['depends'] = self::stringToDep($emConf['dependencies']);
+				if (strlen($emConf['PHP_version'])) {
+					$versionRange = self::splitVersionRange($emConf['PHP_version']);
+					if (version_compare($versionRange[0], '3.0.0', '<')) {
+						$versionRange[0] = '3.0.0';
+					}
+					if (version_compare($versionRange[1], '3.0.0', '<')) {
+						$versionRange[1] = '0.0.0';
+					}
+					$emConf['constraints']['depends']['php'] = implode('-', $versionRange);
+				}
+				if (strlen($emConf['TYPO3_version'])) {
+					$versionRange = self::splitVersionRange($emConf['TYPO3_version']);
+					if (version_compare($versionRange[0], '3.5.0', '<')) {
+						$versionRange[0] = '3.5.0';
+					}
+					if (version_compare($versionRange[1], '3.5.0', '<')) {
+						$versionRange[1] = '0.0.0';
+					}
+					$emConf['constraints']['depends']['typo3'] = implode('-', $versionRange);
+				}
+			}
+			if (!isset($emConf['constraints']) || !isset($emConf['constraints']['conflicts'])) {
+				$emConf['constraints']['conflicts'] = self::stringToDep($emConf['conflicts']);
+			}
+			if (!isset($emConf['constraints']) || !isset($emConf['constraints']['suggests'])) {
+				$emConf['constraints']['suggests'] = array();
+			}
+		} elseif (isset($emConf['constraints']) && isset($emConf['dependencies'])) {
+			$emConf['suggests'] = isset($emConf['suggests']) ? $emConf['suggests'] : array();
+			$emConf['dependencies'] = self::depToString($emConf['constraints']);
+			$emConf['conflicts'] = self::depToString($emConf['constraints'], 'conflicts');
+		}
+
+		// sanity check for version numbers, intentionally only checks php and typo3
+		if (isset($emConf['constraints']['depends']) && isset($emConf['constraints']['depends']['php'])) {
+			$versionRange = self::splitVersionRange($emConf['constraints']['depends']['php']);
+			if (version_compare($versionRange[0], '3.0.0', '<')) {
+				$versionRange[0] = '3.0.0';
+			}
+			if (version_compare($versionRange[1], '3.0.0', '<')) {
+				$versionRange[1] = '0.0.0';
+			}
+			$emConf['constraints']['depends']['php'] = implode('-', $versionRange);
+		}
+		if (isset($emConf['constraints']['depends']) && isset($emConf['constraints']['depends']['typo3'])) {
+			$versionRange = self::splitVersionRange($emConf['constraints']['depends']['typo3']);
+			if (version_compare($versionRange[0], '3.5.0', '<')) {
+				$versionRange[0] = '3.5.0';
+			}
+			if (version_compare($versionRange[1], '3.5.0', '<')) {
+				$versionRange[1] = '0.0.0';
+			}
+			$emConf['constraints']['depends']['typo3'] = implode('-', $versionRange);
+		}
+
+		unset($emConf['private']);
+		unset($emConf['download_password']);
+		unset($emConf['TYPO3_version']);
+		unset($emConf['PHP_version']);
+
+		return $emConf;
+	}
+
+
+	/**
+	 * Returns the $EM_CONF array from an extensions ext_emconf.php file
+	 *
+	 * @param	string		Absolute path to EMCONF file.
+	 * @param	string		Extension key.
+	 * @return	array		EMconf array values.
+	 */
+	public function includeEMCONF($path, $_EXTKEY) {
+		$EM_CONF = NULL;
+		@include($path);
+		if (is_array($EM_CONF[$_EXTKEY])) {
+			return self::fixEMCONF($EM_CONF[$_EXTKEY]);
+		}
+		return false;
+	}
+
+
+	/**
+	 * Extracts the directories in the $files array
+	 *
+	 * @param	array		Array of files / directories
+	 * @return	array		Array of directories from the input array.
+	 */
+	function extractDirsFromFileList($files) {
+		$dirs = array();
+
+		if (is_array($files)) {
+			// Traverse files / directories array:
+			foreach ($files as $file) {
+				if (substr($file, -1) == '/') {
+					$dirs[$file] = $file;
+				} else {
+					$pI = pathinfo($file);
+					if (strcmp($pI['dirname'], '') && strcmp($pI['dirname'], '.')) {
+						$dirs[$pI['dirname'] . '/'] = $pI['dirname'] . '/';
+					}
+				}
+			}
+		}
+		return $dirs;
+	}
+
+	/**
+	 * Splits a version range into an array.
+	 *
+	 * If a single version number is given, it is considered a minimum value.
+	 * If a dash is found, the numbers left and right are considered as minimum and maximum. Empty values are allowed.
+	 *
+	 * @param	string		$ver A string with a version range.
+	 * @return	array
+	 */
+	public function splitVersionRange($ver) {
+		$versionRange = array();
+		if (strstr($ver, '-')) {
+			$versionRange = explode('-', $ver, 2);
+		} else {
+			$versionRange[0] = $ver;
+			$versionRange[1] = '';
+		}
+
+		if (!$versionRange[0]) {
+			$versionRange[0] = '0.0.0';
+		}
+		if (!$versionRange[1]) {
+			$versionRange[1] = '0.0.0';
+		}
+
+		return $versionRange;
+	}
+
+	/**
+	 * Checks whether the passed dependency is TER2-style (array) and returns a single string for displaying the dependencies.
+	 *
+	 * It leaves out all version numbers and the "php" and "typo3" dependencies, as they are implicit and of no interest without the version number.
+	 *
+	 * @param	mixed		$dep Either a string or an array listing dependencies.
+	 * @param	string		$type The dependency type to list if $dep is an array
+	 * @return	string		A simple dependency list for display
+	 */
+	public function depToString($dep, $type = 'depends') {
+		if (is_array($dep)) {
+			unset($dep[$type]['php']);
+			unset($dep[$type]['typo3']);
+			$s = (count($dep[$type])) ? implode(',', array_keys($dep[$type])) : '';
+			return $s;
+		}
+		return '';
+	}
+
+	/**
+	 * Checks whether the passed dependency is TER-style (string) or TER2-style (array) and returns a single string for displaying the dependencies.
+	 *
+	 * It leaves out all version numbers and the "php" and "typo3" dependencies, as they are implicit and of no interest without the version number.
+	 *
+	 * @param	mixed		$dep Either a string or an array listing dependencies.
+	 * @param	string		$type The dependency type to list if $dep is an array
+	 * @return	string		A simple dependency list for display
+	 */
+	public function stringToDep($dep) {
+		$constraint = array();
+		if (is_string($dep) && strlen($dep)) {
+			$dep = explode(',', $dep);
+			foreach ($dep as $v) {
+				$constraint[$v] = '';
+			}
+		}
+		return $constraint;
+	}
+
+
+	/**
+	 * Returns version information
+	 *
+	 * @param	string		Version code, x.x.x
+	 * @param	string		part: "", "int", "main", "sub", "dev"
+	 * @return	string
+	 * @see renderVersion()
+	 */
+	public function makeVersion($v, $mode) {
+		$vDat = self::renderVersion($v);
+		return $vDat['version_' . $mode];
+	}
+
+	/**
+	 * Parses the version number x.x.x and returns an array with the various parts.
+	 *
+	 * @param	string		Version code, x.x.x
+	 * @param	string		Increase version part: "main", "sub", "dev"
+	 * @return	string
+	 */
+	public function renderVersion($v, $raise = '') {
+		$parts = t3lib_div::intExplode('.', $v . '..');
+		$parts[0] = t3lib_div::intInRange($parts[0], 0, 999);
+		$parts[1] = t3lib_div::intInRange($parts[1], 0, 999);
+		$parts[2] = t3lib_div::intInRange($parts[2], 0, 999);
+
+		switch ((string) $raise) {
+			case 'main':
+				$parts[0]++;
+				$parts[1] = 0;
+				$parts[2] = 0;
+				break;
+			case 'sub':
+				$parts[1]++;
+				$parts[2] = 0;
+				break;
+			case 'dev':
+				$parts[2]++;
+				break;
+		}
+
+		$res = array();
+		$res['version'] = $parts[0] . '.' . $parts[1] . '.' . $parts[2];
+		$res['version_int'] = intval($parts[0] * 1000000 + $parts[1] * 1000 + $parts[2]);
+		$res['version_main'] = $parts[0];
+		$res['version_sub'] = $parts[1];
+		$res['version_dev'] = $parts[2];
+
+		return $res;
+	}
+
+	/**
+	 * Evaluates differences in version numbers with three parts, x.x.x. Returns true if $v1 is greater than $v2
+	 *
+	 * @param	string		Version number 1
+	 * @param	string		Version number 2
+	 * @param	integer		Tolerance factor. For instance, set to 1000 to ignore difference in dev-version (third part)
+	 * @return	boolean		True if version 1 is greater than version 2
+	 */
+	public function versionDifference($v1, $v2, $div = 1) {
+		return floor(self::makeVersion($v1, 'int') / $div) > floor(self::makeVersion($v2, 'int') / $div);
+	}
+
+
+	/**
+	 * Returns true if the $str is found as the first part of a string in $array
+	 *
+	 * @param	string		String to test with.
+	 * @param	array		Input array
+	 * @param	boolean		If set, the test is case insensitive
+	 * @return	boolean		True if found.
+	 */
+	public function first_in_array($str, $array, $caseInsensitive = FALSE) {
+		if ($caseInsensitive) {
+			$str = strtolower($str);
+		}
+		if (is_array($array)) {
+			foreach ($array as $cl) {
+				if ($caseInsensitive) {
+					$cl = strtolower($cl);
+				}
+				if (t3lib_div::isFirstPartOfStr($cl, $str)) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Compares two arrays with MD5-hash values for analysis of which files has changed.
+	 *
+	 * @param	array		Current values
+	 * @param	array		Past values
+	 * @return	array		Affected files
+	 */
+	function findMD5ArrayDiff($current, $past) {
+		if (!is_array($current)) {
+			$current = array();
+		}
+		if (!is_array($past)) {
+			$past = array();
+		}
+		$filesInCommon = array_intersect($current, $past);
+		$diff1 = array_keys(array_diff($past, $filesInCommon));
+		$diff2 = array_keys(array_diff($current, $filesInCommon));
+		$affectedFiles = array_unique(array_merge($diff1, $diff2));
+		return $affectedFiles;
+	}
+
+	/**
+	 * Returns title and style attribute for mouseover help text.
+	 *
+	 * @param	string		Help text.
+	 * @return	string		title="" attribute prepended with a single space
+	 */
+	public function labelInfo($str) {
+		return ' title="' . htmlspecialchars($str) . '" style="cursor:help;"';
+	}
+
+
+	/**
+	 * Returns the absolute path where the extension $extKey is installed (based on 'type' (SGL))
+	 *
+	 * @param	string		Extension key
+	 * @param	string		Install scope type: L, G, S
+	 * @return	string		Returns the absolute path to the install scope given by input $type variable. It is checked if the path is a directory. Slash is appended.
+	 */
+	public function getExtPath($extKey, $type, $returnWithoutExtKey = FALSE) {
+		$typePath = self::typePath($type);
+
+		if ($typePath) {
+			$path = $typePath . ($returnWithoutExtKey ? '' : $extKey . '/');
+			return $path; # @is_dir($path) ? $path : '';
+		} else {
+			return '';
+		}
+	}
+
+	/**
+	 * Get type of extension (G,S,L) from extension path
+	 *
+	 * @param string $path
+	 */
+	public function getExtTypeFromPath($path) {
+		if (strpos($path, TYPO3_mainDir . 'sysext/') !== false) {
+			return 'S';
+		} elseif (strpos($path, TYPO3_mainDir . 'ext/') !== false) {
+			return 'G';
+		} elseif (strpos($path, 'typo3conf/ext/') !== false) {
+			return 'L';
+		}
+	}
+
+	/**
+	 * Get path from type
+	 *
+	 * @param string $type S/G/L
+	 */
+	public function typePath($type) {
+		if ($type === 'S') {
+			return PATH_typo3 . 'sysext/';
+		} elseif ($type === 'G') {
+			return PATH_typo3 . 'ext/';
+		} elseif ($type === 'L') {
+			return PATH_typo3conf . 'ext/';
+		}
+	}
+
+	/**
+	 * Reads locallang file into array (for possible include in header)
+	 *
+	 * @param $file
+	 */
+	public function getArrayFromLocallang($file, $key = 'default') {
+		$content = t3lib_div::getURL($file);
+		$array = t3lib_div::xml2array($content);
+		return $array['data'][$key];
+
+	}
+
+	/**
+	 * Include a locallang file and return the $LOCAL_LANG array serialized.
+	 *
+	 * @param	string		Absolute path to locallang file to include.
+	 * @param	string		Old content of a locallang file (keeping the header content)
+	 * @return	array		Array with header/content as key 0/1
+	 * @see makeUploadarray()
+	 */
+	function getSerializedLocalLang($file, $content) {
+		$LOCAL_LANG = NULL;
+		$returnParts = explode('$LOCAL_LANG', $content, 2);
+
+		include($file);
+		if (is_array($LOCAL_LANG)) {
+			$returnParts[1] = serialize($LOCAL_LANG);
+			return $returnParts;
+		} else {
+			return array();
+		}
+	}
+
+
+	/**
+	 * Enter description here...
+	 *
+	 * @param	unknown_type		$array
+	 * @param	unknown_type		$lines
+	 * @param	unknown_type		$level
+	 * @return	unknown
+	 */
+	function arrayToCode($array, $level = 0) {
+		$lines = 'array(' . LF;
+		$level++;
+		foreach ($array as $k => $v) {
+			if (strlen($k) && is_array($v)) {
+				$lines .= str_repeat(TAB, $level) . "'" . $k . "' => " . self::arrayToCode($v, $level);
+			} elseif (strlen($k)) {
+				$lines .= str_repeat(TAB, $level) . "'" . $k . "' => " . (t3lib_div::testInt($v) ? intval($v) : "'" . t3lib_div::slashJS(trim($v), 1) . "'") . ',' . LF;
+			}
+		}
+
+		$lines .= str_repeat(TAB, $level - 1) . ')' . ($level - 1 == 0 ? '' : ',' . LF);
+		return $lines;
+	}
+
+
+	/**
+	 * Traverse the array of installed extensions keys and arranges extensions in the priority order they should be in
+	 *
+	 * @param	array		Array of extension keys as values
+	 * @param	array		Extension information array
+	 * @return	array		Modified array of extention keys as values
+	 * @see addExtToList()
+	 */
+	function managesPriorities($listArr, $instExtInfo) {
+
+		// Initialize:
+		$levels = array(
+			'top' => array(),
+			'middle' => array(),
+			'bottom' => array(),
+		);
+
+		// Traverse list of extensions:
+		foreach ($listArr as $ext) {
+			$prio = trim($instExtInfo[$ext]['EM_CONF']['priority']);
+			switch ((string) $prio) {
+				case 'top':
+				case 'bottom':
+					$levels[$prio][] = $ext;
+					break;
+				default:
+					$levels['middle'][] = $ext;
+					break;
+			}
+		}
+		return array_merge(
+			$levels['top'],
+			$levels['middle'],
+			$levels['bottom']
+		);
+	}
+
+
+	/**
+	 * Returns either array with all default categories or index/title
+	 * of a category entry.
+	 *
+	 * @access  public
+	 * @param   mixed   $cat  category title or category index
+	 * @return  mixed
+	 */
+	static public function getDefaultCategory($cat = NULL) {
+		if (is_null($cat)) {
+			return self::$defaultCategories;
+		} else {
+			if (is_string($cat)) {
+				// default category
+				$catIndex = 4;
+				if (array_key_exists(strtolower($cat), self::$defaultCategories)) {
+					$catIndex = self::$defaultCategories[strtolower($cat)];
+				}
+				return $catIndex;
+			} else {
+				if (is_int($cat) && $cat >= 0) {
+					$catTitle = array_search($cat, self::$defaultCategories);
+					// default category
+					if (!$catTitle) {
+						$catTitle = 'misc';
+					}
+					return $catTitle;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Returns either array with all default states or index/title
+	 * of a state entry.
+	 *
+	 * @access  public
+	 * @param   mixed   $state  state title or state index
+	 * @return  mixed
+	 */
+	static public function getDefaultState($state = NULL) {
+		if (is_null($state)) {
+			return self::$defaultStates;
+		} else {
+			if (is_string($state)) {
+				// default state
+				$stateIndex = 999;
+				if (array_key_exists(strtolower($state), self::$defaultStates)) {
+					$stateIndex = self::$defaultStates[strtolower($state)];
+				}
+				return $stateIndex;
+			} else {
+				if (is_int($state) && $state >= 0) {
+					$stateTitle = array_search($state, self::$defaultStates);
+					// default state
+					if (!$stateTitle) {
+						$stateTitle = 'n/a';
+					}
+					return $stateTitle;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Reports back if installation in a certain scope is possible.
+	 *
+	 * @param	string		Scope: G, L, S
+	 * @param	string		Extension lock-type (eg. "L" or "G")
+	 * @return	boolean		True if installation is allowed.
+	 */
+	function importAsType($type, $lockType = '') {
+		switch ($type) {
+			case 'G':
+				return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall'] && (!$lockType || !strcmp($lockType, $type));
+				break;
+			case 'L':
+				return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowLocalInstall'] && (!$lockType || !strcmp($lockType, $type));
+				break;
+			case 'S':
+				return $this->systemInstall;
+				break;
+			default:
+				return false;
+		}
+	}
+
+	/**
+	 * Returns true if extensions in scope, $type, can be deleted (or installed for that sake)
+	 *
+	 * @param	string		Scope: "G" or "L"
+	 * @return	boolean		True if possible.
+	 */
+	function deleteAsType($type) {
+		switch ($type) {
+			case 'G':
+				return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall'];
+				break;
+			case 'L':
+				return $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowLocalInstall'];
+				break;
+			default:
+				return false;
+		}
+	}
+
+
+	/**
+	 * Creates directories in $extDirPath
+	 *
+	 * @param	array		Array of directories to create relative to extDirPath, eg. "blabla", "blabla/blabla" etc...
+	 * @param	string		Absolute path to directory.
+	 * @return	mixed		Returns false on success or an error string
+	 */
+	function createDirsInPath($dirs, $extDirPath) {
+		if (is_array($dirs)) {
+			foreach ($dirs as $dir) {
+				$error = t3lib_div::mkdir_deep($extDirPath, $dir);
+				if ($error) {
+					return $error;
+				}
+			}
+		}
+
+		return false;
+	}
+
+	/**
+	 * Analyses the php-scripts of an available extension on server
+	 *
+	 * @param	string		Absolute path to extension
+	 * @param	string		Prefix for tables/classes.
+	 * @param	string		Extension key
+	 * @return	array		Information array.
+	 * @see makeDetailedExtensionAnalysis()
+	 */
+	function getClassIndexLocallangFiles($absPath, $table_class_prefix, $extKey) {
+		$filesInside = t3lib_div::removePrefixPathFromList(t3lib_div::getAllFilesAndFoldersInPath(array(), $absPath, 'php,inc', 0, 99, $this->excludeForPackaging), $absPath);
+		$out = array();
+		$reg = array();
+
+		foreach ($filesInside as $fileName) {
+			if (substr($fileName, 0, 4) != 'ext_' && substr($fileName, 0, 6) != 'tests/') { // ignore supposed-to-be unit tests as well
+				$baseName = basename($fileName);
+				if (substr($baseName, 0, 9) == 'locallang' && substr($baseName, -4) == '.php') {
+					$out['locallang'][] = $fileName;
+				} elseif ($baseName != 'conf.php') {
+					if (filesize($absPath . $fileName) < 500 * 1024) {
+						$fContent = t3lib_div::getUrl($absPath . $fileName);
+						unset($reg);
+						if (preg_match('/\n[[:space:]]*class[[:space:]]*([[:alnum:]_]+)([[:alnum:][:space:]_]*)/', $fContent, $reg)) {
+
+							// Find classes:
+							$lines = explode(LF, $fContent);
+							foreach ($lines as $l) {
+								$line = trim($l);
+								unset($reg);
+								if (preg_match('/^class[[:space:]]*([[:alnum:]_]+)([[:alnum:][:space:]_]*)/', $line, $reg)) {
+									$out['classes'][] = $reg[1];
+									$out['files'][$fileName]['classes'][] = $reg[1];
+									if ($reg[1]!=='ext_update' && substr($reg[1], 0, 3) != 'ux_' && !t3lib_div::isFirstPartOfStr($reg[1], $table_class_prefix) && strcmp(substr($table_class_prefix, 0, -1), $reg[1])) {
+										$out['NSerrors']['classname'][] = $reg[1];
+									} else {
+										$out['NSok']['classname'][] = $reg[1];
+									}
+								}
+							}
+							// If class file prefixed 'class.'....
+							if (substr($baseName, 0, 6) == 'class.') {
+								$fI = pathinfo($baseName);
+								$testName = substr($baseName, 6, -(1 + strlen($fI['extension'])));
+								if ($testName!=='ext_update' && substr($testName, 0, 3) != 'ux_' && !t3lib_div::isFirstPartOfStr($testName, $table_class_prefix) && strcmp(substr($table_class_prefix, 0, -1), $testName)) {
+									$out['NSerrors']['classfilename'][] = $baseName;
+								} else {
+									$out['NSok']['classfilename'][] = $baseName;
+									if (is_array($out['files'][$fileName]['classes']) && tx_em_Tools::first_in_array($testName, $out['files'][$fileName]['classes'], 1)) {
+										$out['msg'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_class_ok'),
+											$fileName, $testName
+										);
+									} else {
+										$out['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_class_not_ok'),
+											$fileName, $testName
+										);
+									}
+								}
+							}
+							// Check for proper XCLASS definition
+							// Match $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS'] with single or doublequotes
+							$XclassSearch = '\$TYPO3_CONF_VARS\[TYPO3_MODE\]\[[\'"]XCLASS[\'"]\]';
+							$XclassParts = preg_split('/if \(defined\([\'"]TYPO3_MODE[\'"]\) && ' . $XclassSearch . '/', $fContent, 2);
+							if (count($XclassParts) !== 2) {
+								// Match $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS'] with single or doublequotes
+								$XclassSearch = '\$GLOBALS\[[\'"]TYPO3_CONF_VARS[\'"]\]\[TYPO3_MODE\]\[[\'"]XCLASS[\'"]\]';
+								$XclassParts = preg_split('/if \(defined\([\'"]TYPO3_MODE[\'"]\) && ' . $XclassSearch . '/', $fContent, 2);
+							}
+							if (count($XclassParts) == 2) {
+								unset($reg);
+								preg_match('/^\[[\'"]([[:alnum:]_\/\.]*)[\'"]\]/', $XclassParts[1], $reg);
+								if ($reg[1]) {
+									$cmpF = 'ext/' . $extKey . '/' . $fileName;
+									if (!strcmp($reg[1], $cmpF)) {
+										if (preg_match('/_once[[:space:]]*\(' . $XclassSearch . '\[[\'"]' . preg_quote($cmpF, '/') . '[\'"]\]\);/', $XclassParts[1])) {
+											$out['msg'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_xclass_ok'), $fileName);
+										} else {
+											$out['errors'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_xclass_no_include');
+										}
+									} else {
+										$out['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_xclass_incorrect'),
+											$reg[1], $cmpF
+										);
+									}
+								} else {
+									$out['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_no_xclass_filename'), $fileName);
+								}
+							} elseif (!tx_em_Tools::first_in_array('ux_', $out['files'][$fileName]['classes'])) {
+								// No Xclass definition required if classname starts with 'ux_'
+								$out['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_no_xclass_found'), $fileName);
+							}
+						}
+					}
+				}
+			}
+		}
+		return $out;
+	}
+
+	/**
+	 * Write new TYPO3_MOD_PATH to "conf.php" file.
+	 *
+	 * @param	string		Absolute path to a "conf.php" file of the backend module which we want to write back to.
+	 * @param	string		Install scope type: L, G, S
+	 * @param	string		Relative path for the module folder in extenson
+	 * @return	string		Returns message about the status.
+	 * @see modConfFileAnalysis()
+	 */
+	function writeTYPO3_MOD_PATH($confFilePath, $type, $mP) {
+		$lines = explode(LF, t3lib_div::getUrl($confFilePath));
+		$confFileInfo = array();
+		$confFileInfo['lines'] = $lines;
+		$reg = array();
+
+		$flag_M = 0;
+		$flag_B = 0;
+		$flag_Dispatch = 0;
+
+		foreach ($lines as $k => $l) {
+			$line = trim($l);
+
+			unset($reg);
+			if (preg_match('/^define[[:space:]]*\([[:space:]]*["\']TYPO3_MOD_PATH["\'][[:space:]]*,[[:space:]]*["\']([[:alnum:]_\/\.]+)["\'][[:space:]]*\)[[:space:]]*;/', $line, $reg)) {
+				$lines[$k] = str_replace($reg[0], 'define(\'TYPO3_MOD_PATH\', \'' . $this->typeRelPaths[$type] . $mP . '\');', $lines[$k]);
+				$flag_M = $k + 1;
+			}
+
+			unset($reg);
+			if (preg_match('/^\$BACK_PATH[[:space:]]*=[[:space:]]*["\']([[:alnum:]_\/\.]+)["\'][[:space:]]*;/', $line, $reg)) {
+				$lines[$k] = str_replace($reg[0], '$BACK_PATH=\'' . $this->typeBackPaths[$type] . '\';', $lines[$k]);
+				$flag_B = $k + 1;
+			}
+
+			// Check if this module uses new API (see http://bugs.typo3.org/view.php?id=5278)
+			// where TYPO3_MOD_PATH and BACK_PATH are not required
+			unset($reg);
+			if (preg_match('/^\$MCONF\[["\']script["\']\][[:space:]]*=[[:space:]]*["\']_DISPATCH["\'][[:space:]]*;/', $line, $reg)) {
+				$flag_Dispatch = $k + 1;
+			}
+
+		}
+
+		if ($flag_B && $flag_M) {
+			t3lib_div::writeFile($confFilePath, implode(LF, $lines));
+			return sprintf($GLOBALS['LANG']->getLL('writeModPath_ok'),
+				substr($confFilePath, strlen(PATH_site)));
+		} elseif ($flag_Dispatch) {
+			return sprintf(
+				$GLOBALS['LANG']->getLL('writeModPath_notRequired'),
+				substr($confFilePath, strlen(PATH_site))
+			);
+		} else {
+			return $GLOBALS["TBE_TEMPLATE"]->rfw(
+				sprintf($GLOBALS['LANG']->getLL('writeModPath_error'),
+					$confFilePath)
+			);
+		}
+	}
+
+	/**
+	 * Wrapping input string in a link tag with link to email address
+	 *
+	 * @param	string		Input string, being wrapped in <a> tags
+	 * @param	string		Email address for use in link.
+	 * @return	string		Output
+	 */
+	function wrapEmail($str, $email) {
+		if ($email) {
+			$str = '<a href="mailto:' . htmlspecialchars($email) . '">' . htmlspecialchars($str) . '</a>';
+		}
+		return $str;
+	}
+
+	/**
+	 * red-fontwrap. Returns the string wrapped in a <span>-tag defining the color to be red
+	 *
+	 * @param	string		Input string
+	 * @return	string		Output string
+	 */
+	function rfw($string) {
+		return '<span class="typo3-red">' . $string . '</span>';
+	}
+
+	/**
+	 * dimmed-fontwrap. Returns the string wrapped in a <span>-tag defining the color to be gray/dimmed
+	 *
+	 * @param	string		Input string
+	 * @return	string		Output string
+	 */
+	function dfw($string) {
+		return '<span class="typo3-dimmed">' . $string . '</span>';
+	}
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/exception/class.em_connection_exception.php
===================================================================
--- typo3/sysext/em/classes/exception/class.em_connection_exception.php	(revision 9222)
+++ typo3/sysext/em/classes/exception/class.tx_em_connection_exception.php	(revision )
@@ -25,7 +25,7 @@
 /**
  * Module: Extension manager - connection exception
  *
- * $Id: class.em_connection_exception.php 1876 2010-02-18 23:23:13Z mkrause $
+ * $Id: class.tx_em_connection_exception.php 1876 2010-02-18 23:23:13Z mkrause $
  */
 
 /**
@@ -42,7 +42,7 @@
  * @package     TYPO3
  * @subpackage  EM
  */
-class em_connection_Exception extends Exception {
+class tx_em_ConnectionException extends Exception {
 
 }
 ?>
\ No newline at end of file
Index: typo3/sysext/em/classes/exception/class.tx_em_extensionimport_exception.php
===================================================================
--- typo3/sysext/em/classes/exception/class.tx_em_extensionimport_exception.php	(revision )
+++ typo3/sysext/em/classes/exception/class.tx_em_extensionimport_exception.php	(revision )
@@ -0,0 +1,46 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
+*           Steffen Kamper <info@sk-typo3.de>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+/**
+ * Module: Extension manager - Extension import exception
+ *
+ * $Id: class.tx_em_extensionimport_exception.php 1883 2010-02-19 13:45:32Z mkrause $
+ */
+
+/**
+ * Exception for extension import handling.
+ *
+ * TODO: this is currently unused
+ *
+ * @author      Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author      Steffen Kamper <info@sk-typo3.de>
+ *
+ * @since       2010-02-18
+ * @package     TYPO3
+ * @subpackage  EM
+ */
+class tx_em_ExtensionImportException extends Exception {
+
+}
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/repository/class.tx_em_repository_mirrors.php
===================================================================
--- typo3/sysext/em/classes/repository/class.tx_em_repository_mirrors.php	(revision )
+++ typo3/sysext/em/classes/repository/class.tx_em_repository_mirrors.php	(revision )
@@ -0,0 +1,146 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
+ *		   Steffen Kamper <info@sk-typo3.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * class.em_repository_mirrors
+ *
+ * Module: Extension manager - Repository mirrors
+ *
+ * $Id: class.tx_em_repository_mirrors.php 1887 2010-02-19 22:22:54Z mkrause $
+ *
+ * @author  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author  Steffen Kamper <info@sk-typo3.de>
+ */
+
+/**
+ * Repository mirrors object for extension manager.
+ *
+ * @author	  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author	  Steffen Kamper <info@sk-typo3.de>
+ *
+ * @since	   2010-02-11
+ * @package	 TYPO3
+ * @subpackage  EM
+ */
+class tx_em_Repository_Mirrors {
+
+	/**
+	 * Keeps mirrors.
+	 *
+	 * @var  array
+	 */
+	protected $mirrors = array();
+
+	/**
+	 * Keeps currently select mirror.
+	 *
+	 * Is array index.
+	 *
+	 * @var  integer
+	 */
+	protected $currentMirror;
+
+	/**
+	 * Keeps information if a mirror should
+	 * be randomly selected.
+	 *
+	 * @var  boolean
+	 */
+	protected $isRandomSelection = TRUE;
+
+	/**
+	 * Class constructor.
+	 *
+	 * @access  public
+	 * @return  void
+	 */
+	function __construct() {
+		// empty constructor
+	}
+
+	/**
+	 * Method selects one specific mirror to be used.
+	 *
+	 * @access  public
+	 * @param   integer  $mirrorID  an order number (>=1) of mirror or NULL for random selection
+	 * @return  void
+	 * @see	 $currentMirror
+	 */
+	public function setSelect($mirrorID = NULL) {
+		if (is_null($mirrorID)) {
+			$this->isRandomSelection = TRUE;
+		} else {
+			if (is_int($mirrorID) && $mirrorID >= 1 && $mirrorID <= count($this->mirrors)) {
+				$this->currentMirror = $mirrorID - 1;
+			}
+		}
+	}
+
+	/**
+	 * Method returns one mirror for use.
+	 *
+	 * Mirror has previously been selected or is chosen
+	 * randomly.
+	 *
+	 * @access  public
+	 * @return  array  array of a mirror's properties or NULL in case of errors
+	 */
+	public function getMirror() {
+		$sumMirrors = count($this->mirrors);
+		if ($sumMirrors > 0) {
+			if (!is_int($this->currentMirror)) {
+				$this->currentMirror = rand(0, $sumMirrors - 1);
+			}
+			return $this->mirrors[$this->currentMirror];
+		}
+		return NULL;
+	}
+
+	/**
+	 * Method returns all available mirrors.
+	 *
+	 * @access  public
+	 * @return  array  multidimensional array with mirrors and their properties
+	 * @see	 $mirrors, setMirrors()
+	 */
+	public function getMirrors() {
+		return $this->mirrors;
+	}
+
+	/**
+	 * Method sets available mirrors.
+	 *
+	 * @access  public
+	 * @param   array  $mirrors  multidimensional array with mirrors and their properties to set
+	 * @return  void
+	 * @see	 $mirrors, getMirrors()
+	 */
+	public function setMirrors(array $mirrors) {
+		if (count($mirrors) >= 1) {
+			$this->mirrors = $mirrors;
+		}
+	}
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/settings/class.tx_em_settings.php
===================================================================
--- typo3/sysext/em/classes/settings/class.tx_em_settings.php	(revision )
+++ typo3/sysext/em/classes/settings/class.tx_em_settings.php	(revision )
@@ -0,0 +1,274 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Steffen Kamper (info@sk-typo3.de)
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * Module: Extension manager, developer module
+ *
+ * $Id: class.tx_em_settings.php 2089 2010-03-22 12:03:25Z steffenk $
+ *
+ * @author	Steffen Kamper <info@sk-typo3.de>
+ */
+
+
+$GLOBALS['LANG']->includeLLFile(t3lib_extMgm::extPath('em', 'language/locallang.xml'));
+
+
+class tx_em_Settings implements t3lib_Singleton {
+
+	public $MOD_MENU = array(); // Module menu items
+
+
+	/**
+	 * Develop commands
+	 *
+	 * @var string
+	 */
+	protected $settings;
+
+	/**
+	 * Constructor
+	 *
+	 */
+	public function __construct() {
+		$this->readSettings();
+	}
+
+	/**
+	 * Get Session Settings
+	 */
+	public function getSettings() {
+		return $this->settings;
+	}
+
+	/**
+	 * Get User Settings
+	 */
+	public function getUserSettings() {
+		$userSettings = t3lib_beFunc::getModTSconfig(0, 'mod.tools_em');
+		return $userSettings['properties'];
+	}
+
+	/**
+	 * Save Settings
+	 *
+	 * @param array $settings
+	 */
+	public function saveSettings($settings) {
+		$this->settings = t3lib_BEfunc::getModuleData($this->MOD_MENU, $settings, 'tools_em');
+		return $this->settings;
+	}
+
+	/**
+	 * Save single value in session settings
+	 *
+	 * @param string $name
+	 * @param string $value
+	 */
+	public function saveSetting($name, $value) {
+		t3lib_BEfunc::getModuleData($this->MOD_MENU, array($name => $value), 'tools_em');
+	}
+
+	/**
+	 * @return void
+	 */
+	protected function readSettings() {
+		$this->MOD_MENU = array(
+			'function' => array(
+				'loaded_list' => $GLOBALS['LANG']->getLL('menu_loaded_extensions'),
+				'installed_list' => $GLOBALS['LANG']->getLL('menu_install_extensions'),
+				'import' => $GLOBALS['LANG']->getLL('menu_import_extensions'),
+				'translations' => $GLOBALS['LANG']->getLL('menu_translation_handling'),
+				'settings' => $GLOBALS['LANG']->getLL('menu_settings'),
+				'updates' => $GLOBALS['LANG']->getLL('menu_extension_updates'),
+				//'extensionmanager' => 'New Extension Manager',
+				//'develop' => $GLOBALS['LANG']->getLL('menu_extension_develop'),
+			),
+			'listOrder' => array(
+				'cat' => $GLOBALS['LANG']->getLL('list_order_category'),
+				'author_company' => $GLOBALS['LANG']->getLL('list_order_author'),
+				'state' => $GLOBALS['LANG']->getLL('list_order_state'),
+				'type' => $GLOBALS['LANG']->getLL('list_order_type'),
+			),
+			'display_details' => array(
+				1 => $GLOBALS['LANG']->getLL('show_details'),
+				0 => $GLOBALS['LANG']->getLL('show_description'),
+				2 => $GLOBALS['LANG']->getLL('show_more_details'),
+
+				3 => $GLOBALS['LANG']->getLL('show_technical'),
+				4 => $GLOBALS['LANG']->getLL('show_validating'),
+				5 => $GLOBALS['LANG']->getLL('show_changed'),
+			),
+			'display_shy' => '',
+			'display_own' => '',
+			'display_obsolete' => '',
+			'display_installed' => '',
+			'display_files' => '',
+
+
+			'singleDetails' => array(
+				'info' => $GLOBALS['LANG']->getLL('details_info'),
+				'edit' => $GLOBALS['LANG']->getLL('details_edit'),
+				'backup' => $GLOBALS['LANG']->getLL('details_backup_delete'),
+				'dump' => $GLOBALS['LANG']->getLL('details_dump_db'),
+				'upload' => $GLOBALS['LANG']->getLL('details_upload'),
+				'updateModule' => $GLOBALS['LANG']->getLL('details_update'),
+			),
+			'fe_u' => '',
+			'fe_p' => '',
+
+			'mirrorListURL' => '',
+			'rep_url' => '',
+			'extMirrors' => '',
+
+			// returns uid of currently selected repository
+			// default and hardcoded: 1 = TYPO3.org
+			'selectedRepository' => '1',
+			'selectedMirror' => '0',
+
+			'selectedLanguages' => '',
+
+			'mainTab' => '0',
+		);
+		$this->settings = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), 'tools_em');
+	}
+
+	/**
+	 * @return string
+	 */
+	public function getMirrorURL() {
+		if (strlen($this->settings['rep_url'])) {
+			return $this->settings['rep_url'];
+		}
+
+		$mirrors = unserialize($this->settings['extMirrors']);
+		/*if(!is_array($mirrors)) {
+			$this->fetchMetaData('mirrors');
+			$mirrors = unserialize($this->MOD_SETTINGS['extMirrors']);
+			if(!is_array($mirrors)) return false;
+		}*/
+		if (!$this->settings['selectedMirror']) {
+			$rand = array_rand($mirrors);
+			$url = 'http://' . $mirrors[$rand]['host'] . $mirrors[$rand]['path'];
+		}
+		else {
+			$url = 'http://' . $mirrors[$this->settings['selectedMirror']]['host'] . $mirrors[$this->settings['selectedMirror']]['path'];
+		}
+
+		return $url;
+	}
+
+	/**
+	 * Method returns registered extension repositories.
+	 *
+	 * Registered repositories are global (per installation) settings.
+	 *
+	 * @access  public
+	 * @return  array of {@link em_repository em_repository} instances
+	 * @see	 registerDefaultRepository(), setRegisteredRepositories()
+	 */
+	public function getRegisteredRepositories() {
+		$registry = t3lib_div::makeInstance('t3lib_Registry');
+		$regRepos = $registry->get('core', 'em.repositories.registered');
+
+		// create default entry if there wasn't one
+		if (empty($regRepos)) {
+			$this->registerDefaultRepository();
+			$regRepos = $registry->get('core', 'em.repositories.registered');
+		}
+
+		return $regRepos;
+	}
+
+	/**
+	 * Method creates default registered repositories entry.
+	 *
+	 * @access  protected
+	 * @return  void
+	 * @see	 getRegisteredRepository(), setRegisteredRepositories()
+	 */
+	protected function registerDefaultRepository() {
+		$registry = t3lib_div::makeInstance('t3lib_Registry');
+		$defaultRepo = t3lib_div::makeInstance('tx_em_Repository');
+		$registry->set('core', 'em.repositories.registered', array($defaultRepo));
+	}
+
+	/**
+	 * Method sets (persists) registered repositories.
+	 *
+	 * Registered repositories are global (per installation) settings.
+	 *
+	 * @access  public
+	 * @param   array  $repositories  array of {@link em_repository em_repository} instances
+	 * @see	 registerDefaultRepository(), setRegisteredRepositories()
+	 * @throws  InvalidArgumentException in case argument contains no instances of {@link em_repository em_repository}
+	 */
+	public function setRegisteredRepositories(array $repositories) {
+		// removing mirror instances
+		foreach ($repositories as $repository) {
+			if ($repository instanceof em_repository) {
+				$repository->removeMirrors();
+			} else {
+				throw new InvalidArgumentException(get_class($this) . ': ' . 'No valid instances of em_repository given.');
+			}
+		}
+		if (count($repositories)) {
+			$registry = t3lib_div::makeInstance('t3lib_Registry');
+			$registry->set('core', 'em.repositories.registered', $repositories);
+		}
+	}
+
+	/**
+	 * Method returns currently selected repository
+	 *
+	 * Selected repository is local (per user) settings.
+	 *
+	 * @access  public
+	 * @return  em_repository  repository instance that is currently selected by a BE user
+	 * @see	 setSelectedRepository()
+	 */
+	public function getSelectedRepository() {
+		return t3lib_div::makeInstance('tx_em_Repository', $this->settings['selectedRepository']);
+	}
+
+	/**
+	 * Method sets currently selected repository.
+	 *
+	 * Selected repository is local (per user) settings.
+	 *
+	 * @todo	STUB, implementation missing
+	 * @access  public
+	 * @param   em_repository  $repository  repository instance that is currently selected by a BE user
+	 * @see	 getSelectedRepository()
+	 */
+	public function setSelectedRepository(em_repository $repository) {
+		// this method would set sth. like "REPOSITORY_TITLE:INT" in a setting field
+		// REPOSITORY_TITLE = example: main
+		// INT = 0 means randomly selected mirror, >0 selects specific mirror
+	}
+
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/repository/class.tx_em_repository.php
===================================================================
--- typo3/sysext/em/classes/repository/class.tx_em_repository.php	(revision )
+++ typo3/sysext/em/classes/repository/class.tx_em_repository.php	(revision )
@@ -0,0 +1,394 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
+ *		   Steffen Kamper <info@sk-typo3.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * class.tx_em_repository.php
+ *
+ * Module: Extension manager - Repository
+ *
+ * $Id: class.tx_em_repository.php 2082 2010-03-21 17:19:42Z steffenk $
+ *
+ * @author  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author  Steffen Kamper <info@sk-typo3.de>
+ */
+
+
+/**
+ * Repository object for extension manager.
+ *
+ * @author	  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author	  Steffen Kamper <info@sk-typo3.de>
+ *
+ * @since	   2010-02-11
+ * @package	 TYPO3
+ * @subpackage  EM
+ */
+class tx_em_Repository {
+
+	/**
+	 * Keeps repository identifier.
+	 *
+	 * @var  string
+	 */
+	protected $id;
+
+	/**
+	 * Keeps repository title.
+	 *
+	 * @var  string
+	 */
+	protected $title;
+
+	/**
+	 * Keeps repository description.
+	 *
+	 * @var  string
+	 */
+	protected $description;
+
+	/**
+	 * Keeps repository priority.
+	 *
+	 * @var  integer
+	 */
+	protected $priority;
+
+	/**
+	 * Keeps mirror list URL.
+	 *
+	 * @var  string
+	 */
+	protected $mirrorListUrl;
+
+	/**
+	 * Keeps repository mirrors object.
+	 *
+	 * @var  em_repository_mirrors
+	 */
+	protected $mirrors;
+
+	/**
+	 * Keeps wsdl URL.
+	 *
+	 * @var  string
+	 */
+	protected $wsdlUrl;
+
+	/**
+	 * Keeps last update.
+	 *
+	 * @var  string
+	 */
+	protected $lastUpdate;
+
+	/**
+	 * Keeps extension count.
+	 *
+	 * @var  string
+	 */
+	protected $extensionCount;
+
+
+	/**
+	 * Class constructor.
+	 *
+	 * Initializes repository with properties of TYPO3.org main repository.
+	 *
+	 * @access  public
+	 * @return  void
+	 */
+	function __construct($uid = 0) {
+		if ($uid === 0) {
+			// default repository
+			$this->setTitle('TYPO3.org Main Repository');
+			$this->setId('1');
+			$this->setPriority(1);
+			$this->setMirrorListUrl('http://repositories.typo3.org/mirrors.xml.gz');
+			$this->setWsdlUrl('http://typo3.org/wsdl/tx_ter_wsdl.php');
+		} else {
+			$row = tx_em_Database::getRepositoryByUID($uid);
+			$this->setTitle($row['title']);
+			$this->setId($row['uid']);
+			$this->setPriority(1);
+			$this->setMirrorListUrl($row['mirror_url']);
+			$this->setWsdlUrl($row['wsdl_url']);
+			$this->setLastUpdate($row['lastUpdated']);
+			$this->setExtensionCount($row['extCount']);
+		}
+
+	}
+
+	/**
+	 * Method returns uid of a repository.
+	 *
+	 * @access  public
+	 * @return  int  ID of a repository
+	 * @see	 $id, setId()
+	 */
+	public function getId() {
+		return $this->id;
+	}
+
+	/**
+	 * Method sets uid of a repository.
+	 *
+	 * @access  public
+	 * @param   string  $id  ID of repository to set
+	 * @return  void
+	 * @see	 $id, getId()
+	 */
+	public function setId($id) {
+		$this->id = intval($id);
+	}
+
+	/**
+	 * Method returns title of a repository.
+	 *
+	 * @access  public
+	 * @return  string  title of repository
+	 * @see	 $title, setTitle()
+	 */
+	public function getTitle() {
+		return $this->title;
+	}
+
+	/**
+	 * Method sets title of a repository.
+	 *
+	 * @access  public
+	 * @param   string  $title  title of repository to set
+	 * @return  void
+	 * @see	 $title, getTitle()
+	 */
+	public function setTitle($title) {
+		if (!empty($title) && is_string($title)) {
+			$this->title = $title;
+		}
+	}
+
+	/**
+	 * Method returns description of a repository.
+	 *
+	 * @access  public
+	 * @return  string  title of repository
+	 * @see	 $title, setTitle()
+	 */
+	public function getDescription() {
+		return $this->description;
+	}
+
+	/**
+	 * Method sets description of a repository.
+	 *
+	 * @access  public
+	 * @param   string  $description  title of repository to set
+	 * @return  void
+	 */
+	public function setDescription($description) {
+		if (!empty($description) && is_string($description)) {
+			$this->description = $description;
+		}
+	}
+
+	/**
+	 * Method returns priority of a repository.
+	 *
+	 * The repository with lowest priority value takes precedence over
+	 * those that have a higher value.
+	 *
+	 * @access  public
+	 * @return  integer
+	 * @see	 $priority, setPriority()
+	 * @todo	repository priority is currently unused
+	 */
+	public function getPriority() {
+		return $this->priority;
+	}
+
+	/**
+	 * Method sets priority of a repository.
+	 *
+	 * The repository with lowest priority value takes precedence over
+	 * those that have a higher value.
+	 *
+	 * @access  public
+	 * @param   integer  $priority  priority value to set
+	 * @return  void
+	 * @see	 $priority, getPriority()
+	 * @todo	repository priority is currently unused
+	 */
+	public function setPriority($priority) {
+		if (!empty($priority) && is_int($priority)) {
+			$this->priority = $priority;
+		}
+	}
+
+	/**
+	 * Method returns URL of a ressource that contains repository mirrors.
+	 *
+	 * @access  public
+	 * @return  string  URL of file that contains repository mirros
+	 * @see	 $mirrorListUrl, getMirrorListUrl()
+	 */
+	public function getMirrorListUrl() {
+		return $this->mirrorListUrl;
+	}
+
+	/**
+	 * Method sets URL of a ressource that contains repository mirrors.
+	 *
+	 * Parameter is typically a remote gzipped xml file.
+	 *
+	 * @access  public
+	 * @param   string  $url  URL of file that contains repository mirros
+	 * @return  void
+	 * @see	 $mirrorListUrl, getMirrorListUrl()
+	 */
+	public function setMirrorListUrl($url) {
+		if (!empty($url) && t3lib_div::isValidUrl($url)) {
+			$this->mirrorListUrl = $url;
+		}
+	}
+
+	/**
+	 * Method returns URL of repository WSDL.
+	 *
+	 * @access  public
+	 * @return  string  URL of repository WSDL
+	 * @see	 $wsdlUrl, setWsdlUrl()
+	 */
+	public function getWsdlUrl() {
+		return $this->wsdlUrl;
+	}
+
+	/**
+	 * Method sets URL of repository WSDL.
+	 *
+	 * @access  public
+	 * @param   string  $url  URL of repository WSDL
+	 * @return  void
+	 * @see	 $wsdlUrl, getWsdlUrl()
+	 */
+	public function setWsdlUrl($url) {
+		if (!empty($url) && t3lib_div::isValidUrl($url)) {
+			$this->wsdlUrl = $url;
+		}
+	}
+
+	/**
+	 * Method returns LastUpdate.
+	 *
+	 * @access  public
+	 * @return  int  timestamp of last update
+	 */
+	public function getLastUpdate() {
+		return $this->lastUpdate;
+	}
+
+	/**
+	 * Method sets LastUpdate.
+	 *
+	 * @access  public
+	 * @param   int  $time  URL of repository WSDL
+	 * @return  void
+	 */
+	public function setLastUpdate($time) {
+		$this->lastUpdate = $time;
+	}
+
+	/**
+	 * Method returns extension count
+	 *
+	 * @access  public
+	 * @return  int count of readed extensions
+	 */
+	public function getExtensionCount() {
+		return $this->extensionCount;
+	}
+
+	/**
+	 * Method sets extension count
+	 *
+	 * @access  public
+	 * @param   string  $count count of readed extensions
+	 * @return  void
+	 */
+	public function setExtensionCount($count) {
+		$this->extensionCount = $count;
+	}
+
+	/**
+	 * Method registers repository mirrors object.
+	 *
+	 * Repository mirrors object is passed by reference.
+	 *
+	 * @access  public
+	 * @param   em_repository_mirrors  &$mirrors  instance of {@link em_repository_mirrors repository mirrors} class
+	 * @return  void
+	 * @see	 $mirrors, getMirrors(), hasMirrors(), removeMirrors()
+	 */
+	public function addMirrors(tx_em_Repository_Mirrors &$mirrors) {
+		$this->mirrors = $mirrors;
+	}
+
+	/**
+	 * Method returns information if a repository mirrors
+	 * object has been registered to this repository.
+	 *
+	 * @access  public
+	 * @return  boolean  true, if a repository mirrors object has been registered, otherwise false
+	 * @see	 $mirrors, addMirrors(), getMirrors(), removeMirrors()
+	 */
+	public function hasMirrors() {
+		$hasMirrors = FALSE;
+		if (is_object($this->mirrors)) {
+			$hasMirrors = TRUE;
+		}
+		return $hasMirrors;
+	}
+
+	/**
+	 * Method returns a repository mirrors object.
+	 *
+	 * @access  public
+	 * @return  em_repository_mirrors  registered instance of {@link em_repository_mirrors repository mirrors} class or NULL
+	 * @see	 $mirrors, addMirrors(), hasMirrors(), removeMirrors()
+	 */
+	public function getMirrors() {
+		return $this->hasMirrors() ? $this->mirrors : NULL;
+	}
+
+	/**
+	 * Method unregisters a repository mirrors object.
+	 *
+	 * @access  public
+	 * @return  void
+	 * @see	 $mirrors, addMirrors(), getMirrors(), hasMirrors()
+	 */
+	public function removeMirrors() {
+		unset($this->mirrors);
+	}
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/connection/class.tx_em_connection_soap.php
===================================================================
--- typo3/sysext/em/classes/connection/class.tx_em_connection_soap.php	(revision )
+++ typo3/sysext/em/classes/connection/class.tx_em_connection_soap.php	(revision )
@@ -0,0 +1,274 @@
+<?php
+/* **************************************************************
+*  Copyright notice
+*
+*  (c) webservices.nl
+*  (c) 2006-2010 Karsten Dambekalns <karsten@typo3.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+/* $Id: class.tx_em_Connection_Soap.php 1978 2010-03-09 03:18:50Z mkrause $ */
+
+/**
+ * Enter description here...
+ *
+ */
+class tx_em_Connection_Soap {
+	/**
+	 * valid options passed to the constructor :
+	 * wsdl		   : The WSDL location, can be a local file location or
+	 *				  an URL.
+	 * soapoptions	: Associative array of SOAP options to be passed to
+	 *				  the SOAP implementation constructor, only used for
+	 *				  the phpsoap implement.
+	 * authentication : method of authentication :
+	 *				  'headers'   soap headers are used
+	 *				  'prefix'	function prefixes are used
+	 * prefix		 : optional prefix to be put in front of all methods.
+	 * format		 : Which type of return structure :
+	 *				  'object'	PHP objects
+	 *				  'array'	 PHP arrays, default
+	 */
+	var $options = array();
+
+	/**
+	 * SOAP client, instance of PHP SOAP class
+	 *
+	 * @var SoapClient
+	 */
+	var $client = false;
+
+	var $error = false;
+	var $username = false;
+	var $password = false;
+	var $reactid = false;
+
+	/**
+	 * Enter description here...
+	 *
+	 * @param	array		$options
+	 * @param	string		$username
+	 * @param	string		$password
+	 * @return	[type]		...
+	 */
+	function init($options = false, $username = false, $password = false) {
+		if ($username !== false) {
+			if ($password === false) {
+				$this->reactid = $username;
+			} else {
+				$this->username = $username;
+				$this->password = $password;
+			}
+		}
+
+		$options['format'] = $options['format'] == 'object' ? 'object' : 'array';
+
+		if ($options !== false) {
+			$this->options = (array) $options;
+		}
+
+		if (defined('SOAP_1_2')) {
+			$this->client = new SoapClient($options['wsdl'], (array) $options['soapoptions']);
+		} else {
+			$this->client = FALSE;
+			throw new Exception('PHP soap extension not available');
+		}
+	}
+
+	/**
+	 * Enter description here...
+	 *
+	 * @param	string		$username
+	 * @param	string		$password
+	 * @return	mixed		false on failure, $reactid on success
+	 */
+	function login($username, $password) {
+		$reactid = $this->call('login', array('username' => $username, 'password' => $password));
+
+		if ($this->error) {
+			return false;
+		}
+
+		$this->reactid = $reactid;
+		$this->username = $username;
+		$this->password = false;
+
+		return $reactid;
+	}
+
+	/**
+	 * Enter description here...
+	 *
+	 * @return	unknown
+	 */
+	function logout() {
+		$this->call('logout');
+		$this->reactid = false;
+		if ($this->error) {
+			return false;
+		}
+		return true;
+	}
+
+
+	/**
+	 * Enter description here...
+	 *
+	 * @param	unknown_type		$func
+	 * @param	unknown_type		$param
+	 * @param	unknown_type		$username
+	 * @param	unknown_type		$password
+	 * @return	unknown
+	 */
+	function call($func, $param = array(), $username = false, $password = false) {
+		if (!$this->client) {
+			$this->error = sprintf(
+				'Error in %s: No soap client implementation found. ' .
+						'Make sure PHP soap extension is available!', __FILE__);
+			return false;
+		}
+
+		if ($username !== false) {
+			if ($password === false) {
+				$this->reactid = $username;
+			} else {
+				$this->username = $username;
+				$this->password = $password;
+			}
+		}
+
+		if ($this->options['authentication'] == 'prefix') {
+			$param = array_merge(array('reactid' => $this->reactid), $param);
+		}
+
+		if ($this->options['prefix']) {
+			$func = $this->options['prefix'] . ucfirst($func);
+		}
+		$this->error = false;
+
+		return $this->callPhpSOAP($func, $param);
+	}
+
+	/**
+	 * Enter description here...
+	 *
+	 * @param	unknown_type		$func
+	 * @param	unknown_type		$param
+	 * @return	unknown
+	 */
+	function callPhpSOAP($func, $param) {
+		$header = null;
+		if ($this->options['authentication'] == 'headers') {
+			if ($this->reactid) {
+				$header = new SoapHeader(
+					'', 'HeaderAuthenticate',
+					(object) array('reactid' => $this->reactid), 1
+				);
+			} elseif ($this->username && $this->password) {
+				$header = new SoapHeader(
+					'', 'HeaderLogin',
+					(object) array(
+						'username' => $this->username,
+						'password' => $this->password
+					), 1
+				);
+				$this->password = false;
+			}
+		}
+
+		$result = $this->client->__soapCall($func, $param, NULL, $header);
+
+		if (is_soap_fault($result)) {
+			$this->error = $result;
+			return false;
+		}
+
+		if (is_a($this->client->headersIn['HeaderAuthenticate'], 'stdClass')) {
+			$this->reactid = $this->client->headersIn['HeaderAuthenticate']->reactid;
+		}
+
+		return $this->options['format'] == 'object' ? $result : $this->object2array($result);
+	}
+
+	/**
+	 * Enter description here...
+	 *
+	 * @param	unknown_type		$object
+	 * @return	unknown
+	 */
+	function object2array($object) {
+		if (!is_object($object) && !is_array($object)) {
+			return $object;
+		}
+
+		$array = (array) $object;
+		foreach ($array as $key => $value) {
+			$array[$key] = $this->object2array($value);
+		}
+		return $array;
+	}
+
+	/**
+	 * Enter description here...
+	 *
+	 * @param	unknown_type		$array
+	 * @return	unknown
+	 */
+	function array2object($array) {
+		if (!is_array($array)) {
+			return $array;
+		}
+
+		foreach ($array as $key => $value) {
+			$array[$key] = $this->array2object($value);
+		}
+		return (object) $array;
+	}
+
+	/**
+	 * Enter description here...
+	 *
+	 * @return	unknown
+	 */
+	function lastRequest() {
+		return $this->client->__getLastRequest();
+	}
+
+	/**
+	 * Enter description here...
+	 *
+	 * @return	unknown
+	 */
+	function lastResponse() {
+		$this->client->__getLastResponse();
+	}
+
+	/**
+	 * Enter description here...
+	 *
+	 * @return	unknown
+	 */
+	function getFunctions() {
+		return $this->client->__getFunctions();
+	}
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/tools/class.tx_em_tools_unzip.php
===================================================================
--- typo3/sysext/em/classes/tools/class.tx_em_tools_unzip.php	(revision )
+++ typo3/sysext/em/classes/tools/class.tx_em_tools_unzip.php	(revision )
@@ -0,0 +1,1385 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) Vincent Blavet <vincent@phpconcept.net>
+ *  (c) 2005-2010 Karsten Dambekalns <karsten@typo3.org>
+ *  All rights reserved
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * Module: Extension manager
+ *
+ * $Id: class.tx_em_tools_unzip.php 1977 2010-03-09 03:13:20Z mkrause $
+ *
+ * @author	Vincent Blavet <vincent@phpconcept.net>
+ * @author	Karsten Dambekalns <karsten@typo3.org>
+ */
+
+
+// Constants
+define('ARCHIVE_ZIP_READ_BLOCK_SIZE', 2048);
+
+// File list separator
+define('ARCHIVE_ZIP_SEPARATOR', ',');
+
+define('ARCHIVE_ZIP_TEMPORARY_DIR', '');
+
+// Error codes
+define('ARCHIVE_ZIP_ERR_NO_ERROR', 0);
+define('ARCHIVE_ZIP_ERR_WRITE_OPEN_FAIL', -1);
+define('ARCHIVE_ZIP_ERR_READ_OPEN_FAIL', -2);
+define('ARCHIVE_ZIP_ERR_INVALID_PARAMETER', -3);
+define('ARCHIVE_ZIP_ERR_MISSING_FILE', -4);
+define('ARCHIVE_ZIP_ERR_FILENAME_TOO_LONG', -5);
+define('ARCHIVE_ZIP_ERR_INVALID_ZIP', -6);
+define('ARCHIVE_ZIP_ERR_BAD_EXTRACTED_FILE', -7);
+define('ARCHIVE_ZIP_ERR_DIR_CREATE_FAIL', -8);
+define('ARCHIVE_ZIP_ERR_BAD_EXTENSION', -9);
+define('ARCHIVE_ZIP_ERR_BAD_FORMAT', -10);
+define('ARCHIVE_ZIP_ERR_DELETE_FILE_FAIL', -11);
+define('ARCHIVE_ZIP_ERR_RENAME_FILE_FAIL', -12);
+define('ARCHIVE_ZIP_ERR_BAD_CHECKSUM', -13);
+define('ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP', -14);
+define('ARCHIVE_ZIP_ERR_MISSING_OPTION_VALUE', -15);
+define('ARCHIVE_ZIP_ERR_INVALID_PARAM_VALUE', -16);
+
+// Warning codes
+define('ARCHIVE_ZIP_WARN_NO_WARNING', 0);
+define('ARCHIVE_ZIP_WARN_FILE_EXIST', 1);
+
+// Methods parameters
+define('ARCHIVE_ZIP_PARAM_PATH', 'path');
+define('ARCHIVE_ZIP_PARAM_ADD_PATH', 'add_path');
+define('ARCHIVE_ZIP_PARAM_REMOVE_PATH', 'remove_path');
+define('ARCHIVE_ZIP_PARAM_REMOVE_ALL_PATH', 'remove_all_path');
+define('ARCHIVE_ZIP_PARAM_SET_CHMOD', 'set_chmod');
+define('ARCHIVE_ZIP_PARAM_EXTRACT_AS_STRING', 'extract_as_string');
+define('ARCHIVE_ZIP_PARAM_NO_COMPRESSION', 'no_compression');
+
+define('ARCHIVE_ZIP_PARAM_PRE_EXTRACT', 'callback_pre_extract');
+define('ARCHIVE_ZIP_PARAM_POST_EXTRACT', 'callback_post_extract');
+define('ARCHIVE_ZIP_PARAM_PRE_ADD', 'callback_pre_add');
+define('ARCHIVE_ZIP_PARAM_POST_ADD', 'callback_post_add');
+
+
+/**
+ * Class for unpacking zip archive files
+ *
+ * @author   Vincent Blavet <vincent@blavet.net>
+ * @author   Karsten Dambekalns <karsten@typo3.org>
+ */
+class tx_em_Tools_Unzip {
+	/**
+	 * The filename of the zip archive.
+	 *
+	 * @var string Name of the Zip file
+	 */
+	var $_zipname = '';
+
+	/**
+	 * File descriptor of the opened Zip file.
+	 *
+	 * @var int Internal zip file descriptor
+	 */
+	var $_zip_fd = 0;
+
+	/**
+	 * @var int last error code
+	 */
+	var $_error_code = 1;
+
+	/**
+	 * @var string Last error description
+	 */
+	var $_error_string = '';
+
+	/**
+	 * tx_em_Tools_Unzip Class constructor. This flavour of the constructor only
+	 * declare a new tx_em_Tools_Unzip object, identifying it by the name of the
+	 * zip file.
+	 *
+	 * @param	string  $p_zipname  The name of the zip archive to create
+	 * @access public
+	 */
+	public function __construct($p_zipname) {
+
+		// Check the zlib
+		if (!extension_loaded('zlib')) {
+			throw new RuntimeException(
+				'TYPO3 Fatal Error: ' . "The extension 'zlib' couldn't be found.\n" .
+						"Please make sure your version of PHP was built " .
+						"with 'zlib' support.\n",
+				1270853984
+			);
+		}
+
+		// Set the attributes
+		$this->_zipname = $p_zipname;
+		$this->_zip_fd = 0;
+
+		return;
+	}
+
+
+	/**
+	 * This method extract the files and folders which are in the zip archive.
+	 * It can extract all the archive or a part of the archive by using filter
+	 * feature (extract by name, by index, by ereg, by preg). The extraction
+	 * can occur in the current path or an other path.
+	 * All the advanced features are activated by the use of variable
+	 * parameters.
+	 * The return value is an array of entry descriptions which gives
+	 * information on extracted files (See listContent()).
+	 * The method may return a success value (an array) even if some files
+	 * are not correctly extracted (see the file status in listContent()).
+	 * The supported variable parameters for this method are :
+	 *   'add_path' : Path where the files and directories are to be extracted
+	 *
+	 * @access public
+	 * @param	mixed  $p_params  An array of variable parameters and values.
+	 * @return mixed An array of file description on success,
+	 *			   0 on an unrecoverable failure, an error code is logged.
+	 */
+	function extract($p_params = 0) {
+		$this->_errorReset();
+
+		// Check archive
+		if (!$this->_checkFormat()) {
+			return (0);
+		}
+
+		// Set default values
+		if ($p_params === 0) {
+			$p_params = array();
+		}
+		if ($this->_check_parameters($p_params,
+			array('extract_as_string' => false,
+				'add_path' => '',
+				'remove_path' => '',
+				'remove_all_path' => false,
+				'callback_pre_extract' => '',
+				'callback_post_extract' => '',
+				'set_chmod' => 0)) != 1) {
+			return 0;
+		}
+
+		// Call the extracting fct
+		$v_list = array();
+		if ($this->_extractByRule($v_list, $p_params) != 1) {
+			unset($v_list);
+			return (0);
+		}
+
+		return $v_list;
+	}
+
+	/**
+	 * Method that gives the lastest error code.
+	 *
+	 * @access public
+	 * @return integer The error code value.
+	 */
+	function errorCode() {
+		return ($this->_error_code);
+	}
+
+	/**
+	 * This method gives the latest error code name.
+	 *
+	 * @access public
+	 * @param  boolean $p_with_code  If true, gives the name and the int value.
+	 * @return string The error name.
+	 */
+	function errorName($p_with_code = false) {
+		$v_const_list = get_defined_constants();
+
+		// Extract error constants from all const.
+		for (reset($v_const_list);
+			list($v_key, $v_value) = each($v_const_list);) {
+			if (substr($v_key, 0, strlen('ARCHIVE_ZIP_ERR_')) == 'ARCHIVE_ZIP_ERR_') {
+				$v_error_list[$v_key] = $v_value;
+			}
+		}
+
+		// Search the name form the code value
+		$v_key = array_search($this->_error_code, $v_error_list, true);
+		if ($v_key != false) {
+			$v_value = $v_key;
+		} else {
+			$v_value = 'NoName';
+		}
+
+		if ($p_with_code) {
+			return ($v_value . ' (' . $this->_error_code . ')');
+		} else {
+			return ($v_value);
+		}
+	}
+
+	/**
+	 * This method returns the description associated with the latest error.
+	 *
+	 * @access public
+	 * @param  boolean $p_full If set to true gives the description with the
+	 *						 error code, the name and the description.
+	 *						 If set to false gives only the description
+	 *						 and the error code.
+	 * @return string The error description.
+	 */
+	function errorInfo($p_full = false) {
+		if ($p_full) {
+			return ($this->errorName(true) . " : " . $this->_error_string);
+		} else {
+			return ($this->_error_string . " [code " . $this->_error_code . "]");
+		}
+	}
+
+
+	/**
+	 * tx_em_Tools_Unzip::_checkFormat()
+	 *
+	 * { Description }
+	 *
+	 * @param integer $p_level
+	 */
+	function _checkFormat($p_level = 0) {
+		$v_result = true;
+
+		// Reset the error handler
+		$this->_errorReset();
+
+		// Look if the file exits
+		if (!is_file($this->_zipname)) {
+			// Error log
+			$this->_errorLog(ARCHIVE_ZIP_ERR_MISSING_FILE,
+					"Missing archive file '" . $this->_zipname . "'");
+			return (false);
+		}
+
+		// Check that the file is readeable
+		if (!is_readable($this->_zipname)) {
+			// Error log
+			$this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL,
+					"Unable to read archive '" . $this->_zipname . "'");
+			return (false);
+		}
+
+		// Check the magic code
+		// TBC
+
+		// Check the central header
+		// TBC
+
+		// Check each file header
+		// TBC
+
+		// Return
+		return $v_result;
+	}
+
+
+	/**
+	 * tx_em_Tools_Unzip::_openFd()
+	 *
+	 * { Description }
+	 *
+	 */
+	function _openFd($p_mode) {
+		$v_result = 1;
+
+		// Look if already open
+		if ($this->_zip_fd != 0) {
+			$this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL,
+					'Zip file \'' . $this->_zipname . '\' already open');
+			return tx_em_Tools_Unzip::errorCode();
+		}
+
+		// Open the zip file
+		if (($this->_zip_fd = @fopen($this->_zipname, $p_mode)) == 0) {
+			$this->_errorLog(ARCHIVE_ZIP_ERR_READ_OPEN_FAIL,
+					'Unable to open archive \'' . $this->_zipname
+							. '\' in ' . $p_mode . ' mode');
+			return tx_em_Tools_Unzip::errorCode();
+		}
+
+		// Return
+		return $v_result;
+	}
+
+	/**
+	 * tx_em_Tools_Unzip::_closeFd()
+	 *
+	 * { Description }
+	 *
+	 */
+	function _closeFd() {
+		$v_result = 1;
+
+		if ($this->_zip_fd != 0) {
+			@fclose($this->_zip_fd);
+		}
+		$this->_zip_fd = 0;
+
+		// Return
+		return $v_result;
+	}
+
+
+	/**
+	 * tx_em_Tools_Unzip::_convertHeader2FileInfo()
+	 *
+	 * { Description }
+	 *
+	 */
+	function _convertHeader2FileInfo($p_header, &$p_info) {
+		$v_result = 1;
+
+		// Get the interesting attributes
+		$p_info['filename'] = $p_header['filename'];
+		$p_info['stored_filename'] = $p_header['stored_filename'];
+		$p_info['size'] = $p_header['size'];
+		$p_info['compressed_size'] = $p_header['compressed_size'];
+		$p_info['mtime'] = $p_header['mtime'];
+		$p_info['comment'] = $p_header['comment'];
+		$p_info['folder'] = (($p_header['external'] & 0x00000010) == 0x00000010);
+		$p_info['index'] = $p_header['index'];
+		$p_info['status'] = $p_header['status'];
+
+		// Return
+		return $v_result;
+	}
+
+
+	// Function : _extractByRule()
+	// Description :
+	//   Extract a file or directory depending of rules (by index, by name, ...)
+	// Parameters :
+	//   $p_file_list : An array where will be placed the properties of each
+	//                  extracted file
+	//   $p_path : Path to add while writing the extracted files
+	//   $p_remove_path : Path to remove (from the file memorized path) while writing the
+	//                    extracted files. If the path does not match the file path,
+	//                    the file is extracted with its memorized path.
+	//                    $p_remove_path does not apply to 'list' mode.
+	//                    $p_path and $p_remove_path are commulative.
+	// Return Values :
+	//   1 on success,0 or less on error (see error code list)
+
+	/**
+	 * tx_em_Tools_Unzip::_extractByRule()
+	 *
+	 * { Description }
+	 *
+	 */
+	function _extractByRule(&$p_file_list, &$p_params) {
+		$v_result = 1;
+
+		$p_path = $p_params['add_path'];
+		$p_remove_path = $p_params['remove_path'];
+		$p_remove_all_path = $p_params['remove_all_path'];
+
+		// Check the path
+		if (($p_path == "")
+				|| ((substr($p_path, 0, 1) != "/")
+						&& (substr($p_path, 0, 3) != "../") && (substr($p_path, 1, 2) != ":/"))) {
+			$p_path = "./" . $p_path;
+		}
+
+		// Reduce the path last (and duplicated) '/'
+		if (($p_path != "./") && ($p_path != "/")) {
+			// Look for the path end '/'
+			while (substr($p_path, -1) == "/") {
+				$p_path = substr($p_path, 0, strlen($p_path) - 1);
+			}
+		}
+
+		// Open the zip file
+		if (($v_result = $this->_openFd('rb')) != 1) {
+			return $v_result;
+		}
+
+		// Read the central directory informations
+		$v_central_dir = array();
+		if (($v_result = $this->_readEndCentralDir($v_central_dir)) != 1) {
+			// Close the zip file
+			$this->_closeFd();
+
+			return $v_result;
+		}
+
+		// Start at beginning of Central Dir
+		$v_pos_entry = $v_central_dir['offset'];
+
+		// Read each entry
+		$j_start = 0;
+		for ($i = 0, $v_nb_extracted = 0; $i < $v_central_dir['entries']; $i++) {
+			// Read next Central dir entry
+			@rewind($this->_zip_fd);
+			if (@fseek($this->_zip_fd, $v_pos_entry)) {
+				$this->_closeFd();
+
+				$this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP,
+					'Invalid archive size');
+
+				return tx_em_Tools_Unzip::errorCode();
+			}
+
+			// Read the file header
+			$v_header = array();
+			if (($v_result = $this->_readCentralFileHeader($v_header)) != 1) {
+				$this->_closeFd();
+
+				return $v_result;
+			}
+
+			// Store the index
+			$v_header['index'] = $i;
+
+			// Store the file position
+			$v_pos_entry = ftell($this->_zip_fd);
+
+
+			// Go to the file position
+			@rewind($this->_zip_fd);
+			if (@fseek($this->_zip_fd, $v_header['offset'])) {
+				// Close the zip file
+				$this->_closeFd();
+
+				// Error log
+				$this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+				// Return
+				return tx_em_Tools_Unzip::errorCode();
+			}
+
+			// Extracting the file
+			if (($v_result = $this->_extractFile($v_header, $p_path, $p_remove_path, $p_remove_all_path, $p_params)) != 1) {
+				// Close the zip file
+				$this->_closeFd();
+
+				return $v_result;
+			}
+
+			// Get the only interesting attributes
+			if (($v_result = $this->_convertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
+				// Close the zip file
+				$this->_closeFd();
+
+				return $v_result;
+			}
+		}
+
+		// Close the zip file
+		$this->_closeFd();
+
+		// Return
+		return $v_result;
+	}
+
+	/**
+	 * tx_em_Tools_Unzip::_extractFile()
+	 *
+	 * { Description }
+	 *
+	 */
+	function _extractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_params) {
+		$v_result = 1;
+
+		// Read the file header
+		$v_header = '';
+		if (($v_result = $this->_readFileHeader($v_header)) != 1) {
+			// Return
+			return $v_result;
+		}
+
+
+		// Check that the file header is coherent with $p_entry info
+		// TBC
+
+		// Look for all path to remove
+		if ($p_remove_all_path == true) {
+			// Get the basename of the path
+			$p_entry['filename'] = basename($p_entry['filename']);
+		}
+
+			// Look for path to remove
+		else {
+			if ($p_remove_path != "") {
+				//if (strcmp($p_remove_path, $p_entry['filename'])==0)
+				if ($this->_tool_PathInclusion($p_remove_path, $p_entry['filename']) == 2) {
+
+					// Change the file status
+					$p_entry['status'] = "filtered";
+
+					// Return
+					return $v_result;
+				}
+
+				$p_remove_path_size = strlen($p_remove_path);
+				if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) {
+
+					// Remove the path
+					$p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
+
+				}
+			}
+		}
+
+		// Add the path
+		if ($p_path != '') {
+			$p_entry['filename'] = $p_path . "/" . $p_entry['filename'];
+		}
+
+		// Look for pre-extract callback
+		if ((isset($p_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT]))
+				&& ($p_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT] != '')) {
+
+			// Generate a local information
+			$v_local_header = array();
+			$this->_convertHeader2FileInfo($p_entry, $v_local_header);
+
+			// Call the callback
+			// Here I do not use call_user_func() because I need to send a reference to the
+			// header.
+			eval('$v_result = ' . $p_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT] . '(ARCHIVE_ZIP_PARAM_PRE_EXTRACT, $v_local_header);');
+			if ($v_result == 0) {
+				// Change the file status
+				$p_entry['status'] = "skipped";
+				$v_result = 1;
+			}
+
+			// Update the informations
+			// Only some fields can be modified
+			$p_entry['filename'] = $v_local_header['filename'];
+		}
+
+		// Trace
+
+		// Look if extraction should be done
+		if ($p_entry['status'] == 'ok') {
+
+			// Look for specific actions while the file exist
+			if (file_exists($p_entry['filename'])) {
+				// Look if file is a directory
+				if (is_dir($p_entry['filename'])) {
+					// Change the file status
+					$p_entry['status'] = "already_a_directory";
+
+					// Return
+					//return $v_result;
+				}
+					// Look if file is write protected
+				else {
+					if (!is_writeable($p_entry['filename'])) {
+						// Change the file status
+						$p_entry['status'] = "write_protected";
+
+						// Return
+						//return $v_result;
+					}
+
+						// Look if the extracted file is older
+					else {
+						if (filemtime($p_entry['filename']) > $p_entry['mtime']) {
+							// Change the file status
+							$p_entry['status'] = "newer_exist";
+
+							// Return
+							//return $v_result;
+						}
+					}
+				}
+			}
+
+				// Check the directory availability and create it if necessary
+			else {
+				if ((($p_entry['external'] & 0x00000010) == 0x00000010) || (substr($p_entry['filename'], -1) == '/')) {
+					$v_dir_to_check = $p_entry['filename'];
+				}
+				else {
+					if (!strstr($p_entry['filename'], "/")) {
+						$v_dir_to_check = "";
+					}
+					else
+					{
+						$v_dir_to_check = dirname($p_entry['filename']);
+					}
+				}
+
+				if (($v_result = $this->_dirCheck($v_dir_to_check, (($p_entry['external'] & 0x00000010) == 0x00000010))) != 1) {
+					// Change the file status
+					$p_entry['status'] = "path_creation_fail";
+
+					// Return
+					//return $v_result;
+					$v_result = 1;
+				}
+			}
+		}
+
+		// Look if extraction should be done
+		if ($p_entry['status'] == 'ok') {
+			// Do the extraction (if not a folder)
+			if (!(($p_entry['external'] & 0x00000010) == 0x00000010)) {
+				// Look for not compressed file
+				if ($p_entry['compressed_size'] == $p_entry['size']) {
+					// Opening destination file
+					if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
+						// Change the file status
+						$p_entry['status'] = "write_error";
+
+						// Return
+						return $v_result;
+					}
+
+
+					// Read the file by ARCHIVE_ZIP_READ_BLOCK_SIZE octets blocks
+					$v_size = $p_entry['compressed_size'];
+					while ($v_size != 0) {
+						$v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
+						$v_buffer = fread($this->_zip_fd, $v_read_size);
+						$v_binary_data = pack('a' . $v_read_size, $v_buffer);
+						@fwrite($v_dest_file, $v_binary_data, $v_read_size);
+						$v_size -= $v_read_size;
+					}
+
+					// Closing the destination file
+					fclose($v_dest_file);
+
+					// Change the file mtime
+					touch($p_entry['filename'], $p_entry['mtime']);
+				} else {
+					// Trace
+
+					// Opening destination file
+					if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
+
+						// Change the file status
+						$p_entry['status'] = "write_error";
+
+						return $v_result;
+					}
+
+
+					// Read the compressed file in a buffer (one shot)
+					$v_buffer = @fread($this->_zip_fd, $p_entry['compressed_size']);
+
+					// Decompress the file
+					$v_file_content = gzinflate($v_buffer);
+					unset($v_buffer);
+
+					// Write the uncompressed data
+					@fwrite($v_dest_file, $v_file_content, $p_entry['size']);
+					unset($v_file_content);
+
+					// Closing the destination file
+					@fclose($v_dest_file);
+
+					// Change the file mtime
+					@touch($p_entry['filename'], $p_entry['mtime']);
+				}
+
+				// Look for chmod option
+				if ((isset($p_params[ARCHIVE_ZIP_PARAM_SET_CHMOD]))
+						&& ($p_params[ARCHIVE_ZIP_PARAM_SET_CHMOD] != 0)) {
+
+					// Change the mode of the file
+					chmod($p_entry['filename'], $p_params[ARCHIVE_ZIP_PARAM_SET_CHMOD]);
+				}
+
+			}
+		}
+
+		// Look for post-extract callback
+		if ((isset($p_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT]))
+				&& ($p_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT] != '')) {
+
+			// Generate a local information
+			$v_local_header = array();
+			$this->_convertHeader2FileInfo($p_entry, $v_local_header);
+
+			// Call the callback
+			// Here I do not use call_user_func() because I need to send a reference to the
+			// header.
+			eval('$v_result = ' . $p_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT] . '(ARCHIVE_ZIP_PARAM_POST_EXTRACT, $v_local_header);');
+		}
+
+		// Return
+		return $v_result;
+	}
+
+	/**
+	 * tx_em_Tools_Unzip::_readFileHeader()
+	 *
+	 * { Description }
+	 *
+	 */
+	function _readFileHeader(&$p_header) {
+		$v_result = 1;
+
+		// Read the 4 bytes signature
+		$v_binary_data = @fread($this->_zip_fd, 4);
+		$v_data = unpack('Vid', $v_binary_data);
+
+		// Check signature
+		if ($v_data['id'] != 0x04034b50) {
+
+			// Error log
+			$this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
+
+			// Return
+			return tx_em_Tools_Unzip::errorCode();
+		}
+
+		// Read the first 42 bytes of the header
+		$v_binary_data = fread($this->_zip_fd, 26);
+
+		// Look for invalid block size
+		if (strlen($v_binary_data) != 26) {
+			$p_header['filename'] = "";
+			$p_header['status'] = "invalid_header";
+
+			// Error log
+			$this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, "Invalid block size : " . strlen($v_binary_data));
+
+			// Return
+			return tx_em_Tools_Unzip::errorCode();
+		}
+
+		// Extract the values
+		$v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
+
+		// Get filename
+		$p_header['filename'] = fread($this->_zip_fd, $v_data['filename_len']);
+
+		// Get extra_fields
+		if ($v_data['extra_len'] != 0) {
+			$p_header['extra'] = fread($this->_zip_fd, $v_data['extra_len']);
+		}
+		else {
+			$p_header['extra'] = '';
+		}
+
+		// Extract properties
+		$p_header['compression'] = $v_data['compression'];
+		$p_header['size'] = $v_data['size'];
+		$p_header['compressed_size'] = $v_data['compressed_size'];
+		$p_header['crc'] = $v_data['crc'];
+		$p_header['flag'] = $v_data['flag'];
+
+		// Recuperate date in UNIX format
+		$p_header['mdate'] = $v_data['mdate'];
+		$p_header['mtime'] = $v_data['mtime'];
+		if ($p_header['mdate'] && $p_header['mtime']) {
+			// Extract time
+			$v_hour = ($p_header['mtime'] & 0xF800) >> 11;
+			$v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
+			$v_seconde = ($p_header['mtime'] & 0x001F) * 2;
+
+			// Extract date
+			$v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
+			$v_month = ($p_header['mdate'] & 0x01E0) >> 5;
+			$v_day = $p_header['mdate'] & 0x001F;
+
+			// Get UNIX date format
+			$p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
+
+		} else {
+			$p_header['mtime'] = $GLOBALS['EXEC_TIME'];
+		}
+
+		// Other informations
+
+		// TBC
+		//for(reset($v_data); $key = key($v_data); next($v_data)) {
+		//}
+
+		// Set the stored filename
+		$p_header['stored_filename'] = $p_header['filename'];
+
+		// Set the status field
+		$p_header['status'] = "ok";
+
+		// Return
+		return $v_result;
+	}
+
+	/**
+	 * tx_em_Tools_Unzip::_readCentralFileHeader()
+	 *
+	 * { Description }
+	 *
+	 */
+	function _readCentralFileHeader(&$p_header) {
+		$v_result = 1;
+
+		// Read the 4 bytes signature
+		$v_binary_data = @fread($this->_zip_fd, 4);
+		$v_data = unpack('Vid', $v_binary_data);
+
+		// Check signature
+		if ($v_data['id'] != 0x02014b50) {
+
+			// Error log
+			$this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
+
+			// Return
+			return tx_em_Tools_Unzip::errorCode();
+		}
+
+		// Read the first 42 bytes of the header
+		$v_binary_data = fread($this->_zip_fd, 42);
+
+		// Look for invalid block size
+		if (strlen($v_binary_data) != 42) {
+			$p_header['filename'] = "";
+			$p_header['status'] = "invalid_header";
+
+			// Error log
+			$this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, "Invalid block size : " . strlen($v_binary_data));
+
+			// Return
+			return tx_em_Tools_Unzip::errorCode();
+		}
+
+		// Extract the values
+		$p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);
+
+		// Get filename
+		if ($p_header['filename_len'] != 0) {
+			$p_header['filename'] = fread($this->_zip_fd, $p_header['filename_len']);
+		}
+		else
+		{
+			$p_header['filename'] = '';
+		}
+
+		// Get extra
+		if ($p_header['extra_len'] != 0) {
+			$p_header['extra'] = fread($this->_zip_fd, $p_header['extra_len']);
+		}
+		else
+		{
+			$p_header['extra'] = '';
+		}
+
+		// Get comment
+		if ($p_header['comment_len'] != 0) {
+			$p_header['comment'] = fread($this->_zip_fd, $p_header['comment_len']);
+		}
+		else
+		{
+			$p_header['comment'] = '';
+		}
+
+		// Extract properties
+
+		// Recuperate date in UNIX format
+		if ($p_header['mdate'] && $p_header['mtime']) {
+			// Extract time
+			$v_hour = ($p_header['mtime'] & 0xF800) >> 11;
+			$v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
+			$v_seconde = ($p_header['mtime'] & 0x001F) * 2;
+
+			// Extract date
+			$v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
+			$v_month = ($p_header['mdate'] & 0x01E0) >> 5;
+			$v_day = $p_header['mdate'] & 0x001F;
+
+			// Get UNIX date format
+			$p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
+
+		} else {
+			$p_header['mtime'] = $GLOBALS['EXEC_TIME'];
+		}
+
+		// Set the stored filename
+		$p_header['stored_filename'] = $p_header['filename'];
+
+		// Set default status to ok
+		$p_header['status'] = 'ok';
+
+		// Look if it is a directory
+		if (substr($p_header['filename'], -1) == '/') {
+			$p_header['external'] = 0x41FF0010;
+		}
+
+
+		// Return
+		return $v_result;
+	}
+
+	/**
+	 * tx_em_Tools_Unzip::_readEndCentralDir()
+	 *
+	 * { Description }
+	 *
+	 */
+	function _readEndCentralDir(&$p_central_dir) {
+		$v_result = 1;
+
+		// Go to the end of the zip file
+		$v_size = filesize($this->_zipname);
+		@fseek($this->_zip_fd, $v_size);
+		if (@ftell($this->_zip_fd) != $v_size) {
+			$this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
+					'Unable to go to the end of the archive \''
+							. $this->_zipname . '\'');
+			return tx_em_Tools_Unzip::errorCode();
+		}
+
+		// First try : look if this is an archive with no commentaries
+		// (most of the time)
+		// in this case the end of central dir is at 22 bytes of the file end
+		$v_found = 0;
+		if ($v_size > 26) {
+			@fseek($this->_zip_fd, $v_size - 22);
+			if (($v_pos = @ftell($this->_zip_fd)) != ($v_size - 22)) {
+				$this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
+						'Unable to seek back to the middle of the archive \''
+								. $this->_zipname . '\'');
+				return tx_em_Tools_Unzip::errorCode();
+			}
+
+			// Read for bytes
+			$v_binary_data = @fread($this->_zip_fd, 4);
+			$v_data = unpack('Vid', $v_binary_data);
+
+			// Check signature
+			if ($v_data['id'] == 0x06054b50) {
+				$v_found = 1;
+			}
+
+			$v_pos = ftell($this->_zip_fd);
+		}
+
+		// Go back to the maximum possible size of the Central Dir End Record
+		if (!$v_found) {
+			$v_maximum_size = 65557; // 0xFFFF + 22;
+			if ($v_maximum_size > $v_size) {
+				$v_maximum_size = $v_size;
+			}
+			@fseek($this->_zip_fd, $v_size - $v_maximum_size);
+			if (@ftell($this->_zip_fd) != ($v_size - $v_maximum_size)) {
+				$this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
+						'Unable to seek back to the middle of the archive \''
+								. $this->_zipname . '\'');
+				return tx_em_Tools_Unzip::errorCode();
+			}
+
+			// Read byte per byte in order to find the signature
+			$v_pos = ftell($this->_zip_fd);
+			$v_bytes = 0x00000000;
+			while ($v_pos < $v_size) {
+				// Read a byte
+				$v_byte = @fread($this->_zip_fd, 1);
+
+				//  Add the byte
+				$v_bytes = ($v_bytes << 8) | Ord($v_byte);
+
+				// Compare the bytes
+				if ($v_bytes == 0x504b0506) {
+					$v_pos++;
+					break;
+				}
+
+				$v_pos++;
+			}
+
+			// Look if not found end of central dir
+			if ($v_pos == $v_size) {
+				$this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
+					"Unable to find End of Central Dir Record signature");
+				return tx_em_Tools_Unzip::errorCode();
+			}
+		}
+
+		// Read the first 18 bytes of the header
+		$v_binary_data = fread($this->_zip_fd, 18);
+
+		// Look for invalid block size
+		if (strlen($v_binary_data) != 18) {
+			$this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
+					"Invalid End of Central Dir Record size : "
+							. strlen($v_binary_data));
+			return tx_em_Tools_Unzip::errorCode();
+		}
+
+		// Extract the values
+		$v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
+
+		// Check the global size
+		if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
+			$this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT,
+				"Fail to find the right signature");
+			return tx_em_Tools_Unzip::errorCode();
+		}
+
+		// Get comment
+		if ($v_data['comment_size'] != 0) {
+			$p_central_dir['comment'] = fread($this->_zip_fd, $v_data['comment_size']);
+		}
+		else
+		{
+			$p_central_dir['comment'] = '';
+		}
+
+		$p_central_dir['entries'] = $v_data['entries'];
+		$p_central_dir['disk_entries'] = $v_data['disk_entries'];
+		$p_central_dir['offset'] = $v_data['offset'];
+		$p_central_dir['size'] = $v_data['size'];
+		$p_central_dir['disk'] = $v_data['disk'];
+		$p_central_dir['disk_start'] = $v_data['disk_start'];
+
+		// Return
+		return $v_result;
+	}
+
+	/**
+	 * tx_em_Tools_Unzip::_dirCheck()
+	 *
+	 * { Description }
+	 *
+	 * @param [type] $p_is_dir
+	 */
+	function _dirCheck($p_dir, $p_is_dir = false) {
+		$v_result = 1;
+
+		// Remove the final '/'
+		if (($p_is_dir) && (substr($p_dir, -1) == '/')) {
+			$p_dir = substr($p_dir, 0, strlen($p_dir) - 1);
+		}
+
+		// Check the directory availability
+		if ((is_dir($p_dir)) || ($p_dir == "")) {
+			return 1;
+		}
+
+		// Extract parent directory
+		$p_parent_dir = dirname($p_dir);
+
+		// Just a check
+		if ($p_parent_dir != $p_dir) {
+			// Look for parent directory
+			if ($p_parent_dir != "") {
+				if (($v_result = $this->_dirCheck($p_parent_dir)) != 1) {
+					return $v_result;
+				}
+			}
+		}
+
+		// Create the directory
+		if (!@mkdir($p_dir, 0777)) {
+			$this->_errorLog(ARCHIVE_ZIP_ERR_DIR_CREATE_FAIL,
+				"Unable to create directory '$p_dir'");
+			return tx_em_Tools_Unzip::errorCode();
+		}
+
+		// Return
+		return $v_result;
+	}
+
+	/**
+	 * tx_em_Tools_Unzip::_check_parameters()
+	 *
+	 * { Description }
+	 *
+	 * @param integer $p_error_code
+	 * @param string $p_error_string
+	 */
+	function _check_parameters(&$p_params, $p_default) {
+
+		// Check that param is an array
+		if (!is_array($p_params)) {
+			$this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER,
+				'Unsupported parameter, waiting for an array');
+			return tx_em_Tools_Unzip::errorCode();
+		}
+
+		// Check that all the params are valid
+		for (reset($p_params); list($v_key, $v_value) = each($p_params);) {
+			if (!isset($p_default[$v_key])) {
+				$this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAMETER,
+						'Unsupported parameter with key \'' . $v_key . '\'');
+
+				return tx_em_Tools_Unzip::errorCode();
+			}
+		}
+
+		// Set the default values
+		for (reset($p_default); list($v_key, $v_value) = each($p_default);) {
+			if (!isset($p_params[$v_key])) {
+				$p_params[$v_key] = $p_default[$v_key];
+			}
+		}
+
+		// Check specific parameters
+		$v_callback_list = array('callback_pre_add', 'callback_post_add',
+			'callback_pre_extract', 'callback_post_extract');
+		for ($i = 0; $i < sizeof($v_callback_list); $i++) {
+			$v_key = $v_callback_list[$i];
+			if ((isset($p_params[$v_key])) && ($p_params[$v_key] != '')) {
+				if (!function_exists($p_params[$v_key])) {
+					$this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_PARAM_VALUE,
+							"Callback '" . $p_params[$v_key]
+									. "()' is not an existing function for "
+									. "parameter '" . $v_key . "'");
+					return tx_em_Tools_Unzip::errorCode();
+				}
+			}
+		}
+
+		return (1);
+	}
+
+	/**
+	 * tx_em_Tools_Unzip::_errorLog()
+	 *
+	 * { Description }
+	 *
+	 * @param integer $p_error_code
+	 * @param string $p_error_string
+	 */
+	function _errorLog($p_error_code = 0, $p_error_string = '') {
+		$this->_error_code = $p_error_code;
+		$this->_error_string = $p_error_string;
+	}
+
+	/**
+	 * tx_em_Tools_Unzip::_errorReset()
+	 *
+	 * { Description }
+	 *
+	 */
+	function _errorReset() {
+		$this->_error_code = 1;
+		$this->_error_string = '';
+	}
+
+	/**
+	 * _tool_PathReduction()
+	 *
+	 * { Description }
+	 *
+	 */
+	function _tool_PathReduction($p_dir) {
+		$v_result = "";
+
+		// Look for not empty path
+		if ($p_dir != "") {
+			// Explode path by directory names
+			$v_list = explode("/", $p_dir);
+
+			// Study directories from last to first
+			for ($i = sizeof($v_list) - 1; $i >= 0; $i--) {
+				// Look for current path
+				if ($v_list[$i] == ".") {
+					// Ignore this directory
+					// Should be the first $i=0, but no check is done
+				} else {
+					if ($v_list[$i] == "..") {
+						// Ignore it and ignore the $i-1
+						$i--;
+					} else {
+						if (($v_list[$i] == "") && ($i != (sizeof($v_list) - 1)) && ($i != 0)) {
+							// Ignore only the double '//' in path,
+							// but not the first and last '/'
+						} else {
+							$v_result = $v_list[$i] . ($i != (sizeof($v_list) - 1) ? "/" . $v_result : "");
+						}
+					}
+				}
+			}
+		}
+
+		// Return
+		return $v_result;
+	}
+
+	/**
+	 * _tool_PathInclusion()
+	 *
+	 * { Description }
+	 *
+	 */
+	function _tool_PathInclusion($p_dir, $p_path) {
+		$v_result = 1;
+
+		// Explode dir and path by directory separator
+		$v_list_dir = explode("/", $p_dir);
+		$v_list_dir_size = sizeof($v_list_dir);
+		$v_list_path = explode("/", $p_path);
+		$v_list_path_size = sizeof($v_list_path);
+
+		// Study directories paths
+		$i = 0;
+		$j = 0;
+		while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
+			// Look for empty dir (path reduction)
+			if ($v_list_dir[$i] == '') {
+				$i++;
+				continue;
+			}
+			if ($v_list_path[$j] == '') {
+				$j++;
+				continue;
+			}
+
+			// Compare the items
+			if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ($v_list_path[$j] != '')) {
+				$v_result = 0;
+			}
+
+			// Next items
+			$i++;
+			$j++;
+		}
+
+		// Look if everything seems to be the same
+		if ($v_result) {
+			// Skip all the empty items
+			while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) {
+				$j++;
+			}
+			while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) {
+				$i++;
+			}
+
+			if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
+				// There are exactly the same
+				$v_result = 2;
+			} else {
+				if ($i < $v_list_dir_size) {
+					// The path is shorter than the dir
+					$v_result = 0;
+				}
+			}
+		}
+
+		// Return
+		return $v_result;
+	}
+
+	/**
+	 * _tool_CopyBlock()
+	 *
+	 * { Description }
+	 *
+	 * @param integer $p_mode
+	 */
+	function _tool_CopyBlock($p_src, $p_dest, $p_size, $p_mode = 0) {
+		$v_result = 1;
+
+		if ($p_mode == 0) {
+			while ($p_size != 0) {
+				$v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
+						? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
+				$v_buffer = @fread($p_src, $v_read_size);
+				@fwrite($p_dest, $v_buffer, $v_read_size);
+				$p_size -= $v_read_size;
+			}
+		} else {
+			if ($p_mode == 1) {
+				while ($p_size != 0) {
+					$v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
+							? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
+					$v_buffer = @gzread($p_src, $v_read_size);
+					@fwrite($p_dest, $v_buffer, $v_read_size);
+					$p_size -= $v_read_size;
+				}
+			} else {
+				if ($p_mode == 2) {
+					while ($p_size != 0) {
+						$v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
+								? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
+						$v_buffer = @fread($p_src, $v_read_size);
+						@gzwrite($p_dest, $v_buffer, $v_read_size);
+						$p_size -= $v_read_size;
+					}
+				}
+				else {
+					if ($p_mode == 3) {
+						while ($p_size != 0) {
+							$v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE
+									? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE);
+							$v_buffer = @gzread($p_src, $v_read_size);
+							@gzwrite($p_dest, $v_buffer, $v_read_size);
+							$p_size -= $v_read_size;
+						}
+					}
+				}
+			}
+		}
+
+		// Return
+		return $v_result;
+	}
+
+	/**
+	 * _tool_Rename()
+	 *
+	 * { Description }
+	 *
+	 */
+	function _tool_Rename($p_src, $p_dest) {
+		$v_result = 1;
+
+		// Try to rename the files
+		if (!@rename($p_src, $p_dest)) {
+
+			// Try to copy & unlink the src
+			if (!@copy($p_src, $p_dest)) {
+				$v_result = 0;
+			} else {
+				if (!@unlink($p_src)) {
+					$v_result = 0;
+				}
+			}
+		}
+
+		// Return
+		return $v_result;
+	}
+
+	/**
+	 * _tool_TranslateWinPath()
+	 *
+	 * { Description }
+	 *
+	 * @param [type] $p_remove_disk_letter
+	 */
+	function _tool_TranslateWinPath($p_path, $p_remove_disk_letter = true) {
+		if (stristr(php_uname(), 'windows')) {
+			// Look for potential disk letter
+			if (($p_remove_disk_letter)
+					&& (($v_position = strpos($p_path, ':')) != false)) {
+				$p_path = substr($p_path, $v_position + 1);
+			}
+			// Change potential windows directory separator
+			if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0, 1) == '\\')) {
+				$p_path = strtr($p_path, '\\', '/');
+			}
+		}
+		return $p_path;
+	}
+
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/parser/class.tx_em_parser_extensionxmlpushparser.php
===================================================================
--- typo3/sysext/em/classes/parser/class.tx_em_parser_extensionxmlpushparser.php	(revision )
+++ typo3/sysext/em/classes/parser/class.tx_em_parser_extensionxmlpushparser.php	(revision )
@@ -0,0 +1,245 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
+ *		   Steffen Kamper <info@sk-typo3.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * Module: Extension manager - Extension.xml push-parser
+ *
+ * $Id: class.tx_em_parser_extensionxmlpushparser.php 1913 2010-02-21 15:47:37Z mkrause $
+ */
+
+
+/**
+ * Parser for TYPO3's extension.xml file.
+ *
+ * Depends on PHP ext/xml which should be available
+ * with PHP 4+. This is the parser used in TYPO3
+ * Core <= 4.3 (without the "collect all data in one
+ * array" behaviour).
+ * Notice: ext/xml has proven to be buggy with entities.
+ * Use at least PHP 5.2.9+ and libxml2 2.7.3+!
+ *
+ * @author	  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author	  Steffen Kamper <info@sk-typo3.de>
+ *
+ * @since	   2010-02-10
+ * @package	 TYPO3
+ * @subpackage  EM
+ */
+class tx_em_Parser_ExtensionXmlPushParser extends tx_em_Parser_ExtensionXmlAbstractParser implements SplSubject {
+
+
+	/**
+	 * Keeps current element to process.
+	 *
+	 * @var  string
+	 */
+	protected $element = NULL;
+
+	/**
+	 * Class constructor.
+	 *
+	 * @return void
+	 */
+	function __construct() {
+		$this->requiredPHPExt = 'xml';
+
+		if ($this->isAvailable()) {
+			$this->objXML = xml_parser_create();
+			xml_set_object($this->objXML, $this);
+		}
+	}
+
+	/**
+	 * Method parses an extensions.xml file.
+	 *
+	 * @param   string  $file: GZIP stream resource
+	 * @return  void
+	 * @throws  tx_em_ExtensionXmlException  in case of XML parser errors
+	 */
+	public function parseXML($file) {
+
+		if (!is_resource($this->objXML)) {
+			$this->throwException('Unable to create XML parser.');
+		}
+		// keep original character case of XML document
+		xml_parser_set_option($this->objXML, XML_OPTION_CASE_FOLDING, FALSE);
+		xml_parser_set_option($this->objXML, XML_OPTION_SKIP_WHITE, FALSE);
+		xml_parser_set_option($this->objXML, XML_OPTION_TARGET_ENCODING, 'utf-8');
+		xml_set_element_handler($this->objXML, 'startElement', 'endElement');
+		xml_set_character_data_handler($this->objXML, 'characterData');
+
+		if (!($fp = fopen($file, "r"))) {
+			$this->throwException(sprintf('Unable to open file ressource %s.', htmlspecialchars($file)));
+		}
+		while ($data = fread($fp, 4096)) {
+			if (!xml_parse($this->objXML, $data, feof($fp))) {
+				$this->throwException(sprintf('XML error %s in line %u of file ressource %s.',
+					xml_error_string(xml_get_error_code($this->objXML)),
+					xml_get_current_line_number($this->objXML),
+					htmlspecialchars($file)));
+			}
+		}
+		xml_parser_free($this->objXML);
+	}
+
+	/**
+	 * Method is invoked when parser accesses start tag of an element.
+	 *
+	 * @param   ressource  $parser parser resource
+	 * @param   string	 $elementName: element name at parser's current position
+	 * @param   array	  $attrs: array of an element's attributes if available
+	 * @return  void
+	 */
+	protected function startElement($parser, $elementName, $attrs) {
+		switch ($elementName) {
+			case 'extension':
+				$this->extensionKey = $attrs['extensionkey'];
+				break;
+			case 'version':
+				$this->version = $attrs['version'];
+				break;
+			default:
+				$this->element = $elementName;
+		}
+	}
+
+	/**
+	 * Method is invoked when parser accesses end tag of an element.
+	 *
+	 * @param   ressource  $parser parser resource
+	 * @param   string	 $elementName: element name at parser's current position
+	 * @return  void
+	 */
+	protected function endElement($parser, $elementName) {
+		switch ($elementName) {
+			case 'extension':
+				$this->resetProperties(TRUE);
+				break;
+			case 'version':
+				$this->notify();
+				$this->resetProperties();
+				break;
+			default:
+				$this->element = NULL;
+		}
+	}
+
+	/**
+	 * Method is invoked when parser accesses any character other than elements.
+	 *
+	 * @param   ressource  $parser: parser ressource
+	 * @param   string	 $data: an element's value
+	 * @return  void
+	 */
+	protected function characterData($parser, $data) {
+		if (isset($this->element)) {
+			switch ($this->element) {
+				case 'downloadcounter':
+					// downloadcounter could be a child node of
+					// extension or version
+					if ($this->version == NULL) {
+						$this->extensionDLCounter = $data;
+					} else {
+						$this->versionDLCounter = $data;
+					}
+					break;
+				case 'title':
+					$this->title = $data;
+					break;
+				case 'description':
+					$this->description = $data;
+					break;
+				case 'state':
+					$this->state = $data;
+					break;
+				case 'reviewstate':
+					$this->reviewstate = $data;
+					break;
+				case 'category':
+					$this->category = $data;
+					break;
+				case 'lastuploaddate':
+					$this->lastuploaddate = $data;
+					break;
+				case 'uploadcomment':
+					$this->uploadcomment = $data;
+					break;
+				case 'dependencies':
+					$this->dependencies = $data;
+					break;
+				case 'authorname':
+					$this->authorname = $data;
+					break;
+				case 'authoremail':
+					$this->authoremail = $data;
+					break;
+				case 'authorcompany':
+					$this->authorcompany = $data;
+					break;
+				case 'ownerusername':
+					$this->ownerusername = $data;
+					break;
+				case 't3xfilemd5':
+					$this->t3xfilemd5 = $data;
+					break;
+			}
+		}
+	}
+
+	/**
+	 * Method attaches an observer.
+	 *
+	 * @param   SplObserver  $observer: an observer to attach
+	 * @return  void
+	 */
+	public function attach(SplObserver $observer) {
+		$this->observers[] = $observer;
+	}
+
+	/**
+	 * Method detaches an attached observer
+	 *
+	 * @param   SplObserver  $observer: an observer to detach
+	 * @return  void
+	 */
+	public function detach(SplObserver $observer) {
+		$key = array_search($observer, $this->observers, true);
+		if (!($key === false)) {
+			unset($this->observers[$key]);
+		}
+	}
+
+	/**
+	 * Method notifies attached observers.
+	 *
+	 * @return  void
+	 */
+	public function notify() {
+		foreach ($this->observers as $observer) {
+			$observer->update($this);
+		}
+	}
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/interfaces/interface.em_index_checkdatabaseupdateshook.php
===================================================================
--- typo3/sysext/em/interfaces/interface.em_index_checkdatabaseupdateshook.php	(revision 9241)
+++ typo3/sysext/em/interfaces/interface.tx_em_index_checkdatabaseupdateshook.php	(revision )
@@ -32,7 +32,7 @@
  * @package TYPO3
  * @subpackage em
  */
-interface em_index_checkDatabaseUpdatesHook {
+interface tx_em_Index_CheckDatabaseUpdatesHook {
 
 	/**
 	 * Hook that allows pre-processing of database structure modifications.
Index: typo3/sysext/em/classes/index.php
===================================================================
--- typo3/sysext/em/classes/index.php	(revision )
+++ typo3/sysext/em/classes/index.php	(revision )
@@ -0,0 +1,2676 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 1999-2010 Kasper Skårhøj (kasperYYYY@typo3.com)
+ *  (c) 2005-2010 Karsten Dambekalns <karsten@typo3.org>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * Module: Extension manager
+ *
+ * $Id: index.php 2083 2010-03-22 00:48:31Z steffenk $
+ *
+ * @author	Kasper Skårhøj <kasperYYYY@typo3.com>
+ * @author	Karsten Dambekalns <karsten@typo3.org>
+ * @author	Steffen Kamper <info@sk-typo3.de>
+ */
+
+$GLOBALS['LANG']->includeLLFile(t3lib_extMgm::extPath('em') . 'language/locallang.xml');
+
+// from tx_ter by Robert Lemke
+define('TX_TER_RESULT_EXTENSIONSUCCESSFULLYUPLOADED', '10504');
+
+define('EM_INSTALL_VERSION_MIN', 1);
+define('EM_INSTALL_VERSION_MAX', 2);
+define('EM_INSTALL_VERSION_STRICT', 3);
+
+unset($MCONF);
+require('conf.php');
+
+$BE_USER->modAccess($MCONF, 1);
+
+
+/**
+ * Module: Extension manager
+ *
+ * @author	Kasper Skårhøj <kasperYYYY@typo3.com>
+ * @author	Karsten Dambekalns <karsten@typo3.org>
+ * @package TYPO3
+ * @subpackage core
+ */
+class SC_mod_tools_em_index extends t3lib_SCbase {
+
+	// Internal, static:
+	var $versionDiffFactor = 1; // This means that version difference testing for import is detected for sub-versions only, not dev-versions. Default: 1000
+	var $systemInstall = 0; // If "1" then installs in the sysext directory is allowed. Default: 0
+	var $requiredExt = ''; // List of required extension (from TYPO3_CONF_VARS)
+	var $maxUploadSize = 31457280; // Max size in bytes of extension upload to repository
+	var $kbMax = 500; // Max size in kilobytes for files to be edited.
+	var $doPrintContent = true; // If set (default), the function printContent() will echo the content which was collected in $this->content. You can set this to FALSE in order to echo content from elsewhere, fx. when using outbut buffering
+	var $listingLimit = 500; // List that many extension maximally at one time (fixing memory problems)
+	var $listingLimitAuthor = 250; // List that many extension maximally at one time (fixing memory problems)
+	var $script = ''; //URL to this script
+
+
+	var $categories = array(); // Extension Categories (static var); see init()
+
+	var $states = array(); // Extension States; see init()
+
+	/**
+	 * Internal variable loaded with extension categories (for display/listing). Should reflect $categories above
+	 * Dynamic var.
+	 */
+	var $defaultCategories = array(
+		'cat' => array(
+		'be' => array(),
+		'module' => array(),
+		'fe' => array(),
+		'plugin' => array(),
+		'misc' => array(),
+		'services' => array(),
+		'templates' => array(),
+		'example' => array(),
+		'doc' => array()
+		)
+	);
+
+	/**
+	 * Colors for extension states
+	 */
+	var $stateColors = array(
+		'alpha' => '#d12438',
+		'beta' => '#97b17e',
+		'stable' => '#3bb65c',
+		'experimental' => '#007eba',
+		'test' => '#979797',
+		'obsolete' => '#000000',
+		'excludeFromUpdates' => '#cf7307'
+	);
+
+	/**
+	 * "TYPE" information; labels, paths, description etc. See init()
+	 */
+	var $typeLabels = array();
+	var $typeDescr = array();
+	var $typeBackPaths = array(); // Also static, set in init()
+
+	var $typeRelPaths = array(
+		'S' => 'sysext/',
+		'G' => 'ext/',
+		'L' => '../typo3conf/ext/',
+	);
+
+	var $detailCols = array(
+		0 => 2,
+		1 => 5,
+		2 => 6,
+		3 => 6,
+		4 => 4,
+		5 => 1
+	);
+
+	var $fe_user = array(
+		'username' => '',
+		'password' => '',
+	);
+
+	var $privacyNotice; // Set in init()
+	var $securityHint; // Set in init()
+	var $editTextExtensions = 'html,htm,txt,css,tmpl,inc,php,sql,conf,cnf,pl,pm,sh,xml,ChangeLog';
+	var $nameSpaceExceptions = 'beuser_tracking,design_components,impexp,static_file_edit,cms,freesite,quickhelp,classic_welcome,indexed_search,sys_action,sys_workflows,sys_todos,sys_messages,direct_mail,sys_stat,tt_address,tt_board,tt_calender,tt_guest,tt_links,tt_news,tt_poll,tt_rating,tt_products,setup,taskcenter,tsconfig_help,context_help,sys_note,tstemplate,lowlevel,install,belog,beuser,phpmyadmin,aboutmodules,imagelist,setup,taskcenter,sys_notepad,viewpage,adodb';
+
+
+	// Default variables for backend modules
+	var $MCONF = array(); // Module configuration
+	var $MOD_MENU = array(); // Module menu items
+	var $MOD_SETTINGS = array(); // Module session settings
+	/**
+	 * Document Template Object
+	 *
+	 * @var noDoc
+	 */
+	var $doc;
+	var $content; // Accumulated content
+
+	var $inst_keys = array(); // Storage of installed extensions
+	var $gzcompress = 0; // Is set true, if system support compression.
+
+	/**
+	 * instance of TER connection handler
+	 *
+	 * @var tx_em_Connection_Ter
+	 */
+	public $terConnection;
+
+	/**
+	 * Develop Module
+	 *
+	 * @var tx_em_Develop
+	 */
+	public $developModule;
+
+
+	/**
+	 * XML handling class for the TYPO3 Extension Manager
+	 *
+	 * @var tx_em_Tools_XmlHandler
+	 */
+	public $xmlhandler;
+
+
+	/**
+	 * Class for printing extension lists
+	 *
+	 * @var tx_em_Extensions_List
+	 */
+	public $extensionList;
+
+	/**
+	 * Class for extension details
+	 *
+	 * @var tx_em_Extensions_Details
+	 */
+	public $extensionDetails;
+
+	/**
+	 * Class for new ExtJs Extension Manager
+	 *
+	 * @var tx_em_ExtensionManager
+	 */
+	public $extensionmanager;
+
+	/**
+	 * Class for translation handling
+	 *
+	 * @var tx_em_Translations
+	 */
+	public $translations;
+
+	/**
+	 * Class for install extensions
+	 *
+	 * @var tx_em_Install
+	 */
+	public $install;
+
+
+	var $JScode; // JavaScript code to be forwared to $this->doc->JScode
+
+	// GPvars:
+	var $CMD = array(); // CMD array
+	var $listRemote; // If set, connects to remote repository
+	var $lookUpStr; // Search string when listing local extensions
+
+
+	/*********************************
+	 *
+	 * Standard module initialization
+	 *
+	 *********************************/
+
+	/**
+	 * Standard init function of a module.
+	 *
+	 * @return	void
+	 */
+	function init() {
+		global $BE_USER, $LANG, $BACK_PATH, $TYPO3_CONF_VARS;
+
+		/**
+		 * Extension Categories (static var)
+		 * Content must be redundant with the same internal variable as in class.tx_extrep.php!
+		 */
+		$this->categories = array(
+			'be' => $GLOBALS['LANG']->getLL('category_BE'),
+			'module' => $GLOBALS['LANG']->getLL('category_BE_modules'),
+			'fe' => $GLOBALS['LANG']->getLL('category_FE'),
+			'plugin' => $GLOBALS['LANG']->getLL('category_FE_plugins'),
+			'misc' => $GLOBALS['LANG']->getLL('category_miscellanous'),
+			'services' => $GLOBALS['LANG']->getLL('category_services'),
+			'templates' => $GLOBALS['LANG']->getLL('category_templates'),
+			'example' => $GLOBALS['LANG']->getLL('category_examples'),
+			'doc' => $GLOBALS['LANG']->getLL('category_documentation')
+		);
+
+		/**
+		 * Extension States
+		 * Content must be redundant with the same internal variable as in class.tx_extrep.php!
+		 */
+		$this->states = array(
+			'alpha' => $GLOBALS['LANG']->getLL('state_alpha'),
+			'beta' => $GLOBALS['LANG']->getLL('state_beta'),
+			'stable' => $GLOBALS['LANG']->getLL('state_stable'),
+			'experimental' => $GLOBALS['LANG']->getLL('state_experimental'),
+			'test' => $GLOBALS['LANG']->getLL('state_test'),
+			'obsolete' => $GLOBALS['LANG']->getLL('state_obsolete'),
+			'excludeFromUpdates' => $GLOBALS['LANG']->getLL('state_exclude_from_updates')
+		);
+
+		/**
+		 * "TYPE" information; labels, paths, description etc.
+		 */
+		$this->typeLabels = array(
+			'S' => $GLOBALS['LANG']->getLL('type_system'),
+			'G' => $GLOBALS['LANG']->getLL('type_global'),
+			'L' => $GLOBALS['LANG']->getLL('type_local'),
+		);
+		$this->typeDescr = array(
+			'S' => $GLOBALS['LANG']->getLL('descr_system'),
+			'G' => $GLOBALS['LANG']->getLL('descr_global'),
+			'L' => $GLOBALS['LANG']->getLL('descr_local'),
+		);
+
+
+		$this->typeBackPaths = array(
+			'S' => '../../../',
+			'G' => '../../../',
+			'L' => '../../../../' . TYPO3_mainDir
+		);
+
+		$this->script = 'mod.php?M=tools_em';
+		$this->privacyNotice = $GLOBALS['LANG']->getLL('privacy_notice');
+		$securityMessage = $GLOBALS['LANG']->getLL('security_warning_extensions') .
+				'<br /><br />' . sprintf($GLOBALS['LANG']->getLL('security_descr'),
+			'<a href="http://typo3.org/teams/security/" target="_blank">', '</a>'
+		);
+		$flashMessage = t3lib_div::makeInstance(
+			't3lib_FlashMessage',
+			$securityMessage,
+			$GLOBALS['LANG']->getLL('security_header'),
+			t3lib_FlashMessage::INFO
+		);
+		$this->securityHint = $flashMessage->render();
+
+		$this->excludeForPackaging = $GLOBALS['TYPO3_CONF_VARS']['EXT']['excludeForPackaging'];
+
+		// Setting module configuration:
+		$this->MCONF = $GLOBALS['MCONF'];
+
+		// Setting GPvars:
+		$this->CMD = is_array(t3lib_div::_GP('CMD')) ? t3lib_div::_GP('CMD') : array();
+		$this->lookUpStr = trim(t3lib_div::_GP('lookUp'));
+		$this->listRemote = t3lib_div::_GP('ter_connect');
+		$this->listRemote_search = trim(t3lib_div::_GP('ter_search'));
+
+		$this->settings = t3lib_div::makeInstance('tx_em_Settings');
+		$this->install = t3lib_div::makeInstance('tx_em_Install', $this);
+
+		// Configure menu
+		$this->menuConfig();
+
+		// Setting internal static:
+
+		$this->requiredExt = t3lib_div::trimExplode(',', $TYPO3_CONF_VARS['EXT']['requiredExt'], 1);
+
+		// Initialize Document Template object:
+		$this->doc = t3lib_div::makeInstance('template');
+		$this->doc->backPath = $BACK_PATH;
+		$this->doc->setModuleTemplate('templates/em_index.html');
+
+		// Initialize helper object
+		$this->terConnection = t3lib_div::makeInstance('tx_em_Connection_Ter', $this);
+		$this->terConnection->wsdlURL = $TYPO3_CONF_VARS['EXT']['em_wsdlURL'];
+
+		/* TODO: old class, will be removed */
+		$this->xmlhandler = t3lib_div::makeInstance('tx_em_Tools_XmlHandler');
+		$this->xmlhandler->emObj = $this;
+		$this->xmlhandler->useObsolete = $this->MOD_SETTINGS['display_obsolete'];
+
+/*
+		// Initialize develop module
+		$this->developModule = t3lib_div::makeInstance('tx_em_Develop', $this);
+		// Initialize newListing
+		$this->extensionmanager = t3lib_div::makeInstance('tx_em_ExtensionManager', $this);
+*/
+		// Output classes
+		$this->extensionList = t3lib_div::makeInstance('tx_em_Extensions_List', $this);
+		$this->extensionDetails = t3lib_div::makeInstance('tx_em_Extensions_Details', $this);
+		$this->translations = t3lib_div::makeInstance('tx_em_Translations', $this);
+
+
+		// the id is needed for getting same styles TODO: general table styles
+		$this->doc->bodyTagId = 'typo3-mod-tools-em-index-php';
+
+		// JavaScript
+		$this->doc->JScode = $this->doc->wrapScriptTags('
+			script_ended = 0;
+			function jumpToUrl(URL)	{	//
+				window.location.href = URL;
+			}
+		');
+
+		// Reload left frame menu
+		if ($this->CMD['refreshMenu']) {
+			$this->doc->JScode .= $this->doc->wrapScriptTags('
+				if(top.refreshMenu) {
+					top.refreshMenu();
+				} else {
+					top.TYPO3ModuleMenu.refreshMenu();
+				}
+			');
+		}
+
+
+		// Descriptions:
+		$this->descrTable = '_MOD_' . $this->MCONF['name'];
+		if ($BE_USER->uc['edit_showFieldHelp']) {
+			$LANG->loadSingleTableDescription($this->descrTable);
+		}
+
+		// Setting username/password etc. for upload-user:
+		$this->fe_user['username'] = $this->MOD_SETTINGS['fe_u'];
+		$this->fe_user['password'] = $this->MOD_SETTINGS['fe_p'];
+		parent::init();
+		$this->handleExternalFunctionValue('singleDetails');
+	}
+
+	/**
+	 * This function is a copy of the same function in t3lib_SCbase with one modification:
+	 * In contrast to t3lib_SCbase::handleExternalFunctionValue() this function merges the $this->extClassConf array
+	 * instead of overwriting it. That was necessary for including the Kickstarter as a submodule into the 'singleDetails'
+	 * selectorbox as well as in the main 'function' selectorbox.
+	 *
+	 * @param	string		Mod-setting array key
+	 * @param	string		Mod setting value, overriding the one in the key
+	 * @return	void
+	 * @see t3lib_SCbase::handleExternalFunctionValue()
+	 */
+	function handleExternalFunctionValue($MM_key = 'function', $MS_value = NULL) {
+		$MS_value = is_null($MS_value) ? $this->MOD_SETTINGS[$MM_key] : $MS_value;
+		$externalItems = $this->getExternalItemConfig($this->MCONF['name'], $MM_key, $MS_value);
+		if (is_array($externalItems)) {
+			$this->extClassConf = array_merge($externalItems, is_array($this->extClassConf) ? $this->extClassConf : array());
+		}
+		if (is_array($this->extClassConf) && $this->extClassConf['path']) {
+			$this->include_once[] = $this->extClassConf['path'];
+		}
+	}
+
+	/**
+	 * Configuration of which mod-menu items can be used
+	 *
+	 * @return	void
+	 */
+	function menuConfig() {
+			// MENU-ITEMS:
+		$this->MOD_MENU = $this->settings->MOD_MENU;
+
+		$this->MOD_MENU['singleDetails'] = $this->mergeExternalItems($this->MCONF['name'], 'singleDetails', $this->MOD_MENU['singleDetails']);
+
+			// temporary set main repository
+		//$changed = array_merge((array) t3lib_div::_GP('SET'), array('selectedRepository' => '1'));
+
+
+			// page/be_user TSconfig settings and blinding of menu-items
+		if (!$GLOBALS['BE_USER']->getTSConfigVal('mod.' . $this->MCONF['name'] . '.allowTVlisting')) {
+			unset($this->MOD_MENU['display_details'][3]);
+			unset($this->MOD_MENU['display_details'][4]);
+			unset($this->MOD_MENU['display_details'][5]);
+		}
+
+			// CLEANSE SETTINGS
+		$this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), $this->MCONF['name']);
+
+
+		if ($this->MOD_SETTINGS['function'] == 2) {
+			// If listing from online repository, certain items are removed though:
+			unset($this->MOD_MENU['listOrder']['type']);
+			unset($this->MOD_MENU['display_details'][2]);
+			unset($this->MOD_MENU['display_details'][3]);
+			unset($this->MOD_MENU['display_details'][4]);
+			unset($this->MOD_MENU['display_details'][5]);
+			$this->MOD_SETTINGS = t3lib_BEfunc::getModuleData($this->MOD_MENU, t3lib_div::_GP('SET'), $this->MCONF['name']);
+		}
+
+		$this->settings->saveSettings($this->MOD_SETTINGS);
+		parent::menuConfig();
+
+		$this->settings->saveSettings($this->MOD_SETTINGS);
+	}
+
+	/**
+	 * Main function for Extension Manager module.
+	 *
+	 * @return	void
+	 */
+	function main() {
+		global $BE_USER, $LANG, $TYPO3_CONF_VARS;
+
+		if (empty($this->MOD_SETTINGS['mirrorListURL'])) {
+			$this->MOD_SETTINGS['mirrorListURL'] = $TYPO3_CONF_VARS['EXT']['em_mirrorListURL'];
+		}
+
+		// Starting page:
+		$this->content .= $this->doc->header($GLOBALS['LANG']->getLL('header'));
+
+		// Command given which is executed regardless of main menu setting:
+		if ($this->CMD['showExt']) { // Show details for a single extension
+			$this->showExtDetails($this->CMD['showExt']);
+		} elseif ($this->CMD['requestInstallExtensions']) { // Show details for a single extension
+			$this->requestInstallExtensions($this->CMD['requestInstallExtensions']);
+		} elseif ($this->CMD['importExt'] || $this->CMD['uploadExt']) { // Imports an extension from online rep.
+			$err = $this->importExtFromRep($this->CMD['importExt'], $this->CMD['extVersion'], $this->CMD['loc'], $this->CMD['uploadExt']);
+			if ($err) {
+				$this->content .= $this->doc->section('', $GLOBALS['TBE_TEMPLATE']->rfw($err));
+			}
+			if (!$err && $this->CMD['importExt']) {
+				$this->translations->installTranslationsForExtension($this->CMD['importExt'], $this->getMirrorURL());
+			}
+		} elseif ($this->CMD['importExtInfo']) { // Gets detailed information of an extension from online rep.
+			$this->importExtInfo($this->CMD['importExtInfo'], $this->CMD['extVersion']);
+		} else { // No command - we show what the menu setting tells us:
+			if (t3lib_div::inList('loaded_list,installed_list,import', $this->MOD_SETTINGS['function'])) {
+				$menu .= '&nbsp;' . $GLOBALS['LANG']->getLL('group_by') . '&nbsp;' . t3lib_BEfunc::getFuncMenu(0, 'SET[listOrder]', $this->MOD_SETTINGS['listOrder'], $this->MOD_MENU['listOrder']) .
+					'&nbsp;&nbsp;' . $GLOBALS['LANG']->getLL('show') . '&nbsp;' . t3lib_BEfunc::getFuncMenu(0, 'SET[display_details]', $this->MOD_SETTINGS['display_details'], $this->MOD_MENU['display_details']) . '<br />';
+			}
+			if (t3lib_div::inList('loaded_list,installed_list,updates', $this->MOD_SETTINGS['function'])) {
+				$menu .= '<label for="checkDisplayShy">' . $GLOBALS['LANG']->getLL('display_shy') . '</label>&nbsp;&nbsp;' . t3lib_BEfunc::getFuncCheck(0, 'SET[display_shy]', $this->MOD_SETTINGS['display_shy'], '', '', 'id="checkDisplayShy"');
+			}
+			if (t3lib_div::inList('import', $this->MOD_SETTINGS['function']) && strlen($this->fe_user['username'])) {
+				$menu .= '<label for="checkDisplayOwn">' . $GLOBALS['LANG']->getLL('only_my_ext') . '</label>&nbsp;&nbsp;' . t3lib_BEfunc::getFuncCheck(0, 'SET[display_own]', $this->MOD_SETTINGS['display_own'], '', '', 'id="checkDisplayOwn"');
+			}
+			if (t3lib_div::inList('loaded_list,installed_list,import', $this->MOD_SETTINGS['function'])) {
+				$menu .= '&nbsp;&nbsp;<label for="checkDisplayObsolete">' . $GLOBALS['LANG']->getLL('show_obsolete') . '</label>&nbsp;&nbsp;' . t3lib_BEfunc::getFuncCheck(0, 'SET[display_obsolete]', $this->MOD_SETTINGS['display_obsolete'], '', '', 'id="checkDisplayObsolete"');
+			}
+
+			$this->content .= $menu ? $this->doc->section('', '<form action="' . $this->script . '" method="post" name="pageform"><span class="nobr">' . $menu . '</span></form>') : '';
+
+			switch ($this->MOD_SETTINGS['function']) {
+				case 'loaded_list':
+					// Lists loaded (installed) extensions
+					$headline = $GLOBALS['LANG']->getLL('loaded_exts');
+					$headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'loaded', $headline);
+					$content = $this->extensionList->extensionList_loaded();
+
+					$this->content .= $this->doc->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
+					break;
+				case 'installed_list':
+					// Lists the installed (available) extensions
+					$headline = sprintf($GLOBALS['LANG']->getLL('available_extensions'), $this->MOD_MENU['listOrder'][$this->MOD_SETTINGS['listOrder']]);
+					$headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'avail', $headline);
+					$content = $this->extensionList->extensionList_installed();
+
+					$this->content .= $this->doc->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
+					break;
+				case 'import':
+					// Lists the extensions available from online rep.
+					$this->extensionList_import();
+					break;
+				case 'settings':
+					// Shows the settings screen
+					$headline = $GLOBALS['LANG']->getLL('repository_settings');
+					$headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'settings', $headline);
+					$content = $this->alterSettings();
+
+					$this->content .= $this->doc->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
+					break;
+				case 'translations':
+					// Allows to set the translation preferences and check the status
+					$this->translations->translationHandling();
+					break;
+				case 'updates':
+					// Shows a list of extensions with updates in TER
+					$this->checkForUpdates();
+					break;
+				case 'develop':
+					$this->content .= $this->developModule->renderModule();
+					break;
+				default:
+				case 'extensionmanager':
+					$this->content .= $this->extensionmanager->render();
+					break;
+				default:
+					$this->extObjContent();
+					break;
+			}
+		}
+
+			// closing any form?
+		$formTags = substr_count($this->content, '<form') + substr_count($this->content, '</form');
+		if ($formTags % 2 > 0) {
+			$this->content .= '</form>';
+		}
+
+		// Setting up the buttons and markers for docheader
+		$docHeaderButtons = $this->getButtons();
+		$markers = array(
+			'CSH' => $docHeaderButtons['csh'],
+			'FUNC_MENU' => $this->getFuncMenu(),
+			'CONTENT' => $this->content
+		);
+
+		// Build the <body> for the module
+		$this->content = $this->doc->startPage('Extension Manager');
+		$this->content .= $this->doc->moduleBody($this->pageinfo, $docHeaderButtons, $markers);
+		$this->content .= $this->doc->endPage();
+		$this->content = $this->doc->insertStylesAndJS($this->content);
+	}
+
+	/**
+	 * Print module content. Called as last thing in the global scope.
+	 *
+	 * @return	void
+	 */
+	function printContent() {
+		if ($this->doPrintContent) {
+			echo $this->content;
+		}
+	}
+
+	/**
+	 * Create the function menu
+	 *
+	 * @return	string	HTML of the function menu
+	 */
+	public function getFuncMenu() {
+		$funcMenu = '';
+		if (!$this->CMD['showExt'] && !$this->CMD['requestInstallExtensions'] && !$this->CMD['importExt'] && !$this->CMD['uploadExt'] && !$this->CMD['importExtInfo']) {
+			$funcMenu = t3lib_BEfunc::getFuncMenu(0, 'SET[function]', $this->MOD_SETTINGS['function'], $this->MOD_MENU['function']);
+		} elseif ($this->CMD['showExt'] && (!$this->CMD['standAlone'] && !t3lib_div::_GP('standAlone'))) {
+			$funcMenu = t3lib_BEfunc::getFuncMenu(0, 'SET[singleDetails]', $this->MOD_SETTINGS['singleDetails'], $this->MOD_MENU['singleDetails'], '', '&CMD[showExt]=' . $this->CMD['showExt']);
+		}
+		return $funcMenu;
+	}
+
+	/**
+	 * Create the panel of buttons for submitting the form or otherwise perform operations.
+	 *
+	 * @return	array	all available buttons as an assoc. array
+	 */
+	public function getButtons() {
+
+		$buttons = array(
+			'csh' => '',
+			'back' => '',
+			'shortcut' => ''
+		);
+
+		// Shortcut
+		if ($GLOBALS['BE_USER']->mayMakeShortcut()) {
+			$buttons['shortcut'] = $this->doc->makeShortcutIcon('CMD', 'function', $this->MCONF['name']);
+		}
+		// Back
+		if (($this->CMD['showExt'] && (!$this->CMD['standAlone'] && !t3lib_div::_GP('standAlone'))) || ($this->CMD['importExt'] || $this->CMD['uploadExt'] && (!$this->CMD['standAlone'])) || $this->CMD['importExtInfo']) {
+			$buttons['back'] = '<a href="' . t3lib_div::linkThisScript(array(
+				'CMD' => ''
+			)) . '" class="typo3-goBack" title="' . $GLOBALS['LANG']->getLL('go_back') . '">' .
+					t3lib_iconWorks::getSpriteIcon('actions-view-go-back') .
+					'</a>';
+		}
+
+		return $buttons;
+	}
+
+
+	/*********************************
+	 *
+	 * Function Menu Applications
+	 *
+	 *********************************/
+
+
+	/**
+	 * Listing remote extensions from online repository
+	 *
+	 * @return	void
+	 */
+	function extensionList_import() {
+		global $TYPO3_LOADED_EXT;
+		$content = '';
+
+		// Listing from online repository:
+		if ($this->listRemote) {
+			list($inst_list,) = $this->extensionList->getInstalledExtensions();
+			$this->inst_keys = array_flip(array_keys($inst_list));
+
+			$this->detailCols[1] += 6;
+
+			// see if we have an extensionlist at all
+			$this->extensionCount = $this->xmlhandler->countExtensions();
+			if (!$this->extensionCount) {
+				$content .= $this->fetchMetaData('extensions');
+			}
+
+			if ($this->MOD_SETTINGS['listOrder'] == 'author_company') {
+				$this->listingLimit = $this->listingLimitAuthor;
+			}
+
+			$this->pointer = intval(t3lib_div::_GP('pointer'));
+			$offset = $this->listingLimit * $this->pointer;
+
+			if ($this->MOD_SETTINGS['display_own'] && strlen($this->fe_user['username'])) {
+				$this->xmlhandler->searchExtensionsXML($this->listRemote_search, $this->fe_user['username'], $this->MOD_SETTINGS['listOrder'], TRUE);
+			} else {
+				$this->xmlhandler->searchExtensionsXML($this->listRemote_search, '', $this->MOD_SETTINGS['listOrder'], TRUE, FALSE, $offset, $this->listingLimit);
+			}
+			if (count($this->xmlhandler->extensionsXML)) {
+				list($list, $cat) = $this->extensionList->prepareImportExtList(true);
+
+				// Available extensions
+				if (is_array($cat[$this->MOD_SETTINGS['listOrder']])) {
+					$lines = array();
+					$lines[] = $this->extensionList->extensionListRowHeader(' class="t3-row-header"', array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>'), 1);
+
+					foreach ($cat[$this->MOD_SETTINGS['listOrder']] as $catName => $extEkeys) {
+						if (count($extEkeys)) {
+							$lines[] = '<tr><td colspan="' . (3 + $this->detailCols[$this->MOD_SETTINGS['display_details']]) . '"><br /></td></tr>';
+							$lines[] = '<tr><td colspan="' . (3 + $this->detailCols[$this->MOD_SETTINGS['display_details']]) . '">' . t3lib_iconWorks::getSpriteIcon('apps-filetree-folder-default') . '<strong>' . htmlspecialchars($this->listOrderTitle($this->MOD_SETTINGS['listOrder'], $catName)) . '</strong></td></tr>';
+							natcasesort($extEkeys);
+							foreach ($extEkeys as $extKey => $value) {
+								$version = array_keys($list[$extKey]['versions']);
+								$version = end($version);
+								$ext = $list[$extKey]['versions'][$version];
+								$ext['downloadcounter_all'] = $list[$extKey]['downloadcounter'];
+								$ext['_ICON'] = $list[$extKey]['_ICON'];
+								$loadUnloadLink = '';
+								if ($inst_list[$extKey]['type'] != 'S' && (!isset($inst_list[$extKey]) || tx_em_Tools::versionDifference($version, $inst_list[$extKey]['EM_CONF']['version'], $this->versionDiffFactor))) {
+									if (isset($inst_list[$extKey])) {
+										// update
+										if ($inst_list[$extKey]['EM_CONF']['state'] != 'excludeFromUpdates') {
+											$loc = ($inst_list[$extKey]['type'] == 'G' ? 'G' : 'L');
+											$aUrl = t3lib_div::linkThisScript(array(
+												'CMD[importExt]' => $extKey,
+												'CMD[extVersion]' => $version,
+												'CMD[loc]' => $loc
+											));
+											$loadUnloadLink .= '<a href="' . htmlspecialchars($aUrl) . '" title="' . sprintf($GLOBALS['LANG']->getLL('do_update'), ($loc == 'G' ? $GLOBALS['LANG']->getLL('global') : $GLOBALS['LANG']->getLL('local'))) . '">' .
+													t3lib_iconWorks::getSpriteIcon('actions-system-extension-update') .
+													'</a>';
+										} else {
+											// extension is marked as "excludeFromUpdates"
+											$loadUnloadLink .= t3lib_iconWorks::getSpriteIcon('status-dialog-warning', $GLOBALS['LANG']->getLL('excluded_from_updates'));
+										}
+									} else {
+										// import
+										$aUrl = t3lib_div::linkThisScript(array(
+											'CMD[importExt]' => $extKey,
+											'CMD[extVersion]' => $version,
+											'CMD[loc]' => 'L'
+										));
+										$loadUnloadLink .= '<a href="' . htmlspecialchars($aUrl) . '" title="' . $GLOBALS['LANG']->getLL('import_to_local_dir') . '">' . t3lib_iconWorks::getSpriteIcon('actions-system-extension-import') . '</a>';
+									}
+								} else {
+									$loadUnloadLink = '&nbsp;';
+								}
+
+								if (isset($inst_list[$extKey])) {
+									$theRowClass = t3lib_extMgm::isLoaded($extKey) ? 'em-listbg1' : 'em-listbg2';
+								} else {
+									$theRowClass = 'em-listbg3';
+								}
+
+								$lines[] = $this->extensionList->extensionListRow(
+									$extKey, $ext, array(
+									'<td class="bgColor">' . $loadUnloadLink . '</td>'
+								), $theRowClass, $inst_list, 1, t3lib_div::linkThisScript(array(
+									'CMD[importExtInfo]' => rawurlencode($extKey)
+								)));
+								unset($list[$extKey]);
+							}
+						}
+					}
+					unset($list);
+
+					// headline and CSH
+					$headline = $GLOBALS['LANG']->getLL('extensions_repository_group_by') . ' ' .
+							$this->MOD_MENU['listOrder'][$this->MOD_SETTINGS['listOrder']];
+					$headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'import_ter', $headline);
+
+					$onsubmit = "window.location.href='" . $this->script . "&ter_connect=1&ter_search='+escape(this.elements['lookUp'].value);return false;";
+					$content .= '<form action="' . $this->script . '" method="post" onsubmit="' . htmlspecialchars($onsubmit) .
+							'"><label for="lookUp">' . $GLOBALS['LANG']->getLL('list_or_look_up_extensions') . '</label><br />
+							<input type="text" id="lookUp" name="lookUp" value="' . htmlspecialchars($this->listRemote_search) .
+							'" /> <input type="submit" value="' . $GLOBALS['LANG']->getLL('look_up_button') . '" /></form><br /><br />';
+
+					$content .= $this->browseLinks();
+
+					$content .= '
+
+					<!-- TER Extensions list -->
+					<table border="0" cellpadding="2" cellspacing="1">' . implode(LF, $lines) . '</table>';
+					$content .= '<br />' . $this->browseLinks();
+					$content .= '<br /><br />' . $this->securityHint;
+					$content .= '<br /><br /><strong>' . $GLOBALS['LANG']->getLL('privacy_notice_header') .
+							'</strong><br /> ' . $this->privacyNotice;
+
+					$this->content .= $this->doc->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
+
+					// Plugins which are NOT uploaded to repository but present on this server.
+					$content = '';
+					$lines = array();
+					if (count($this->inst_keys)) {
+						foreach ($this->inst_keys as $extKey => $value) {
+							$this->xmlhandler->searchExtensionsXMLExact($extKey, '', '', TRUE, TRUE);
+							if ((strlen($this->listRemote_search) && !stristr($extKey, $this->listRemote_search)) || isset($this->xmlhandler->extensionsXML[$extKey])) {
+								continue;
+							}
+
+							$loadUnloadLink = t3lib_extMgm::isLoaded($extKey) ?
+									'<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
+										'CMD[showExt]' => $extKey,
+										'CMD[remove]' => 1,
+										'CMD[clrCmd]' => 1,
+										'SET[singleDetails]' => 'info'
+									))) . '">' . tx_em_Tools::removeButton() . '</a>' :
+									'<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
+										'CMD[showExt]' => $extKey,
+										'CMD[load]' => 1,
+										'CMD[clrCmd]' => 1,
+										'SET[singleDetails]' => 'info'
+									))) . '">' . tx_em_Tools::installButton() . '</a>';
+							if (in_array($extKey, $this->requiredExt)) {
+								$loadUnloadLink = '<strong>' . $GLOBALS['TBE_TEMPLATE']->rfw($GLOBALS['LANG']->getLL('extension_required_short')) . '</strong>';
+							}
+							$lines[] = $this->extensionList->extensionListRow($extKey, $inst_list[$extKey], array('<td class="bgColor">' . $loadUnloadLink . '</td>'), t3lib_extMgm::isLoaded($extKey) ? 'em-listbg1' : 'em-listbg2');
+						}
+					}
+					if (count($lines)) {
+						$content .= $GLOBALS['LANG']->getLL('list_of_local_extensions') .
+								'<br />' . $GLOBALS['LANG']->getLL('might_be_user_defined') . '<br /><br />';
+						$content .= '<table border="0" cellpadding="2" cellspacing="1">' .
+								$this->extensionList->extensionListRowHeader(' class="t3-row-header"', array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>')) .
+								implode('', $lines) . '</table>';
+						$this->content .= $this->doc->spacer(20);
+						$this->content .= $this->doc->section($GLOBALS['LANG']->getLL('only_on_this_server'), $content, 0, 1);
+					}
+				}
+			} else {
+				// headline and CSH
+				$headline = $GLOBALS['LANG']->getLL('extensions_repository_group_by') . ' ' .
+						$this->MOD_MENU['listOrder'][$this->MOD_SETTINGS['listOrder']];
+				$headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'import_ter', $headline);
+
+				$onsubmit = "window.location.href='" . $this->script . "&ter_connect=1&ter_search='+escape(this.elements['lookUp'].value);return false;";
+				$content .= '<form action="' . $this->script . '" method="post" onsubmit="' . htmlspecialchars($onsubmit) .
+						'"><label for="lookUp">' .
+						$GLOBALS['LANG']->getLL('list_or_look_up_extensions') . '</label><br />
+					<input type="text" id="lookUp" name="lookUp" value="' . htmlspecialchars($this->listRemote_search) .
+						'" /> <input type="submit" value="' . $GLOBALS['LANG']->getLL('look_up_button') . '" /></form><br /><br />';
+
+				$content .= '<p><strong>' . $GLOBALS['LANG']->getLL('no_matching_extensions') . '</strong></p>';
+
+				$content .= '<br /><br /><strong>' . $GLOBALS['LANG']->getLL('privacy_notice_header') .
+						'</strong><br /> ' . $this->privacyNotice;
+				$this->content .= $this->doc->section($headline, $content, FALSE, TRUE);
+			}
+		} else {
+			// section headline and CSH
+			$headline = $GLOBALS['LANG']->getLL('in_repository');
+			$headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'import', $headline);
+
+			$onsubmit = "window.location.href='" . $this->script . "&ter_connect=1&ter_search='+escape(this.elements['lookUp'].value);return false;";
+			$content .= '<form action="' . $this->script . '" method="post" onsubmit="' . htmlspecialchars($onsubmit) .
+					'"><label for="lookUp">' .
+					$GLOBALS['LANG']->getLL('list_or_look_up_extensions') . '</label><br />
+				<input type="text" id="lookUp" name="lookUp" value="" /> <input type="submit" value="' .
+					$GLOBALS['LANG']->getLL('look_up_button') . '" /><br /><br />';
+
+			if ($this->CMD['fetchMetaData']) { // fetches mirror/extension data from online rep.
+				$content .= $this->fetchMetaData($this->CMD['fetchMetaData']);
+			} else {
+				$onCLick = 'window.location.href="' . t3lib_div::linkThisScript(array(
+					'CMD[fetchMetaData]' => 'extensions'
+				)) . '";return false;';
+				$content .= $GLOBALS['LANG']->getLL('connect_to_ter') . '<br />
+					<input type="submit" value="' . $GLOBALS['LANG']->getLL('retrieve_update') .
+						'" onclick="' . htmlspecialchars($onCLick) . '" />';
+				if (is_file(PATH_site . 'typo3temp/extensions.xml.gz')) {
+					$dateFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'];
+					$timeFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'];
+					$content .= ' ' . sprintf($GLOBALS['LANG']->getLL('ext_list_last_updated') . ' ',
+						date(
+							$dateFormat . ', ' . $timeFormat,
+							filemtime(PATH_site . 'typo3temp/extensions.xml.gz')
+						),
+						tx_em_Database::getExtensionCountFromRepository()
+					);
+				}
+			}
+			$content .= '</form><br /><br />' . $this->securityHint;
+			$content .= '<br /><br /><strong>' . $GLOBALS['LANG']->getLL('privacy_notice_header') .
+					'</strong><br />' . $this->privacyNotice;
+
+			$this->content .= $this->doc->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
+		}
+
+		// Upload:
+		if ($this->importAtAll()) {
+			$content = '<form action="' . $this->script . '" enctype="' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'] . '" method="post">
+			<label for="upload_ext_file">' . $GLOBALS['LANG']->getLL('upload_t3x') . '</label><br />
+				<input type="file" size="60" id="upload_ext_file" name="upload_ext_file" /><br />' .
+					$GLOBALS['LANG']->getLL('upload_to_location') . '<br />
+				<select name="CMD[loc]">';
+			if (tx_em_Tools::importAsType('L')) {
+				$content .= '<option value="L">' . $GLOBALS['LANG']->getLL('local_folder') . '</option>';
+			}
+			if (tx_em_Tools::importAsType('G')) {
+				$content .= '<option value="G">' . $GLOBALS['LANG']->getLL('global_folder') . '</option>';
+			}
+			if (tx_em_Tools::importAsType('S')) {
+				$content .= '<option value="S">' . $GLOBALS['LANG']->getLL('system_folder') . '</option>';
+			}
+			$content .= '</select><br />
+	<input type="checkbox" value="1" name="CMD[uploadOverwrite]" id="checkUploadOverwrite" /> <label for="checkUploadOverwrite">' .
+					$GLOBALS['LANG']->getLL('overwrite_ext') . '</label><br />
+	<input type="submit" name="CMD[uploadExt]" value="' . $GLOBALS['LANG']->getLL('upload_ext_file') . '" /></form><br />
+			';
+		} else {
+			$content = tx_em_Tools::noImportMsg();
+		}
+
+		$this->content .= $this->doc->spacer(20);
+		$this->content .= $this->doc->section($GLOBALS['LANG']->getLL('upload_ext_directly'), $content, 0, 1);
+	}
+
+	/**
+	 * Generates a link to the next page of extensions
+	 *
+	 * @return	void
+	 */
+	function browseLinks() {
+		$content = '';
+		if ($this->pointer) {
+			$content .= '<a href="' . t3lib_div::linkThisScript(array('pointer' => $this->pointer - 1)) .
+					'" class="typo3-prevPage"><img' . t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],
+				'gfx/pilleft_n.gif', 'width="14" height="14"') .
+					' alt="' . $GLOBALS['LANG']->getLL('previous_page') . '" /> ' .
+					$GLOBALS['LANG']->getLL('previous_page') . '</a>';
+		}
+		if ($content) {
+			$content .= '&nbsp;&nbsp;&nbsp;';
+		}
+		if (intval($this->xmlhandler->matchingCount / $this->listingLimit) > $this->pointer) {
+			$content .= '<a href="' . t3lib_div::linkThisScript(array('pointer' => $this->pointer + 1)) .
+					'" class="typo3-nextPage"><img' . t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],
+				'gfx/pilright_n.gif', 'width="14" height="14"') .
+					' alt="' . $GLOBALS['LANG']->getLL('next_page') . '" /> ' .
+					$GLOBALS['LANG']->getLL('next_page') . '</a>';
+		}
+		$upper = (($this->pointer + 1) * $this->listingLimit);
+		if ($upper > $this->xmlhandler->matchingCount) {
+			$upper = $this->xmlhandler->matchingCount;
+		}
+		if ($content) {
+			$content .= '<br /><br />' .
+					sprintf($GLOBALS['LANG']->getLL('showing_extensions_from_to'),
+							'<strong>' . ($this->pointer * $this->listingLimit + 1) . '</strong>',
+							'<strong>' . $upper . '</strong>'
+					);
+		}
+		if ($content) {
+			$content .= '<br /><br />';
+		}
+		return $content;
+	}
+
+	/**
+	 * Allows changing of settings
+	 *
+	 * @return	void
+	 */
+	function alterSettings() {
+
+		// Prepare the HTML output:
+		$content .= '
+			<form action="' . $this->script . '" method="post" name="altersettings">
+			<fieldset><legend>' . $GLOBALS['LANG']->getLL('user_settings') . '</legend>
+			<table border="0" cellpadding="2" cellspacing="2">
+				<tr class="bgColor4">
+					<td><label for="set_fe_u">' . $GLOBALS['LANG']->getLL('enter_repository_username') . '</label></td>
+					<td><input type="text" id="set_fe_u" name="SET[fe_u]" value="' . htmlspecialchars($this->MOD_SETTINGS['fe_u']) . '" /></td>
+				</tr>
+				<tr class="bgColor4">
+					<td><label for="set_fe_p">' . $GLOBALS['LANG']->getLL('enter_repository_password') . '</label></td>
+					<td><input type="password" id="set_fe_p" name="SET[fe_p]" value="' . htmlspecialchars($this->MOD_SETTINGS['fe_p']) . '" /></td>
+				</tr>
+			</table>
+			<strong>' . $GLOBALS['LANG']->getLL('notice') . '</strong> ' .
+				$GLOBALS['LANG']->getLL('repository_password_info') . '
+			</fieldset>
+			<br />
+			<br />
+			<fieldset><legend>' . $GLOBALS['LANG']->getLL('mirror_selection') . '</legend>
+			<table border="0" cellpadding="2" cellspacing="2">
+				<tr class="bgColor4">
+					<td><label for="set_mirror_list_url">' . $GLOBALS['LANG']->getLL('mirror_list_url') . '</label></td>
+					<td><input type="text" size="50" id="set_mirror_list_url" name="SET[mirrorListURL]" value="' . htmlspecialchars($this->MOD_SETTINGS['mirrorListURL']) . '" /></td>
+				</tr>
+			</table>
+			</fieldset>
+			<br />
+			<p>' . $GLOBALS['LANG']->getLL('mirror_select') . '<br /><br /></p>
+			<fieldset><legend>' . $GLOBALS['LANG']->getLL('mirror_list') . '</legend>';
+		if (!empty($this->MOD_SETTINGS['mirrorListURL'])) {
+			if ($this->CMD['fetchMetaData']) { // fetches mirror/extension data from online rep.
+				$content .= $this->fetchMetaData($this->CMD['fetchMetaData']);
+			} else {
+				$content .= '<a href="' . t3lib_div::linkThisScript(array(
+					'CMD[fetchMetaData]' => 'mirrors'
+				)) . '">' . $GLOBALS['LANG']->getLL('mirror_list_reload') . '</a>';
+			}
+		}
+		$content .= '<br />
+			<table cellspacing="4" style="text-align:left; vertical-alignment:top;">
+			<tr>
+				<td>' . $GLOBALS['LANG']->getLL('mirror_use') . '</td>
+				<td>' . $GLOBALS['LANG']->getLL('mirror_name') . '</td>
+				<td>' . $GLOBALS['LANG']->getLL('mirror_url') . '</td>
+				<td>' . $GLOBALS['LANG']->getLL('mirror_country') . '</td>
+				<td>' . $GLOBALS['LANG']->getLL('mirror_sponsored_by') . '</td>
+			</tr>
+		';
+
+		if (!strlen($this->MOD_SETTINGS['extMirrors'])) {
+			$this->fetchMetaData('mirrors');
+		}
+		$extMirrors = unserialize($this->MOD_SETTINGS['extMirrors']);
+		$extMirrors[''] = array('title' => $GLOBALS['LANG']->getLL('mirror_use_random'));
+		ksort($extMirrors);
+		if (is_array($extMirrors)) {
+			foreach ($extMirrors as $k => $v) {
+				if (isset($v['sponsor'])) {
+					$sponsor = '<a href="' . htmlspecialchars($v['sponsor']['link']) . '" target="_blank"><img src="' . $v['sponsor']['logo'] . '" title="' . htmlspecialchars($v['sponsor']['name']) . '" alt="' . htmlspecialchars($v['sponsor']['name']) . '" /></a>';
+				}
+				$selected = ($this->MOD_SETTINGS['selectedMirror'] == $k) ? 'checked="checked"' : '';
+				$content .= '<tr class="bgColor4">
+			<td><input type="radio" name="SET[selectedMirror]" id="selectedMirror' . $k . '" value="' . $k . '" ' . $selected . '/></td><td><label for="selectedMirror' . $k . '">' . htmlspecialchars($v['title']) . '</label></td><td>' . htmlspecialchars($v['host'] . $v['path']) . '</td><td>' . $v['country'] . '</td><td>' . $sponsor . '</td></tr>';
+			}
+		}
+		$content .= '
+			</table>
+			</fieldset>
+			<fieldset>
+			<br />
+			<table border="0" cellpadding="2" cellspacing="2">
+				<tr class="bgColor4">
+					<td><label for="set_rep_url">' . $GLOBALS['LANG']->getLL('enter_repository_url') . '</label></td>
+					<td><input type="text" size="50" id="set_rep_url" name="SET[rep_url]" value="' . htmlspecialchars($this->MOD_SETTINGS['rep_url']) . '" /></td>
+				</tr>
+			</table>
+
+			' . $GLOBALS['LANG']->getLL('repository_url_hint') . '<br />
+			</fieldset>
+			<br />
+			<input type="submit" value="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_tsfe.xml:update') . '" />
+			</form>
+		';
+
+		return $content;
+	}
+
+	/**
+	 * Allows to set the translation preferences and check the status
+	 *
+	 * @return	void
+	 */
+
+
+	/*********************************
+	 *
+	 * Command Applications (triggered by GET var)
+	 *
+	 *********************************/
+
+	/**
+	 * Returns detailed info about an extension in the online repository
+	 *
+	 * @param	string		Extension repository uid + optional "private key": [uid]-[key].
+	 * @param	[type]		$version: ...
+	 * @return	void
+	 */
+	function importExtInfo($extKey, $version = '') {
+
+		$content = '<form action="' . $this->script . '" method="post" name="pageform">';
+
+		// Fetch remote data:
+		$this->xmlhandler->searchExtensionsXMLExact($extKey, '', '', true, true);
+		list($fetchData,) = $this->extensionList->prepareImportExtList(true);
+
+		$versions = array_keys($fetchData[$extKey]['versions']);
+		natsort($versions);
+		$version = ($version == '') ? end($versions) : $version;
+
+		$opt = array();
+		foreach ($versions as $ver) {
+			$opt[] = '<option value="' . $ver . '"' . (($version == $ver) ? ' selected="selected"' : '') . '>' . $ver . '</option>';
+		}
+
+		// "Select version" box:
+		$onClick = 'window.location.href="' . $this->script . '&CMD[importExtInfo]=' . $extKey . '&CMD[extVersion]="+document.pageform.extVersion.options[document.pageform.extVersion.selectedIndex].value; return false;';
+		$select = '<select name="extVersion">' . implode('', $opt) .
+				'</select> <input type="submit" value="' . $GLOBALS['LANG']->getLL('ext_load_details_button') .
+				'" onclick="' . htmlspecialchars($onClick) . '" />';
+
+		if ($this->importAtAll()) {
+			// Check for write-protected extension
+			list($inst_list,) = $this->extensionList->getInstalledExtensions();
+			if ($inst_list[$extKey]['EM_CONF']['state'] != 'excludeFromUpdates') {
+				$onClick = '
+						window.location.href="' . $this->script . '&CMD[importExt]=' . $extKey . '"
+							+"&CMD[extVersion]="+document.pageform.extVersion.options[document.pageform.extVersion.selectedIndex].value
+							+"&CMD[loc]="+document.pageform.loc.options[document.pageform.loc.selectedIndex].value;
+							return false;';
+				$select .= ' ' . $GLOBALS['LANG']->getLL('ext_or') . '<br /><br />
+					<input type="submit" value="' . $GLOBALS['LANG']->getLL('ext_import_update_button') .
+						'" onclick="' . htmlspecialchars($onClick) . '" /> ' . $GLOBALS['LANG']->getLL('ext_import_update_to') . '
+					<select name="loc">' .
+						(tx_em_Tools::importAsType('G', $fetchData['emconf_lockType']) ?
+								'<option value="G">' . $GLOBALS['LANG']->getLL('ext_import_global') . ' ' . tx_em_Tools::typePath('G') . $extKey . '/' .
+										(@is_dir(tx_em_Tools::typePath('G') . $extKey) ?
+												' ' . $GLOBALS['LANG']->getLL('ext_import_overwrite') :
+												' ' . $GLOBALS['LANG']->getLL('ext_import_folder_empty')
+										) . '</option>' : ''
+						) .
+						(tx_em_Tools::importAsType('L', $fetchData['emconf_lockType']) ?
+								'<option value="L">' . $GLOBALS['LANG']->getLL('ext_import_local') . ' ' . tx_em_Tools::typePath('L') . $extKey . '/' .
+										(@is_dir(tx_em_Tools::typePath('L') . $extKey) ?
+												' ' . $GLOBALS['LANG']->getLL('ext_import_overwrite') :
+												' ' . $GLOBALS['LANG']->getLL('ext_import_folder_empty')
+										) . '</option>' : ''
+						) .
+						(tx_em_Tools::importAsType('S', $fetchData['emconf_lockType']) ?
+								'<option value="S">' . $GLOBALS['LANG']->getLL('ext_import_system') . ' ' . tx_em_Tools::typePath('S') . $extKey . '/' .
+										(@is_dir(tx_em_Tools::typePath('S') . $extKey) ?
+												' ' . $GLOBALS['LANG']->getLL('ext_import_overwrite') :
+												' ' . $GLOBALS['LANG']->getLL('ext_import_folder_empty')
+										) . '</option>' : ''
+						) .
+						'</select>
+					</form>';
+			} else {
+				$select .= '<br /><br />' . $GLOBALS['LANG']->getLL('ext_import_excluded_from_updates');
+			}
+		} else {
+			$select .= '<br /><br />' . tx_em_Tools::noImportMsg();
+		}
+		$content .= $select;
+		$this->content .= $this->doc->section($GLOBALS['LANG']->getLL('ext_import_select_command'), $content, 0, 1);
+
+		// Details:
+		$eInfo = $fetchData[$extKey]['versions'][$version];
+		$content = '<strong>' . $fetchData[$extKey]['_ICON'] . ' &nbsp;' . $eInfo['EM_CONF']['title'] . ' (' . $extKey . ', ' . $version . ')</strong><br /><br />';
+		$content .= $this->extensionDetails->extInformationarray($extKey, $eInfo, 1);
+		$this->content .= $this->doc->spacer(10);
+		$this->content .= $this->doc->section($GLOBALS['LANG']->getLL('ext_import_remote_ext_details'), $content, 0, 1);
+	}
+
+	/**
+	 * Fetches metadata and stores it to the corresponding place. This includes the mirror list,
+	 * extension XML files.
+	 *
+	 * @param	string		Type of data to fetch: (mirrors)
+	 * @param	boolean		If true the method doesn't produce any output
+	 * @return	void
+	 */
+	function fetchMetaData($metaType) {
+		global $TYPO3_CONF_VARS;
+
+		switch ($metaType) {
+			case 'mirrors':
+				$mfile = t3lib_div::tempnam('mirrors');
+				$mirrorsFile = t3lib_div::getURL($this->MOD_SETTINGS['mirrorListURL'], 0, array(TYPO3_user_agent));
+				if ($mirrorsFile===false) {
+					t3lib_div::unlink_tempfile($mfile);
+					$content = '<p>' .
+							sprintf($GLOBALS['LANG']->getLL('ext_import_list_not_updated'),
+								$this->MOD_SETTINGS['mirrorListURL']
+							) . ' ' .
+							$GLOBALS['LANG']->getLL('translation_problems') . '</p>';
+				} else {
+					t3lib_div::writeFile($mfile, $mirrorsFile);
+					$mirrors = implode('', gzfile($mfile));
+					t3lib_div::unlink_tempfile($mfile);
+
+					$mirrors = $this->xmlhandler->parseMirrorsXML($mirrors);
+					if (is_array($mirrors) && count($mirrors)) {
+						t3lib_BEfunc::getModuleData($this->MOD_MENU, array('extMirrors' => serialize($mirrors)), $this->MCONF['name'], '', 'extMirrors');
+						$this->MOD_SETTINGS['extMirrors'] = serialize($mirrors);
+						$content = '<p>' .
+								sprintf($GLOBALS['LANG']->getLL('ext_import_list_updated'),
+									count($mirrors)
+								) . '</p>';
+					}
+					else {
+						$content = '<p>' . $mirrors . '<br />' . $GLOBALS['LANG']->getLL('ext_import_list_empty') . '</p>';
+					}
+				}
+				break;
+			case 'extensions':
+				$this->fetchMetaData('mirrors'); // if we fetch the extensions anyway, we can as well keep this up-to-date
+
+				$mirror = $this->getMirrorURL();
+				$extfile = $mirror . 'extensions.xml.gz';
+				$extmd5 = t3lib_div::getURL($mirror . 'extensions.md5', 0, array(TYPO3_user_agent));
+				if (is_file(PATH_site . 'typo3temp/extensions.xml.gz')) {
+					$localmd5 = md5_file(PATH_site . 'typo3temp/extensions.xml.gz');
+				}
+
+				// count cached extensions. If cache is empty re-fill it
+				$cacheCount = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('extkey', 'cache_extensions');
+
+				if ($extmd5 === false) {
+					$content .= '<p>' .
+							sprintf($GLOBALS['LANG']->getLL('ext_import_md5_not_updated'),
+									$mirror . 'extensions.md5'
+							) .
+							$GLOBALS['LANG']->getLL('translation_problems') . '</p>';
+				} elseif ($extmd5 == $localmd5 && $cacheCount) {
+					$flashMessage = t3lib_div::makeInstance(
+						't3lib_FlashMessage',
+						$GLOBALS['LANG']->getLL('ext_import_list_unchanged'),
+						$GLOBALS['LANG']->getLL('ext_import_list_unchanged_header'),
+						t3lib_FlashMessage::INFO
+					);
+					$content .= $flashMessage->render();
+				} else {
+					$extXML = t3lib_div::getURL($extfile, 0, array(TYPO3_user_agent));
+					if ($extXML === false) {
+						$content .= '<p>' .
+								sprintf($GLOBALS['LANG']->getLL('ext_import_list_unchanged'),
+									$extfile
+								) . ' ' .
+								$GLOBALS['LANG']->getLL('translation_problems') . '</p>';
+					} else {
+						t3lib_div::writeFile(PATH_site . 'typo3temp/extensions.xml.gz', $extXML);
+						$content .= $this->xmlhandler->parseExtensionsXML(PATH_site . 'typo3temp/extensions.xml.gz');
+					}
+				}
+				break;
+		}
+
+		return $content;
+	}
+
+	/**
+	 * Returns the base URL for the slected or a random mirror.
+	 *
+	 * @return	string		The URL for the selected or a random mirror
+	 */
+	function getMirrorURL() {
+		if (strlen($this->MOD_SETTINGS['rep_url'])) {
+			return $this->MOD_SETTINGS['rep_url'];
+		}
+
+		$mirrors = unserialize($this->MOD_SETTINGS['extMirrors']);
+		if (!is_array($mirrors)) {
+			$this->fetchMetaData('mirrors');
+			$mirrors = unserialize($this->MOD_SETTINGS['extMirrors']);
+			if (!is_array($mirrors)) {
+				return false;
+			}
+		}
+		if ($this->MOD_SETTINGS['selectedMirror'] == '') {
+			$rand = array_rand($mirrors);
+			$url = 'http://' . $mirrors[$rand]['host'] . $mirrors[$rand]['path'];
+		}
+		else {
+			$url = 'http://' . $mirrors[$this->MOD_SETTINGS['selectedMirror']]['host'] . $mirrors[$this->MOD_SETTINGS['selectedMirror']]['path'];
+		}
+
+		return $url;
+	}
+
+
+	/**
+	 * Installs (activates) an extension
+	 *
+	 * For $mode use the three constants EM_INSTALL_VERSION_MIN, EM_INSTALL_VERSION_MAX, EM_INSTALL_VERSION_STRICT
+	 *
+	 * If an extension is loaded or imported already and the version requirement is matched, it will not be
+	 * fetched from the repository. This means, if you use EM_INSTALL_VERSION_MIN, you will not always get the latest
+	 * version of an extension!
+	 *
+	 * @param	string		$extKey	The extension key to install
+	 * @param	string		$version	A version number that should be installed
+	 * @param	int		$mode	If a version is requested, this determines if it is the min, max or strict version requested
+	 * @return	[type]		...
+	 * @todo Make the method able to handle needed interaction somehow (unmatched dependencies)
+	 */
+	function installExtension($extKey, $version = null, $mode = EM_INSTALL_VERSION_MIN) {
+		list($inst_list,) = $this->extensionList->getInstalledExtensions();
+
+		// check if it is already installed and loaded with sufficient version
+		if (isset($inst_list[$extKey])) {
+			$currentVersion = $inst_list[$extKey]['EM_CONF']['version'];
+
+			if (t3lib_extMgm::isLoaded($extKey)) {
+				if ($version===null) {
+					return array(true, $GLOBALS['LANG']->getLL('ext_import_ext_already_installed_loaded'));
+				} else {
+					switch ($mode) {
+						case EM_INSTALL_VERSION_STRICT:
+							if ($currentVersion == $version) {
+								return array(true, $GLOBALS['LANG']->getLL('ext_import_ext_already_installed_loaded'));
+							}
+							break;
+						case EM_INSTALL_VERSION_MIN:
+							if (version_compare($currentVersion, $version, '>=')) {
+								return array(true, $GLOBALS['LANG']->getLL('ext_import_ext_already_installed_loaded'));
+							}
+							break;
+						case EM_INSTALL_VERSION_MAX:
+							if (version_compare($currentVersion, $version, '<=')) {
+								return array(true, $GLOBALS['LANG']->getLL('ext_import_ext_already_installed_loaded'));
+							}
+							break;
+					}
+				}
+			} else {
+				if (!t3lib_extMgm::isLocalconfWritable()) {
+					return array(false, $GLOBALS['LANG']->getLL('ext_import_p_localconf'));
+				}
+				$newExtList = -1;
+				switch ($mode) {
+					case EM_INSTALL_VERSION_STRICT:
+						if ($currentVersion == $version) {
+							$newExtList = $this->extensionList->addExtToList($extKey, $inst_list);
+						}
+						break;
+					case EM_INSTALL_VERSION_MIN:
+						if (version_compare($currentVersion, $version, '>=')) {
+							$newExtList = $this->extensionList->addExtToList($extKey, $inst_list);
+						}
+						break;
+					case EM_INSTALL_VERSION_MAX:
+						if (version_compare($currentVersion, $version, '<=')) {
+							$newExtList = $this->extensionList->addExtToList($extKey, $inst_list);
+						}
+						break;
+				}
+				if ($newExtList != -1) {
+					$this->writeNewExtensionList($newExtList);
+					$this->refreshGlobalExtList();
+					$this->forceDBupdates($extKey, $inst_list[$extKey]);
+					return array(true, $GLOBALS['LANG']->getLL('ext_import_ext_loaded'));
+				}
+			}
+		}
+
+		// at this point we know we need to import (a matching version of) the extension from TER2
+
+		// see if we have an extension list at all
+		if (!$this->xmlhandler->countExtensions()) {
+			$this->fetchMetaData('extensions');
+		}
+		$this->xmlhandler->searchExtensionsXMLExact($extKey, '', '', true);
+
+		// check if extension can be fetched
+		if (isset($this->xmlhandler->extensionsXML[$extKey])) {
+			$versions = array_keys($this->xmlhandler->extensionsXML[$extKey]['versions']);
+			$latestVersion = end($versions);
+			switch ($mode) {
+				case EM_INSTALL_VERSION_STRICT:
+					if (!isset($this->xmlhandler->extensionsXML[$extKey]['versions'][$version])) {
+						return array(false, $GLOBALS['LANG']->getLL('ext_import_ext_n_a'));
+					}
+					break;
+				case EM_INSTALL_VERSION_MIN:
+					if (version_compare($latestVersion, $version, '>=')) {
+						$version = $latestVersion;
+					} else {
+						return array(false, $GLOBALS['LANG']->getLL('ext_import_ext_n_a'));
+					}
+					break;
+				case EM_INSTALL_VERSION_MAX:
+					while (($v = array_pop($versions)) && version_compare($v, $version, '>=')) {
+						// Loop until a version is found
+					}
+
+					if ($v !== null && version_compare($v, $version, '<=')) {
+						$version = $v;
+					} else {
+						return array(false, $GLOBALS['LANG']->getLL('ext_import_ext_n_a'));
+					}
+					break;
+			}
+			$this->importExtFromRep($extKey, $version, 'L');
+			$newExtList = $this->extensionList->addExtToList($extKey, $inst_list);
+			if ($newExtList != -1) {
+				$this->writeNewExtensionList($newExtList);
+				$this->refreshGlobalExtList();
+				$this->forceDBupdates($extKey, $inst_list[$extKey]);
+				$this->translations->installTranslationsForExtension($extKey, $this->getMirrorURL());
+				return array(true, $GLOBALS['LANG']->getLL('ext_import_ext_imported'));
+			} else {
+				return array(false, $GLOBALS['LANG']->getLL('ext_import_ext_not_loaded'));
+			}
+		} else {
+			return array(false, $GLOBALS['LANG']->getLL('ext_import_ext_n_a_rep'));
+		}
+	}
+
+	function refreshGlobalExtList() {
+		global $TYPO3_LOADED_EXT;
+
+		$TYPO3_LOADED_EXT = t3lib_extMgm::typo3_loadExtensions();
+		if ($TYPO3_LOADED_EXT['_CACHEFILE']) {
+			require(PATH_typo3conf . $TYPO3_LOADED_EXT['_CACHEFILE'] . '_ext_localconf.php');
+		}
+		return;
+
+		$GLOBALS['TYPO3_LOADED_EXT'] = t3lib_extMgm::typo3_loadExtensions();
+		if ($TYPO3_LOADED_EXT['_CACHEFILE']) {
+			require(PATH_typo3conf . $TYPO3_LOADED_EXT['_CACHEFILE'] . '_ext_localconf.php');
+		} else {
+			$temp_TYPO3_LOADED_EXT = $TYPO3_LOADED_EXT;
+			foreach ($temp_TYPO3_LOADED_EXT as $_EXTKEY => $temp_lEDat) {
+				if (is_array($temp_lEDat) && $temp_lEDat['ext_localconf.php']) {
+					$_EXTCONF = $GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][$_EXTKEY];
+					require($temp_lEDat['ext_localconf.php']);
+				}
+			}
+		}
+	}
+
+
+	/**
+	 * Imports an extensions from the online repository
+	 * NOTICE: in version 4.0 this changed from "importExtFromRep_old($extRepUid,$loc,$uploadFlag=0,$directInput='',$recentTranslations=0,$incManual=0,$dontDelete=0)"
+	 *
+	 * @param	string		Extension key
+	 * @param	string		Version
+	 * @param	string		Install scope: "L" or "G" or "S"
+	 * @param	boolean		If true, extension is uploaded as file
+	 * @param	boolean		If true, extension directory+files will not be deleted before writing the new ones. That way custom files stored in the extension folder will be kept.
+	 * @param	array		Direct input array (like from kickstarter)
+	 * @return	string		Return false on success, returns error message if error.
+	 */
+	function importExtFromRep($extKey, $version, $loc, $uploadFlag = 0, $dontDelete = 0, $directInput = '') {
+
+		$uploadSucceed = false;
+		$uploadedTempFile = '';
+		if (is_array($directInput)) {
+			$fetchData = array($directInput, '');
+			$loc = ($loc==='G' || $loc==='S') ? $loc : 'L';
+		} elseif ($uploadFlag) {
+			if (($uploadedTempFile = $this->CMD['alreadyUploaded']) || $_FILES['upload_ext_file']['tmp_name']) {
+
+				// Read uploaded file:
+				if (!$uploadedTempFile) {
+					if (!is_uploaded_file($_FILES['upload_ext_file']['tmp_name'])) {
+						t3lib_div::sysLog('Possible file upload attack: ' . $_FILES['upload_ext_file']['tmp_name'], 'Extension Manager', 3);
+
+						return $GLOBALS['LANG']->getLL('ext_import_file_not_uploaded');
+					}
+
+					$uploadedTempFile = t3lib_div::upload_to_tempfile($_FILES['upload_ext_file']['tmp_name']);
+				}
+				$fileContent = t3lib_div::getUrl($uploadedTempFile);
+
+				if (!$fileContent) {
+					return $GLOBALS['LANG']->getLL('ext_import_file_empty');
+				}
+
+				// Decode file data:
+				$fetchData = $this->terConnection->decodeExchangeData($fileContent);
+
+				if (is_array($fetchData)) {
+					$extKey = $fetchData[0]['extKey'];
+					if ($extKey) {
+						if (!$this->CMD['uploadOverwrite']) {
+							$loc = ($loc==='G' || $loc==='S') ? $loc : 'L';
+							$comingExtPath = tx_em_Tools::typePath($loc) . $extKey . '/';
+							if (@is_dir($comingExtPath)) {
+								$flashMessage = t3lib_div::makeInstance(
+									't3lib_FlashMessage',
+										sprintf($GLOBALS['LANG']->getLL('ext_import_ext_present_no_overwrite'), $comingExtPath) .
+												'<br />' . $GLOBALS['LANG']->getLL('ext_import_ext_present_nothing_done'),
+									'',
+									t3lib_FlashMessage::ERROR
+								);
+								return $flashMessage->render();
+							} // ... else go on, install...
+						} // ... else go on, install...
+					} else {
+						return $GLOBALS['LANG']->getLL('ext_import_no_key');
+					}
+				} else {
+					return sprintf($GLOBALS['LANG']->getLL('ext_import_wrong_file_format'), $fetchData);
+				}
+			} else {
+				return $GLOBALS['LANG']->getLL('ext_import_no_file');
+			}
+		} else {
+			$this->xmlhandler->searchExtensionsXMLExact($extKey, '', '', true, true);
+
+			// Fetch extension from TER:
+			if (!strlen($version)) {
+				$versions = array_keys($this->xmlhandler->extensionsXML[$extKey]['versions']);
+				$version = end($versions);
+			}
+			$fetchData = $this->terConnection->fetchExtension($extKey, $version, $this->xmlhandler->extensionsXML[$extKey]['versions'][$version]['t3xfilemd5'], $this->getMirrorURL());
+		}
+
+		// At this point the extension data should be present; so we want to write it to disc:
+		$content = $this->install->installExtension($fetchData, $loc, $version, $uploadedTempFile, $dontDelete);
+
+		$this->content .= $this->doc->section($GLOBALS['LANG']->getLL('ext_import_results'), $content, 0, 1);
+
+		if ($uploadSucceed && $uploadedTempFile) {
+			t3lib_div::unlink_tempfile($uploadedTempFile);
+		}
+
+		return false;
+	}
+
+	/**
+	 * Display extensions details.
+	 *
+	 * @param	string		Extension key
+	 * @return	void		Writes content to $this->content
+	 */
+	function showExtDetails($extKey) {
+		global $TYPO3_LOADED_EXT;
+
+		list($list,) = $this->extensionList->getInstalledExtensions();
+		$absPath = tx_em_Tools::getExtPath($extKey, $list[$extKey]['type']);
+
+		// Check updateModule:
+		if (isset($list[$extKey]) && @is_file($absPath . 'class.ext_update.php')) {
+			require_once($absPath . 'class.ext_update.php');
+			$updateObj = new ext_update;
+			if (!$updateObj->access()) {
+				unset($this->MOD_MENU['singleDetails']['updateModule']);
+			}
+		} else {
+			unset($this->MOD_MENU['singleDetails']['updateModule']);
+		}
+
+		if ($this->CMD['doDelete']) {
+			$this->MOD_MENU['singleDetails'] = array();
+		}
+
+		// Function menu here:
+		if (!$this->CMD['standAlone'] && !t3lib_div::_GP('standAlone')) {
+			$content = $GLOBALS['LANG']->getLL('ext_details_ext') . '&nbsp;<strong>' .
+					$this->extensionTitleIconHeader($extKey, $list[$extKey]) . '</strong> (' . htmlspecialchars($extKey) . ')';
+			$this->content .= $this->doc->section('', $content);
+		}
+
+		// Show extension details:
+		if ($list[$extKey]) {
+
+			// Checking if a command for install/uninstall is executed:
+			if (($this->CMD['remove'] || $this->CMD['load']) && !in_array($extKey, $this->requiredExt)) {
+
+				// Install / Uninstall extension here:
+				if (t3lib_extMgm::isLocalconfWritable()) {
+					// Check dependencies:
+					$depStatus = $this->install->checkDependencies($extKey, $list[$extKey]['EM_CONF'], $list);
+					if (!$this->CMD['remove'] && !$depStatus['returnCode']) {
+						$this->content .= $depStatus['html'];
+						$newExtList = -1;
+					} elseif ($this->CMD['remove']) {
+						$newExtList = $this->extensionList->removeExtFromList($extKey, $list);
+					} else {
+						$newExtList = $this->extensionList->addExtToList($extKey, $list);
+					}
+
+					// Successful installation:
+					if ($newExtList != -1) {
+						$updates = '';
+						if ($this->CMD['load']) {
+							if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+								$script = t3lib_div::linkThisScript(array(
+									'CMD[showExt]' => $extKey,
+									'CMD[load]' => 1,
+									'CMD[clrCmd]' => $this->CMD['clrCmd'],
+									'SET[singleDetails]' => 'info'
+								));
+							} else {
+								$script = '';
+							}
+							if ($this->CMD['standAlone']) {
+								$standaloneUpdates = '<input type="hidden" name="standAlone" value="1" />';
+							}
+							$depsolver = t3lib_div::_POST('depsolver');
+							if (is_array($depsolver['ignore'])) {
+								foreach ($depsolver['ignore'] as $depK => $depV) {
+									$dependencyUpdates .= '<input type="hidden" name="depsolver[ignore][' . $depK . ']" value="1" />';
+								}
+							}
+							$updatesForm = $this->install->updatesForm(
+								$extKey,
+								$list[$extKey],
+								1,
+								$script,
+								$dependencyUpdates . $standaloneUpdates . '<input type="hidden" name="_do_install" value="1" /><input type="hidden" name="_clrCmd" value="' . $this->CMD['clrCmd'] . '" />',
+								TRUE
+							);
+							if ($updatesForm) {
+								$updates = $GLOBALS['LANG']->getLL('ext_details_new_tables_fields') . '<br />' .
+										$GLOBALS['LANG']->getLL('ext_details_new_tables_fields_select') . $updatesForm;
+								$labelDBUpdate = $GLOBALS['LANG']->csConvObj->conv_case(
+									$GLOBALS['LANG']->charSet,
+									$GLOBALS['LANG']->getLL('ext_details_db_needs_update'),
+									'toUpper'
+								);
+								$this->content .= $this->doc->section(
+									sprintf($GLOBALS['LANG']->getLL('ext_details_installing') . ' ',
+										$this->extensionTitleIconHeader($extKey, $list[$extKey])
+									) . ' ' .
+											$labelDBUpdate,
+									$updates, 1, 1, 1, 1
+								);
+							}
+						} elseif ($this->CMD['remove']) {
+							$updates .= $this->install->checkClearCache($list[$extKey]);
+							if ($updates) {
+								$updates = '
+								<form action="' . $this->script . '" method="post">' . $updates . '
+								<br /><input type="submit" name="write" value="' .
+										$GLOBALS['LANG']->getLL('ext_details_remove_ext') . '" />
+								<input type="hidden" name="_do_install" value="1" />
+								<input type="hidden" name="_clrCmd" value="' . $this->CMD['clrCmd'] . '" />
+								<input type="hidden" name="standAlone" value="' . $this->CMD['standAlone'] . '" />
+								</form>';
+								$labelDBUpdate = $GLOBALS['LANG']->csConvObj->conv_case(
+									$GLOBALS['LANG']->charSet,
+									$GLOBALS['LANG']->getLL('ext_details_db_needs_update'),
+									'toUpper'
+								);
+								$this->content .= $this->doc->section(
+									sprintf($GLOBALS['LANG']->getLL('ext_details_removing') . ' ',
+										$this->extensionTitleIconHeader($extKey, $list[$extKey])
+									) . ' ' .
+											$labelDBUpdate,
+									$updates, 1, 1, 1, 1
+								);
+							}
+						}
+						if (!$updates || t3lib_div::_GP('_do_install')) {
+							$this->writeNewExtensionList($newExtList);
+							$action = $this->CMD['load'] ? 'installed' : 'removed';
+							$GLOBALS['BE_USER']->writelog(5, 1, 0, 0, 'Extension list has been changed, extension %s has been %s', array($extKey, $action));
+
+							$messageLabel = 'ext_details_ext_' . $action . '_with_key';
+							$flashMessage = t3lib_div::makeInstance(
+								't3lib_FlashMessage',
+								sprintf($GLOBALS['LANG']->getLL($messageLabel), $extKey),
+								'',
+								t3lib_FlashMessage::OK,
+								TRUE
+							);
+							t3lib_FlashMessageQueue::addMessage($flashMessage);
+
+							if ($this->CMD['clrCmd'] || t3lib_div::_GP('_clrCmd')) {
+								if ($this->CMD['load'] && @is_file($absPath . 'ext_conf_template.txt')) {
+									$vA = array('CMD' => array('showExt' => $extKey));
+								} else {
+									$vA = array('CMD' => '');
+								}
+							} else {
+								$vA = array('CMD' => array('showExt' => $extKey));
+							}
+							if ($this->CMD['standAlone'] || t3lib_div::_GP('standAlone')) {
+								$this->content .= sprintf($GLOBALS['LANG']->getLL('ext_details_ext_installed_removed'),
+									($this->CMD['load'] ?
+											$GLOBALS['LANG']->getLL('ext_details_installed') :
+											$GLOBALS['LANG']->getLL('ext_details_removed')
+									)
+								) .
+										'<br /><br /><a href="javascript:opener.top.list.iframe.document.forms[0].submit();window.close();">' .
+										$GLOBALS['LANG']->getLL('ext_import_close_check') . '</a>';
+							} else {
+								// Determine if new modules were installed:
+								$techInfo = $this->install->makeDetailedExtensionAnalysis($extKey, $list[$extKey]);
+								if (($this->CMD['load'] || $this->CMD['remove']) && is_array($techInfo['flags']) && in_array('Module', $techInfo['flags'], true)) {
+									$vA['CMD']['refreshMenu'] = 1;
+								}
+								t3lib_utility_Http::redirect(t3lib_div::linkThisScript($vA));
+								exit;
+							}
+						}
+					}
+				} else {
+					$writeAccessError = $GLOBALS['LANG']->csConvObj->conv_case(
+						$GLOBALS['LANG']->charSet,
+						$GLOBALS['LANG']->getLL('ext_details_write_access_error'),
+						'toUpper'
+					);
+					$this->content .= $this->doc->section(
+						sprintf($GLOBALS['LANG']->getLL('ext_details_installing') . ' ',
+							$this->extensionTitleIconHeader($extKey, $list[$extKey])
+						) . ' ' .
+								$writeAccessError,
+						$GLOBALS['LANG']->getLL('ext_details_write_error_localconf'),
+						1, 1, 2, 1
+					);
+				}
+
+			} elseif ($this->CMD['downloadFile'] && !in_array($extKey, $this->requiredExt)) {
+
+				// Link for downloading extension has been clicked - deliver content stream:
+				$dlFile = $this->CMD['downloadFile'];
+				if (t3lib_div::isAllowedAbsPath($dlFile) && t3lib_div::isFirstPartOfStr($dlFile, PATH_site) && t3lib_div::isFirstPartOfStr($dlFile, $absPath) && @is_file($dlFile)) {
+					$mimeType = 'application/octet-stream';
+					Header('Content-Type: ' . $mimeType);
+					Header('Content-Disposition: attachment; filename=' . basename($dlFile));
+					echo t3lib_div::getUrl($dlFile);
+					exit;
+				} else {
+					throw new RuntimeException(
+						'TYPO3 Fatal Error: ' . $GLOBALS['LANG']->getLL('ext_details_error_downloading'),
+						1270853980
+					);
+				}
+
+			} elseif ($this->CMD['editFile'] && !in_array($extKey, $this->requiredExt)) {
+
+				// Editing extension file:
+				$editFile = $this->CMD['editFile'];
+				if (t3lib_div::isAllowedAbsPath($editFile) && t3lib_div::isFirstPartOfStr($editFile, $absPath)) {
+
+					$fI = t3lib_div::split_fileref($editFile);
+					if (@is_file($editFile) && t3lib_div::inList($this->editTextExtensions, ($fI['fileext'] ? $fI['fileext'] : $fI['filebody']))) {
+						if (filesize($editFile) < ($this->kbMax * 1024)) {
+							$outCode = '<form action="' . $this->script . ' method="post" name="editfileform">';
+							$info = '';
+							$submittedContent = t3lib_div::_POST('edit');
+							$saveFlag = 0;
+
+							if (isset($submittedContent['file']) && !$GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit']) { // Check referer here?
+								$oldFileContent = t3lib_div::getUrl($editFile);
+								if ($oldFileContent != $submittedContent['file']) {
+									$oldMD5 = md5(str_replace(CR, '', $oldFileContent));
+									$info .= sprintf(
+										$GLOBALS['LANG']->getLL('ext_details_md5_previous'),
+											'<strong>' . $oldMD5 . '</strong>'
+									) . '<br />';
+									t3lib_div::writeFile($editFile, $submittedContent['file']);
+									$saveFlag = 1;
+								} else {
+									$info .= $GLOBALS['LANG']->getLL('ext_details_no_changes') . '<br />';
+								}
+							}
+
+							$fileContent = t3lib_div::getUrl($editFile);
+
+							$outCode .= sprintf(
+								$GLOBALS['LANG']->getLL('ext_details_file'),
+									'<strong>' . substr($editFile, strlen($absPath)) . '</strong> (' .
+											t3lib_div::formatSize(filesize($editFile)) . ')<br />'
+							);
+							$fileMD5 = md5(str_replace(CR, '', $fileContent));
+							$info .= sprintf(
+								$GLOBALS['LANG']->getLL('ext_details_md5_current'),
+									'<strong>' . $fileMD5 . '</strong>'
+							) . '<br />';
+							if ($saveFlag) {
+								$saveMD5 = md5(str_replace(CR, '', $submittedContent['file']));
+								$info .= sprintf(
+									$GLOBALS['LANG']->getLL('ext_details_md5_submitted'),
+										'<strong>' . $saveMD5 . '</strong>'
+								) . '<br />';
+								if ($fileMD5 != $saveMD5) {
+									$info .= $GLOBALS['TBE_TEMPLATE']->rfw(
+										'<br /><strong>' . $GLOBALS['LANG']->getLL('ext_details_saving_failed_changes_lost') . '</strong>'
+									) . '<br />';
+								}
+								else {
+									$info .= $GLOBALS['TBE_TEMPLATE']->rfw(
+										'<br /><strong>' . $GLOBALS['LANG']->getLL('ext_details_file_saved') . '</strong>'
+									) . '<br />';
+								}
+							}
+
+							$outCode .= '<textarea name="edit[file]" rows="35" wrap="off"' . $this->doc->formWidthText(48, 'width:98%;height:70%', 'off') . ' class="fixed-font enable-tab">' . t3lib_div::formatForTextarea($fileContent) . '</textarea>';
+							$outCode .= '<input type="hidden" name="edit[filename]" value="' . $editFile . '" />';
+							$outCode .= '<input type="hidden" name="CMD[editFile]" value="' . htmlspecialchars($editFile) . '" />';
+							$outCode .= '<input type="hidden" name="CMD[showExt]" value="' . $extKey . '" />';
+							$outCode .= $info;
+
+							if (!$GLOBALS['TYPO3_CONF_VARS']['EXT']['noEdit']) {
+								$outCode .= '<br /><input type="submit" name="save_file" value="' .
+										$GLOBALS['LANG']->getLL('ext_details_file_save_button') . '" />';
+							}
+							else {
+								$outCode .= $GLOBALS['TBE_TEMPLATE']->rfw(
+									'<br />' . $GLOBALS['LANG']->getLL('ext_details_saving_disabled') . ' '
+								);
+							}
+
+							$onClick = 'window.location.href="' . t3lib_div::linkThisScript(array(
+								'CMD[showExt]' => $extKey
+							)) . '";return false;';
+							$outCode .= '<input type="submit" name="cancel" value="' .
+									$GLOBALS['LANG']->getLL('ext_details_cancel_button') . '" onclick="' .
+									htmlspecialchars($onClick) . '" /></form>';
+
+							$theOutput .= $this->doc->spacer(15);
+							$theOutput .= $this->doc->section($GLOBALS['LANG']->getLL('ext_details_edit_file'), '', 0, 1);
+							$theOutput .= $this->doc->sectionEnd() . $outCode;
+							$this->content .= $theOutput;
+						} else {
+							$theOutput .= $this->doc->spacer(15);
+							$theOutput .= $this->doc->section(
+								sprintf(
+									$GLOBALS['LANG']->getLL('ext_details_filesize_exceeded_kb'),
+									$this->kbMax
+								),
+								sprintf(
+									$GLOBALS['LANG']->getLL('ext_details_file_too_large'),
+									$this->kbMax
+								)
+							);
+						}
+					}
+				} else {
+					die (sprintf($GLOBALS['LANG']->getLL('ext_details_fatal_edit_error'),
+						htmlspecialchars($editFile)
+					)
+					);
+				}
+			} else {
+
+				// MAIN:
+				switch ((string) $this->MOD_SETTINGS['singleDetails']) {
+					case 'info':
+						// Loaded / Not loaded:
+						if (!in_array($extKey, $this->requiredExt)) {
+							if ($TYPO3_LOADED_EXT[$extKey]) {
+								$content = '<strong>' . $GLOBALS['LANG']->getLL('ext_details_loaded_and_running') . '</strong><br />' .
+										'<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
+									'CMD[showExt]' => $extKey,
+									'CMD[remove]' => 1
+								))) .
+										'">' . $GLOBALS['LANG']->getLL('ext_details_remove_button') . ' ' . tx_em_Tools::removeButton() . '</a>';
+							} else {
+								$content = $GLOBALS['LANG']->getLL('ext_details_not_loaded') . '<br />' .
+										'<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
+									'CMD[showExt]' => $extKey,
+									'CMD[load]' => 1
+								))) .
+										'">' . $GLOBALS['LANG']->getLL('ext_details_install_button') . ' ' . tx_em_Tools::installButton() . '</a>';
+							}
+						} else {
+							$content = $GLOBALS['LANG']->getLL('ext_details_always_loaded');
+						}
+						$this->content .= $this->doc->spacer(10);
+						$this->content .= $this->doc->section(
+							$GLOBALS['LANG']->getLL('ext_details_current_status'), $content, 0, 1
+						);
+
+						if (t3lib_extMgm::isLoaded($extKey)) {
+							$updates = $this->install->updatesForm($extKey, $list[$extKey]);
+							if ($updates) {
+								$this->content .= $this->doc->spacer(10);
+								$this->content .= $this->doc->section(
+									$GLOBALS['LANG']->getLL('ext_details_update_needed'),
+										$updates . '<br /><br />' . $GLOBALS['LANG']->getLL('ext_details_notice_static_data'),
+									0, 1
+								);
+							}
+						}
+
+						// Config:
+						if (@is_file($absPath . 'ext_conf_template.txt')) {
+							$this->content .= $this->doc->spacer(10);
+							$this->content .= $this->doc->section(
+								$GLOBALS['LANG']->getLL('ext_details_configuration'),
+									$GLOBALS['LANG']->getLL('ext_details_notice_clear_cache') . '<br /><br />',
+								0, 1
+							);
+
+							$this->content .= $this->install->tsStyleConfigForm($extKey, $list[$extKey]);
+						}
+
+						// Show details:
+						$headline = $GLOBALS['LANG']->getLL('ext_details_details');
+						$headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'info', $headline);
+						$content = $this->extensionDetails->extInformationarray($extKey, $list[$extKey]);
+
+
+						$this->content .= $this->doc->spacer(10);
+						$this->content .= $this->doc->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
+						break;
+					case 'upload':
+						$em = t3lib_div::_POST('em');
+						if ($em['action'] == 'doUpload') {
+							$em['extKey'] = $extKey;
+							$em['extInfo'] = $list[$extKey];
+							$content = $this->uploadExtensionToTER($em);
+							$content .= $this->doc->spacer(10);
+							// Must reload this, because EM_CONF information has been updated!
+							list($list,) = $this->extensionList->getInstalledExtensions();
+						} else {
+							// headline and CSH
+							$headline = $GLOBALS['LANG']->getLL('ext_details_upload_to_ter');
+							$headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'upload', $headline);
+
+							// Upload:
+							if (substr($extKey, 0, 5) != 'user_') {
+								$content = $this->getRepositoryUploadForm($extKey, $list[$extKey]);
+								$eC = 0;
+							} else {
+								$content = $GLOBALS['LANG']->getLL('ext_details_no_unique_ext');
+								$eC = 2;
+							}
+							if (!$this->fe_user['username']) {
+								$flashMessage = t3lib_div::makeInstance(
+									't3lib_FlashMessage',
+									sprintf($GLOBALS['LANG']->getLL('ext_details_no_username'),
+											'<a href="' . t3lib_div::linkThisScript(array(
+												'SET[function]' => 3
+											)) . '">', '</a>'
+									),
+									'',
+									t3lib_FlashMessage::INFO
+								);
+								$content .= '<br />' . $flashMessage->render();
+
+							}
+						}
+						$this->content .= $this->doc->section($headline, $content, 0, 1, $eC, TRUE);
+						break;
+					case 'backup':
+						if ($this->CMD['doDelete']) {
+							$content = $this->extDelete($extKey, $list[$extKey]);
+							$this->content .= $this->doc->section(
+								$GLOBALS['LANG']->getLL('ext_details_delete'),
+								$content, 0, 1
+							);
+						} else {
+							// headline and CSH
+							$headline = $GLOBALS['LANG']->getLL('ext_details_backup');
+							$headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'backup_delete', $headline);
+
+							$content = $this->extBackup($extKey, $list[$extKey]);
+							$this->content .= $this->doc->section($headline, $content, 0, 1, 0, 1);
+
+							$content = $this->extDelete($extKey, $list[$extKey]);
+							$this->content .= $this->doc->section(
+								$GLOBALS['LANG']->getLL('ext_details_delete'),
+								$content, 0, 1
+							);
+
+							$content = $this->extUpdateEMCONF($extKey, $list[$extKey]);
+							$this->content .= $this->doc->section(
+								$GLOBALS['LANG']->getLL('ext_details_update_em_conf'),
+								$content, 0, 1
+							);
+						}
+						break;
+					case 'dump':
+						$this->extDumpTables($extKey, $list[$extKey]);
+						break;
+					case 'edit':
+						// headline and CSH
+						$headline = $GLOBALS['LANG']->getLL('ext_details_ext_files');
+						$headline = t3lib_BEfunc::wrapInHelp('_MOD_tools_em', 'editfiles', $headline);
+
+						$content = $this->getFileListOfExtension($extKey, $list[$extKey]);
+
+						$this->content .= $this->doc->section($headline, $content, FALSE, TRUE, FALSE, TRUE);
+						break;
+					case 'updateModule':
+						$this->content .= $this->doc->section(
+							$GLOBALS['LANG']->getLL('ext_details_update'),
+							is_object($updateObj) ?
+									$updateObj->main() :
+									$GLOBALS['LANG']->getLL('ext_details_no_update_object'),
+							0, 1
+						);
+						break;
+					default:
+						$this->extObjContent();
+						break;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Outputs a screen from where you can install multiple extensions in one go
+	 * This can be called from external modules with "...index.php?CMD[requestInstallExtensions]=
+	 *
+	 * @param	string		Comma list of extension keys to install. Renders a screen with checkboxes for all extensions not already imported or installed
+	 * @return	void
+	 */
+	function requestInstallExtensions($extList) {
+
+		// Return URL:
+		$returnUrl = t3lib_div::sanitizeLocalUrl(t3lib_div::_GP('returnUrl'));
+		$installOrImportExtension = t3lib_div::_POST('installOrImportExtension');
+
+		// Extension List:
+		$extArray = explode(',', $extList);
+		$outputRow = array();
+		$outputRow[] = '
+			<tr class="t3-row-header tableheader">
+				<td>' . $GLOBALS['LANG']->getLL('reqInstExt_install_import') . '</td>
+				<td>' . $GLOBALS['LANG']->getLL('reqInstExt_ext_key') . '</td>
+			</tr>
+		';
+
+		foreach ($extArray as $extKey) {
+
+			// Check for the request:
+			if ($installOrImportExtension[$extKey]) {
+				$this->installExtension($extKey);
+			}
+
+			// Display:
+			if (!t3lib_extMgm::isLoaded($extKey)) {
+				$outputRow[] = '
+				<tr class="bgColor4">
+					<td><input type="checkbox" name="' . htmlspecialchars('installOrImportExtension[' . $extKey . ']') . '" value="1" checked="checked" id="check_' . $extKey . '" /></td>
+					<td><label for="check_' . $extKey . '">' . htmlspecialchars($extKey) . '</label></td>
+				</tr>
+				';
+			}
+		}
+
+		if (count($outputRow) > 1 || !$returnUrl) {
+			$content = '
+				<!-- ending page form ... -->
+			<form action="' . htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI')) . '" method="post">
+				<table border="0" cellpadding="1" cellspacing="1">' . implode('', $outputRow) . '</table>
+			<input type="submit" name="_" value="' . $GLOBALS['LANG']->getLL('reqInstExt_import_install_selected') . '" />
+			</form>';
+
+			if ($returnUrl) {
+				$content .= '
+				<br />
+				<br />
+				<a href="' . htmlspecialchars($returnUrl) . '">' . $GLOBALS['LANG']->getLL('reqInstExt_return') . '</a>
+				';
+			}
+
+			$this->content .= $this->doc->section(
+				$GLOBALS['LANG']->getLL('reqInstExt_imp_inst_ext'), $content, 0, 1
+			);
+		} else {
+			t3lib_utility_Http::redirect($returnUrl);
+		}
+	}
+
+
+	/***********************************
+	 *
+	 * Application Sub-functions (HTML parts)
+	 *
+	 **********************************/
+
+
+	/**
+	 * Creates view for dumping static tables and table/fields structures...
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @return	void
+	 */
+	function extDumpTables($extKey, $extInfo) {
+
+		// Get dbInfo which holds the structure known from the tables.sql file
+		$techInfo = $this->install->makeDetailedExtensionAnalysis($extKey, $extInfo);
+		$absPath = tx_em_Tools::getExtPath($extKey, $extInfo['type']);
+
+		// Static tables:
+		if (is_array($techInfo['static'])) {
+			if ($this->CMD['writeSTATICdump']) { // Writing static dump:
+				$writeFile = $absPath . 'ext_tables_static+adt.sql';
+				if (@is_file($writeFile)) {
+					$dump_static = tx_em_Database::dumpStaticTables(implode(',', $techInfo['static']));
+					t3lib_div::writeFile($writeFile, $dump_static);
+					$this->content .= $this->doc->section(
+						$GLOBALS['LANG']->getLL('extDumpTables_tables_fields'),
+						sprintf($GLOBALS['LANG']->getLL('extDumpTables_bytes_written_to'),
+							t3lib_div::formatSize(strlen($dump_static)),
+							substr($writeFile, strlen(PATH_site))
+						),
+						0, 1
+					);
+				}
+			} else { // Showing info about what tables to dump - and giving the link to execute it.
+				$msg = $GLOBALS['LANG']->getLL('extDumpTables_dumping_content') . '<br />';
+				$msg .= '<br />' . implode('<br />', $techInfo['static']) . '<br />';
+
+				// ... then feed that to this function which will make new CREATE statements of the same fields but based on the current database content.
+				$this->content .= $this->doc->section(
+					$GLOBALS['LANG']->getLL('extDumpTables_static_tables'),
+						$msg . '<hr /><strong><a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
+							'CMD[showExt]' => $extKey,
+							'CMD[writeSTATICdump]' => 1
+						))) . '">' . $GLOBALS['LANG']->getLL('extDumpTables_write_static') . '</a></strong>',
+					0, 1
+				);
+				$this->content .= $this->doc->spacer(20);
+			}
+		}
+
+		// Table and field definitions:
+		if (is_array($techInfo['dump_tf'])) {
+			$dump_tf_array = tx_em_Database::getTableAndFieldStructure($techInfo['dump_tf']);
+			$dump_tf = tx_em_Database::dumpTableAndFieldStructure($dump_tf_array);
+			if ($this->CMD['writeTFdump']) {
+				$writeFile = $absPath . 'ext_tables.sql';
+				if (@is_file($writeFile)) {
+					t3lib_div::writeFile($writeFile, $dump_tf);
+					$this->content .= $this->doc->section(
+						$GLOBALS['LANG']->getLL('extDumpTables_tables_fields'),
+						sprintf($GLOBALS['LANG']->getLL('extDumpTables_bytes_written_to'),
+							t3lib_div::formatSize(strlen($dump_tf)),
+							substr($writeFile, strlen(PATH_site))
+						),
+						0, 1
+					);
+				}
+			} else {
+				$msg = $GLOBALS['LANG']->getLL('extDumpTables_dumping_db_structure') . '<br />';
+				if (is_array($techInfo['tables'])) {
+					$msg .= '<br /><strong>' . $GLOBALS['LANG']->getLL('extDumpTables_tables') . '</strong><br />' .
+							implode('<br />', $techInfo['tables']) . '<br />';
+				}
+				if (is_array($techInfo['fields'])) {
+					$msg .= '<br /><strong>' . $GLOBALS['LANG']->getLL('extDumpTables_solo_fields') . '</strong><br />' .
+							implode('<br />', $techInfo['fields']) . '<br />';
+				}
+
+				// ... then feed that to this function which will make new CREATE statements of the same fields but based on the current database content.
+				$this->content .= $this->doc->section(
+					$GLOBALS['LANG']->getLL('extDumpTables_tables_fields'),
+						$msg . '<hr /><strong><a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
+							'CMD[showExt]' => $extKey,
+							'CMD[writeTFdump]' => 1
+						))) .
+								'">' . $GLOBALS['LANG']->getLL('extDumpTables_write_dump') . '</a></strong><hr />
+						<pre>' . htmlspecialchars($dump_tf) . '</pre>',
+					0, 1
+				);
+
+
+				$details = '							' . $GLOBALS['LANG']->getLL('extDumpTables_based_on') . '<br />
+				<ul>
+				<li>' . $GLOBALS['LANG']->getLL('extDumpTables_based_on_one') . '</li>
+				<li>' . $GLOBALS['LANG']->getLL('extDumpTables_based_on_two') . '</li>
+				</ul>
+				' . $GLOBALS['LANG']->getLL('extDumpTables_bottomline') . '<br />';
+				$this->content .= $this->doc->section('', $details);
+			}
+		}
+	}
+
+	/**
+	 * Returns file-listing of an extension
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @return	string		HTML table.
+	 */
+	function getFileListOfExtension($extKey, $conf) {
+		$content = '';
+		$extPath = tx_em_Tools::getExtPath($extKey, $conf['type']);
+
+		if ($extPath) {
+			// Read files:
+			$fileArr = array();
+			$fileArr = t3lib_div::getAllFilesAndFoldersInPath($fileArr, $extPath, '', 0, 99, $this->excludeForPackaging);
+
+			// Start table:
+			$lines = array();
+			$totalSize = 0;
+
+			// Header:
+			$lines[] = '
+				<tr class="t3-row-header">
+					<td>' . $GLOBALS['LANG']->getLL('extFileList_file') . '</td>
+					<td>' . $GLOBALS['LANG']->getLL('extFileList_size') . '</td>
+					<td>' . $GLOBALS['LANG']->getLL('extFileList_edit') . '</td>
+				</tr>';
+
+			foreach ($fileArr as $file) {
+				$fI = t3lib_div::split_fileref($file);
+				$lines[] = '
+				<tr class="bgColor4">
+					<td><a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
+					'CMD[showExt]' => $extKey,
+					'CMD[downloadFile]' => rawurlencode($file)
+				))) . '" title="' . $GLOBALS['LANG']->getLL('extFileList_download') . '">' .
+						substr($file, strlen($extPath)) . '</a></td>
+					<td>' . t3lib_div::formatSize(filesize($file)) . '</td>
+					<td>' . (!in_array($extKey, $this->requiredExt) &&
+						t3lib_div::inList($this->editTextExtensions,
+							($fI['fileext'] ? $fI['fileext'] : $fI['filebody'])) ?
+						'<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
+							'CMD[showExt]' => $extKey,
+							'CMD[editFile]' => rawurlencode($file)
+						))) . '">' .
+								$GLOBALS['LANG']->getLL('extFileList_edit_file') . '</a>' : ''
+				) . '</td>
+				</tr>';
+				$totalSize += filesize($file);
+			}
+
+			$lines[] = '
+				<tr class="bgColor6">
+					<td><strong>' . $GLOBALS['LANG']->getLL('extFileList_total') . '</strong></td>
+					<td><strong>' . t3lib_div::formatSize($totalSize) . '</strong></td>
+					<td>&nbsp;</td>
+				</tr>';
+
+			$content = '
+			Path: ' . $extPath . '<br /><br />
+			<table border="0" cellpadding="1" cellspacing="2">' . implode('', $lines) . '</table>';
+		}
+
+		return $content;
+	}
+
+
+	/**
+	 * Update extension EM_CONF...
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @return	string		HTML content.
+	 */
+	function extUpdateEMCONF($extKey, $extInfo) {
+		$absPath = tx_em_Tools::getExtPath($extKey, $extInfo['type']);
+		if ($this->CMD['doUpdateEMCONF']) {
+			return $this->updateLocalEM_CONF($extKey, $extInfo);
+		} else {
+			$sure = $GLOBALS['LANG']->getLL('extUpdateEMCONF_sure');
+			$updateEMConf = $GLOBALS['LANG']->getLL('extUpdateEMCONF_file');
+			$onClick = "if (confirm('$sure')) {window.location.href='" . t3lib_div::linkThisScript(array(
+				'CMD[showExt]' => $extKey,
+				'CMD[doUpdateEMCONF]' => 1
+			)) . "';}";
+			$content .= '<a class="t3-link" href="#" onclick="' . htmlspecialchars($onClick) .
+					' return false;"><strong>' . $updateEMConf . '</strong> ' .
+					sprintf($GLOBALS['LANG']->getLL('extDelete_from_location'),
+						$this->typeLabels[$extInfo['type']],
+						substr($absPath, strlen(PATH_site))
+					) . '</a>';
+			$content .= '<br /><br />' . $GLOBALS['LANG']->getLL('extUpdateEMCONF_info_changes') . '<br />
+						' . $GLOBALS['LANG']->getLL('extUpdateEMCONF_info_reset');
+			return $content;
+		}
+	}
+
+	/**
+	 * Download extension as file / make backup
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @return	string		HTML content
+	 */
+	function extBackup($extKey, $extInfo) {
+		$uArr = $this->extensionDetails->makeUploadarray($extKey, $extInfo);
+		if (is_array($uArr)) {
+			$backUpData = $this->terConnection->makeUploadDataFromarray($uArr);
+			$filename = 'T3X_' . $extKey . '-' . str_replace('.', '_', $extInfo['EM_CONF']['version']) . '-z-' . date('YmdHi') . '.t3x';
+			if (intval($this->CMD['doBackup']) == 1) {
+				header('Content-Type: application/octet-stream');
+				header('Content-Disposition: attachment; filename=' . $filename);
+				echo $backUpData;
+				exit;
+			} elseif ($this->CMD['dumpTables']) {
+				$filename = 'T3X_' . $extKey;
+				$cTables = count(explode(',', $this->CMD['dumpTables']));
+				if ($cTables > 1) {
+					$filename .= '-' . $cTables . 'tables';
+				} else {
+					$filename .= '-' . $this->CMD['dumpTables'];
+				}
+				$filename .= '+adt.sql';
+
+				header('Content-Type: application/octet-stream');
+				header('Content-Disposition: attachment; filename=' . $filename);
+				echo tx_em_Database::dumpStaticTables($this->CMD['dumpTables']);
+				exit;
+			} else {
+				$techInfo = $this->install->makeDetailedExtensionAnalysis($extKey, $extInfo);
+				$lines = array();
+				$lines[] = '<tr class="t3-row-header"><td colspan="2">' .
+						$GLOBALS['LANG']->getLL('extBackup_select') . '</td></tr>';
+				$lines[] = '<tr class="bgColor4"><td><strong>' .
+						$GLOBALS['LANG']->getLL('extBackup_files') . '</strong></td><td>' .
+						'<a class="t3-link" href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
+					'CMD[doBackup]' => 1,
+					'CMD[showExt]' => $extKey
+				))) .
+						'">' . sprintf($GLOBALS['LANG']->getLL('extBackup_download'),
+					$extKey
+				) . '</a><br />
+					(' . $filename . ', <br />' .
+						t3lib_div::formatSize(strlen($backUpData)) . ', <br />' .
+						$GLOBALS['LANG']->getLL('extBackup_md5') . ' ' . md5($backUpData) . ')
+					<br /></td></tr>';
+
+				if (is_array($techInfo['tables'])) {
+					$lines[] = '<tr class="bgColor4"><td><strong>' . $GLOBALS['LANG']->getLL('extBackup_data_tables') .
+							'</strong></td><td>' . $this->extBackup_dumpDataTablesLine($techInfo['tables'], $extKey) . '</td></tr>';
+				}
+				if (is_array($techInfo['static'])) {
+					$lines[] = '<tr class="bgColor4"><td><strong>' . $GLOBALS['LANG']->getLL('extBackup_static_tables') .
+							'</strong></td><td>' . $this->extBackup_dumpDataTablesLine($techInfo['static'], $extKey) . '</td></tr>';
+				}
+
+				$content = '<table border="0" cellpadding="2" cellspacing="2">' . implode('', $lines) . '</table>';
+				return $content;
+			}
+		} else {
+			throw new RuntimeException(
+				'TYPO3 Fatal Error: ' . $GLOBALS['LANG']->getLL('extBackup_unexpected_error'),
+				1270853981
+			);
+		}
+	}
+
+	/**
+	 * Link to dump of database tables
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @return	string		HTML
+	 */
+	function extBackup_dumpDataTablesLine($tablesArray, $extKey) {
+		$tables = array();
+		$tablesNA = array();
+		$allTables = array_keys($GLOBALS['TYPO3_DB']->admin_get_tables());
+
+		foreach ($tablesArray as $tN) {
+			if (in_array($tN, $allTables)) {
+				$count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', $tN);
+				$tables[$tN] = '<tr><td>&nbsp;</td><td>
+					<a class="t3-link" href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
+					'CMD[dumpTables]' => rawurlencode($tN),
+					'CMD[showExt]' => $extKey
+				))) .
+						'" title="' .
+						sprintf($GLOBALS['LANG']->getLL('extBackup_dump_table'),
+							$tN) .
+						'">' . $tN . '</a></td><td>&nbsp;&nbsp;&nbsp;</td><td>' .
+						sprintf($GLOBALS['LANG']->getLL('extBackup_number_of_records'),
+							$count) . '</td></tr>';
+			} else {
+				$tablesNA[$tN] = '<tr><td>&nbsp;</td><td>' . $tN . '</td><td>&nbsp;</td><td>' .
+						$GLOBALS['LANG']->getLL('extBackup_table_not_there') . '</td></tr>';
+			}
+		}
+		$label = '<table border="0" cellpadding="0" cellspacing="0">' . implode('', array_merge($tables, $tablesNA)) . '</table>'; // Candidate for t3lib_div::array_merge() if integer-keys will some day make trouble...
+		if (count($tables)) {
+			$label = '<a class="t3-link" href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
+				'CMD[dumpTables]' => rawurlencode(implode(',', array_keys($tables))),
+				'CMD[showExt]' => $extKey
+			))) .
+					'" title="' . $GLOBALS['LANG']->getLL('extBackup_dump_all_tables') . '">' .
+					$GLOBALS['LANG']->getLL('extBackup_download_all_data') . '</a><br /><br />' . $label;
+		}
+		else {
+			$label = $GLOBALS['LANG']->getLL('extBackup_nothing_to_dump') . '<br /><br />' . $label;
+		}
+		return $label;
+	}
+
+
+	/**
+	 * Prints the upload form for extensions
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @return	string		HTML content.
+	 */
+	function getRepositoryUploadForm($extKey, $extInfo) {
+		$content = '<form action="' . $this->script . '" method="post" name="repuploadform">
+			<input type="hidden" name="CMD[showExt]" value="' . $extKey . '" />
+			<input type="hidden" name="em[action]" value="doUpload" />
+			<table border="0" cellpadding="2" cellspacing="1">
+				<tr class="bgColor4">
+					<td>' . $GLOBALS['LANG']->getLL('repositoryUploadForm_username') . '</td>
+					<td><input' . $this->doc->formWidth(20) . ' type="text" name="em[user][fe_u]" value="' . $this->fe_user['username'] . '" /></td>
+				</tr>
+				<tr class="bgColor4">
+					<td>' . $GLOBALS['LANG']->getLL('repositoryUploadForm_password') . '</td>
+					<td><input' . $this->doc->formWidth(20) . ' type="password" name="em[user][fe_p]" value="' . $this->fe_user['password'] . '" /></td>
+				</tr>
+				<tr class="bgColor4">
+					<td>' . $GLOBALS['LANG']->getLL('repositoryUploadForm_changelog') . '</td>
+					<td><textarea' . $this->doc->formWidth(30, 1) . ' rows="5" name="em[upload][comment]"></textarea></td>
+				</tr>
+				<tr class="bgColor4">
+					<td>' . $GLOBALS['LANG']->getLL('repositoryUploadForm_command') . '</td>
+					<td nowrap="nowrap">
+						<input type="radio" name="em[upload][mode]" id="new_dev" value="new_dev" checked="checked" />
+							<label for="new_dev">' . sprintf($GLOBALS['LANG']->getLL('repositoryUploadForm_new_bugfix'),
+				'x.x.<strong>' . $GLOBALS['TBE_TEMPLATE']->rfw('x+1') . '</strong>'
+		) . '</label><br />
+						<input type="radio" name="em[upload][mode]" id="new_sub" value="new_sub" />
+							<label for="new_sub">' . sprintf($GLOBALS['LANG']->getLL('repositoryUploadForm_new_sub_version'),
+				'x.<strong>' . $GLOBALS['TBE_TEMPLATE']->rfw('x+1') . '</strong>.0'
+		) . '</label><br />
+						<input type="radio" name="em[upload][mode]" id="new_main" value="new_main" />
+							<label for="new_main">' . sprintf($GLOBALS['LANG']->getLL('repositoryUploadForm_new_main_version'),
+				'<strong>' . $GLOBALS['TBE_TEMPLATE']->rfw('x+1') . '</strong>.0.0'
+		) . '</label><br />
+					</td>
+				</tr>
+				<tr class="bgColor4">
+					<td>&nbsp;</td>
+					<td><input type="submit" name="submit" value="' . $GLOBALS['LANG']->getLL('repositoryUploadForm_upload') . '" />
+					</td>
+				</tr>
+			</table>
+			</form>';
+
+		return $content;
+	}
+
+
+	/************************************
+	 *
+	 * Output helper functions
+	 *
+	 ************************************/
+
+
+	/**
+	 * Returns a header for an extensions including icon if any
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @param	string		align-attribute value (for <img> tag)
+	 * @return	string		HTML; Extension title and image.
+	 */
+	function extensionTitleIconHeader($extKey, $extInfo, $align = 'top') {
+		$imgInfo = @getImageSize(tx_em_Tools::getExtPath($extKey, $extInfo['type']) . '/ext_icon.gif');
+		$out = '';
+		if (is_array($imgInfo)) {
+			$out .= '<img src="' . $GLOBALS['BACK_PATH'] . $this->typeRelPaths[$extInfo['type']] . $extKey . '/ext_icon.gif" ' . $imgInfo[3] . ' align="' . $align . '" alt="" />';
+		}
+		$out .= $extInfo['EM_CONF']['title'] ? htmlspecialchars(t3lib_div::fixed_lgd_cs($extInfo['EM_CONF']['title'], 40)) : '<em>' . htmlspecialchars($extKey) . '</em>';
+		return $out;
+	}
+
+
+	/**
+	 * Writes the extension list to "localconf.php" file
+	 * Removes the temp_CACHED* files before return.
+	 *
+	 * @param	string		List of extensions
+	 * @return	void
+	 */
+	function writeNewExtensionList($newExtList) {
+		global $TYPO3_CONF_VARS;
+
+		$strippedExtensionList = $this->stripNonFrontendExtensions($newExtList);
+
+		// Instance of install tool
+		$instObj = new t3lib_install;
+		$instObj->allowUpdateLocalConf = 1;
+		$instObj->updateIdentity = 'TYPO3 Extension Manager';
+
+		// Get lines from localconf file
+		$lines = $instObj->writeToLocalconf_control();
+		$instObj->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'EXT\'][\'extList\']', $newExtList);
+		$instObj->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'EXT\'][\'extList_FE\']', $strippedExtensionList);
+		$instObj->writeToLocalconf_control($lines);
+
+		$TYPO3_CONF_VARS['EXT']['extList'] = $newExtList;
+		$TYPO3_CONF_VARS['EXT']['extList_FE'] = $strippedExtensionList;
+		t3lib_extMgm::removeCacheFiles();
+	}
+
+	/**
+	 * Removes unneeded extensions from the frontend based on
+	 * EMCONF doNotLoadInFE = 1
+	 *
+	 * @param string $extList
+	 * @return string
+	 */
+	function stripNonFrontendExtensions($extList) {
+		$fullExtList = $this->extensionList->getInstalledExtensions();
+		$extListArray = t3lib_div::trimExplode(',', $extList);
+		foreach ($extListArray as $arrayKey => $extKey) {
+			if ($fullExtList[0][$extKey]['EM_CONF']['doNotLoadInFE'] == 1) {
+				unset($extListArray[$arrayKey]);
+			}
+		}
+		$nonFEList = implode(',', $extListArray);
+		return $nonFEList;
+	}
+
+
+	/**
+	 * Updates the database according to extension requirements
+	 * DBAL compliant (based on Install Tool code)
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @return	void
+	 */
+	function forceDBupdates($extKey, $extInfo) {
+		$instObj = new t3lib_install;
+
+		// Updating tables and fields?
+		if (is_array($extInfo['files']) && in_array('ext_tables.sql', $extInfo['files'])) {
+			$fileContent = t3lib_div::getUrl(tx_em_Tools::getExtPath($extKey, $extInfo['type']) . 'ext_tables.sql');
+
+			$FDfile = $instObj->getFieldDefinitions_fileContent($fileContent);
+			if (count($FDfile)) {
+				$FDdb = $instObj->getFieldDefinitions_database(TYPO3_db);
+				$diff = $instObj->getDatabaseExtra($FDfile, $FDdb);
+				$update_statements = $instObj->getUpdateSuggestions($diff);
+
+				foreach ((array) $update_statements['add'] as $string) {
+					$GLOBALS['TYPO3_DB']->admin_query($string);
+				}
+				foreach ((array) $update_statements['change'] as $string) {
+					$GLOBALS['TYPO3_DB']->admin_query($string);
+				}
+				foreach ((array) $update_statements['create_table'] as $string) {
+					$GLOBALS['TYPO3_DB']->admin_query($string);
+				}
+			}
+		}
+
+		// Importing static tables?
+		if (is_array($extInfo['files']) && in_array('ext_tables_static+adt.sql', $extInfo['files'])) {
+			$fileContent = t3lib_div::getUrl(tx_em_Tools::getExtPath($extKey, $extInfo['type']) . 'ext_tables_static+adt.sql');
+
+			$statements = $instObj->getStatementarray($fileContent, 1);
+			list($statements_table, $insertCount) = $instObj->getCreateTables($statements, 1);
+
+			// Traverse the tables
+			foreach ($statements_table as $table => $query) {
+				$GLOBALS['TYPO3_DB']->admin_query('DROP TABLE IF EXISTS ' . $table);
+				$GLOBALS['TYPO3_DB']->admin_query($query);
+
+				if ($insertCount[$table]) {
+					$statements_insert = $instObj->getTableInsertStatements($statements, $table);
+
+					foreach ($statements_insert as $v) {
+						$GLOBALS['TYPO3_DB']->admin_query($v);
+					}
+				}
+			}
+		}
+	}
+
+
+	/************************************
+	 *
+	 * Various helper functions
+	 *
+	 ************************************/
+
+	/**
+	 * Returns subtitles for the extension listings
+	 *
+	 * @param	string		List order type
+	 * @param	string		Key value
+	 * @return	string		output.
+	 */
+	function listOrderTitle($listOrder, $key) {
+		switch ($listOrder) {
+			case 'cat':
+				return isset($this->categories[$key]) ? $this->categories[$key] : '[' . $key . ']';
+				break;
+			case 'author_company':
+				return $key;
+				break;
+			case 'state':
+				return $this->states[$key];
+				break;
+			case 'type':
+				return $this->typeDescr[$key];
+				break;
+		}
+	}
+
+
+	/**
+	 * Returns true if global OR local installation of extensions is allowed/possible.
+	 *
+	 * @return	boolean		Returns true if global OR local installation of extensions is allowed/possible.
+	 */
+	function importAtAll() {
+		return ($GLOBALS['TYPO3_CONF_VARS']['EXT']['allowGlobalInstall'] || $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowLocalInstall']);
+	}
+
+
+	/**
+	 * Searches for ->lookUpStr in extension and returns true if found (or if no search string is set)
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension content
+	 * @return	boolean		If true, display extension in list
+	 */
+	function searchExtension($extKey, $row) {
+		if ($this->lookUpStr) {
+			return (
+					stristr($extKey, $this->lookUpStr) ||
+							stristr($row['EM_CONF']['title'], $this->lookUpStr) ||
+							stristr($row['EM_CONF']['description'], $this->lookUpStr) ||
+							stristr($row['EM_CONF']['author'], $this->lookUpStr) ||
+							stristr($row['EM_CONF']['author_company'], $this->lookUpStr)
+			);
+		} else {
+			return true;
+		}
+	}
+
+
+	/**
+	 *  Checks if there are newer versions of installed extensions in the TER
+	 *  integrated from the extension "ter_update_check" for TYPO3 4.2 by Christian Welzel
+	 *
+	 * @return	nothing
+	 */
+	function checkForUpdates() {
+		global $LANG;
+		$content = '';
+
+		if (is_file(PATH_site . 'typo3temp/extensions.xml.gz')) {
+			$content = $this->extensionList->showExtensionsToUpdate()
+					. t3lib_BEfunc::getFuncCheck(0, 'SET[display_installed]', $this->MOD_SETTINGS['display_installed'], '', '', 'id="checkDisplayInstalled"')
+					. '&nbsp;<label for="checkDisplayInstalled">' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:display_nle') . '</label><br />'
+					. t3lib_BEfunc::getFuncCheck(0, 'SET[display_files]', $this->MOD_SETTINGS['display_files'], '', '', 'id="checkDisplayFiles"')
+					. '&nbsp;<label for="checkDisplayFiles">' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:display_files') . '</label>';
+			$this->content .= $this->doc->section($LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:header_upd_ext'), $content, 0, 1);
+
+			$dateFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'];
+			$timeFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'];
+			$content = sprintf($GLOBALS['LANG']->getLL('note_last_update_new'),
+				date(
+					$dateFormat . ', ' . $timeFormat,
+					filemtime(PATH_site . 'typo3temp/extensions.xml.gz')
+				)
+			) . '<br />';
+		}
+
+		$content .= sprintf($GLOBALS['LANG']->getLL('note_last_update2_new'),
+				'<a href="' . t3lib_div::linkThisScript(array(
+					'SET[function]' => 2
+				)) . '">', '</a>');
+		$this->content .= $this->doc->section($LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:header_vers_ret'), $content, 0, 1);
+	}
+
+
+	function showRepositoryUpdateForm() {
+		$content = '<div class="em-repupdate"><strong>Repository:</strong>';
+
+		// print registered repositories
+		/* @var $settings em_settings */
+		$settings = t3lib_div::makeInstance('tx_em_Settings');
+		$registeredRepos = $settings->getRegisteredRepositories();
+		$content .= '<select>';
+		foreach ($registeredRepos as $repository) {
+			$content .= '<option>' . $repository->getTitle() . '</option>';
+		}
+		$content .= '</select>';
+
+		$selectedRepo = $settings->getSelectedRepository();
+		/* @var $repoUtility em_repository_utility */
+		$repoUtility = t3lib_div::makeInstance('tx_em_Repository_Utility');
+		$repoUtility->setRepository($selectedRepo);
+
+		$onCLick = 'window.location.href="' . t3lib_div::linkThisScript(array(
+			'CMD[fetchMetaData]' => 'extensions'
+		)) . '";return false;';
+		$content .= '
+			<input type="button" value="' . $GLOBALS['LANG']->getLL('retrieve_update') .
+				'" onclick="' . htmlspecialchars($onCLick) . '" />';
+		if (is_file($repoUtility->getLocalExtListFile())) {
+			$dateFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'];
+			$timeFormat = $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'];
+
+			$count = tx_em_Database::getExtensionCountFromRepository($repoUtility->getRepositoryUID());
+			$content .= '<span style="margin-left:10px;padding-right: 50px;" class="typo3-message message-notice">' .
+					sprintf($GLOBALS['LANG']->getLL('ext_list_last_updated'),
+						date(
+							$dateFormat . ', ' . $timeFormat,
+							filemtime($repoUtility->getLocalExtListFile())
+						), $count) . '</span>';
+		} else {
+			$content .= '<span style="margin-left:10px;padding-right: 50px;" class="typo3-message message-error">There are no extensions available, please update!</span>';
+		}
+		$content .= '<br>&nbsp;<br>';
+
+		if ($this->CMD['fetchMetaData'] && $this->CMD['fetchMetaData'] == 'extensions') { // fetches mirror/extension data from online rep.
+			$content .= $repoUtility->updateExtList(TRUE)->render();
+		}
+
+		$content .= '</div>';
+		return $content;
+	}
+
+}
+
+// Make instance:
+$SOBE = t3lib_div::makeInstance('SC_mod_tools_em_index');
+$SOBE->init();
+foreach ($SOBE->include_once as $INC_FILE) {
+	include_once($INC_FILE);
+}
+$SOBE->checkExtObj();
+
+$SOBE->main();
+$SOBE->printContent();
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['em/index.php']) {
+	include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['em/index.php']);
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/exception/class.tx_em_extensionxml_exception.php
===================================================================
--- typo3/sysext/em/classes/exception/class.tx_em_extensionxml_exception.php	(revision )
+++ typo3/sysext/em/classes/exception/class.tx_em_extensionxml_exception.php	(revision )
@@ -0,0 +1,45 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
+*           Steffen Kamper <info@sk-typo3.de>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+/**
+ * Module: Extension manager - Extension.xml exception
+ *
+ * $Id: class.tx_em_extensionxml_exception.php 1870 2010-02-18 12:55:17Z mkrause $
+ */
+
+
+/**
+ * Exception for extension.xml handling.
+ *
+ * @author      Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author      Steffen Kamper <info@sk-typo3.de>
+ *
+ * @since       2010-02-10
+ * @package     TYPO3
+ * @subpackage  EM
+ */
+class tx_em_ExtensionXmlException extends tx_em_XmlException {
+
+}
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/repository/class.tx_em_repository_utility.php
===================================================================
--- typo3/sysext/em/classes/repository/class.tx_em_repository_utility.php	(revision )
+++ typo3/sysext/em/classes/repository/class.tx_em_repository_utility.php	(revision )
@@ -0,0 +1,372 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
+ *		   Steffen Kamper <info@sk-typo3.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * class.tx_em_repository_utility.php
+ *
+ * Module: Extension manager - Central repository utility functions
+ *
+ * $Id: class.tx_em_repository_utility.php 2082 2010-03-21 17:19:42Z steffenk $
+ *
+ * @author  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author  Steffen Kamper <info@sk-typo3.de>
+ */
+
+
+/**
+ * Central utility class for repository handling.
+ *
+ * @author	  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author	  Steffen Kamper <info@sk-typo3.de>
+ *
+ * @since	   2010-02-18
+ * @package	 TYPO3
+ * @subpackage  EM
+ */
+class tx_em_Repository_Utility implements t3lib_Singleton {
+
+
+	/**
+	 * ##########################################
+	 * Problem constants - to be used in bitmasks
+	 * ##########################################
+	 */
+	/**
+	 * Type of problem: extension file not existing in file system.
+	 *
+	 * @var  integer
+	 */
+	const PROBLEM_EXTENSION_FILE_NOT_EXISTING = 1;
+
+	/**
+	 * Type of problem: wrong hash indicates outdated extension file.
+	 *
+	 * @var  integer
+	 */
+	const PROBLEM_EXTENSION_HASH_CHANGED = 2;
+
+	/**
+	 * Type of problem: no version records in database.
+	 *
+	 * @var  integer
+	 */
+	const PROBLEM_NO_VERSIONS_IN_DATABASE = 4;
+
+
+	/**
+	 * Keeps instance of repository class.
+	 *
+	 * @var em_repository
+	 */
+	protected $repository = NULL;
+
+
+	/**
+	 * Class constructor.
+	 *
+	 * @access  public
+	 * @param   object  &$repository  (optional) instance of {@link em_repository repository} class
+	 * @return  void
+	 */
+	function __construct(&$repository = NULL) {
+		if ($repository != NULL && is_object($repository)
+				&& $repository instanceof tx_em_Repository) {
+			$this->setRepository($repository);
+		}
+	}
+
+	/**
+	 * Method provides a wrapper for throwing an exception.
+	 *
+	 * @access  protected
+	 * @see	 tx_em_ConnectionException
+	 * @param   string	 $message  the exception message to throw.
+	 * @param   integer	$code  the exception code.
+	 * @return  void
+	 */
+	protected function throwConnectionException($message = "", $code = 0) {
+		throw new tx_em_ConnectionException(get_class($this) . ': ' . $message, $code);
+	}
+
+	/**
+	 * Method registers required repository instance to work with.
+	 *
+	 * Repository instance is passed by reference.
+	 *
+	 * @access  public
+	 * @param   em_repository  &$repository  instance of {@link em_repository repository} class
+	 * @return  void
+	 * @see	 $repository
+	 */
+	public function setRepository(tx_em_Repository &$repository) {
+		$this->repository = $repository;
+	}
+
+	/**
+	 * Method fetches extension list file from remote server.
+	 *
+	 * Delegates to {@link fetchFile()}.
+	 *
+	 * @access  public
+	 * @return  void
+	 * @see	 fetchFile()
+	 */
+	public function fetchExtListFile() {
+		$this->fetchFile($this->getRemoteExtListFile(), $this->getLocalExtListFile());
+	}
+
+	/**
+	 * Method fetches mirror list file from remote server.
+	 *
+	 * Delegates to {@link fetchFile()}.
+	 *
+	 * @access  public
+	 * @return  void
+	 * @see	 fetchFile()
+	 */
+	public function fetchMirrorListFile() {
+		$this->fetchFile($this->getRemoteMirrorListFile(), $this->getLocalMirrorListFile());
+	}
+
+	/**
+	 * Method fetches contents from remote server and
+	 * writes them into a file in the local file system.
+	 *
+	 * @access  protected
+	 * @param   string  $remoteRessource  remote ressource to read contents from
+	 * @param   string  $localRessource   local ressource (absolute file path) to store retrieved contents to
+	 * @return  void
+	 * @see	 t3lib_div::getURL(), t3lib_div::writeFile()
+	 * @throws  tx_em_ConnectionException
+	 */
+	protected function fetchFile($remoteRessource, $localRessource) {
+		if (is_string($remoteRessource) && is_string($localRessource)
+				&& !empty($remoteRessource) && !empty($localRessource)) {
+			$fileContent = t3lib_div::getURL($remoteRessource, 0, array(TYPO3_user_agent));
+			if ($fileContent !== false) {
+				t3lib_div::writeFile($localRessource, $fileContent) || $this->throwConnectionException(sprintf('Could not write to file %s.', htmlspecialchars($localRessource)));
+			} else {
+				$this->throwConnectionException(sprintf('Could not access remote ressource %s.', htmlspecialchars($remoteRessource)));
+			}
+		}
+	}
+
+	/**
+	 * Method returns location of local extension list file.
+	 *
+	 * @access  public
+	 * @return  string  local location of file
+	 * @see	 getRemoteExtListFile()
+	 */
+	public function getLocalExtListFile() {
+		$absFilePath = PATH_site . 'typo3temp/'
+				. intval($this->repository->getId())
+				. '.extensions.xml.gz';
+		return $absFilePath;
+	}
+
+	/**
+	 * Method returns location of remote extension list file.
+	 *
+	 * @access  public
+	 * @return  string  remote location of file
+	 * @see	 getLocalExtListFile()
+	 */
+	public function getRemoteExtListFile() {
+		$mirror = $this->getMirrors(TRUE)->getMirror();
+		$filePath = 'http://' . $mirror['host'] . $mirror['path']
+				. 'extensions.xml.gz';
+		return $filePath;
+	}
+
+	/**
+	 * Method returns location of remote file containing
+	 * the extension checksum hash.
+	 *
+	 * @access  public
+	 * @return  string  remote location of file
+	 */
+	public function getRemoteExtHashFile() {
+		$mirror = $this->getMirrors(TRUE)->getMirror();
+		$filePath = 'http://' . $mirror['host'] . $mirror['path']
+				. 'extensions.md5';
+		return $filePath;
+	}
+
+	/**
+	 * Method returns location of local mirror list file.
+	 *
+	 * @access  public
+	 * @return  string  local location of file
+	 * @see	 getRemoteMirrorListFile()
+	 */
+	public function getLocalMirrorListFile() {
+		$absFilePath = PATH_site . 'typo3temp/'
+				. intval($this->repository->getId())
+				. '.mirrors.xml.gz';
+		return $absFilePath;
+	}
+
+	/**
+	 * Method returns location of remote mirror list file.
+	 *
+	 * @access  public
+	 * @return  string  remote location of file
+	 * @see	 getLocalMirrorListFile()
+	 */
+	public function getRemoteMirrorListFile() {
+		$filePath = $this->repository->getMirrorListUrl();
+		return $filePath;
+	}
+
+	/**
+	 * Method returns available mirrors for registered repository.
+	 *
+	 * If there are no mirrors registered to the repository,
+	 * the method will retrieve them from file system or remote
+	 * server.
+	 *
+	 * @access  public
+	 * @param   boolean  $forcedUpdateFromRemote  if boolean true, mirror configuration will always retrieved from remote server
+	 * @return  em_repository_mirrors  instance of repository mirrors class
+	 */
+	public function getMirrors($forcedUpdateFromRemote = TRUE) {
+		$assignedMirror = $this->repository->getMirrors();
+		if ($forcedUpdateFromRemote || is_null($assignedMirror) || !is_object($assignedMirror)) {
+			if ($forcedUpdateFromRemote || !is_file($this->getLocalMirrorListFile())) {
+				$this->fetchMirrorListFile();
+			}
+			$objMirrorListImporter = t3lib_div::makeInstance('tx_em_Import_MirrorListImporter');
+			$this->repository->addMirrors($objMirrorListImporter->getMirrors($this->getLocalMirrorListFile()));
+		}
+		return $this->repository->getMirrors();
+	}
+
+	/**
+	 * Method returns information if currently available
+	 * extension list might be outdated.
+	 *
+	 * @access  public
+	 * @see	 em_repository_utility::PROBLEM_NO_VERSIONS_IN_DATABASE,
+	 *		  em_repository_utility::PROBLEM_EXTENSION_FILE_NOT_EXISTING,
+	 *		  em_repository_utility::PROBLEM_EXTENSION_HASH_CHANGED
+	 * @return  integer  integer "0" if everything is perfect, otherwise bitmask with occured problems
+	 * @see	 updateExtList()
+	 */
+	public function isExtListUpdateNecessary() {
+		$updateNecessity = 0;
+
+		if (tx_em_Database::getExtensionCountFromRepository($this->getRepositoryUID(TRUE)) <= 0) {
+			$updateNecessity |= self::PROBLEM_NO_VERSIONS_IN_DATABASE;
+		}
+
+		if (!is_file($this->getLocalExtListFile())) {
+			$updateNecessity |= self::PROBLEM_EXTENSION_FILE_NOT_EXISTING;
+		} else {
+			$remotemd5 = t3lib_div::getURL($this->getRemoteExtHashFile(), 0, array(TYPO3_user_agent));
+
+			if ($remotemd5 !== false) {
+				$localmd5 = md5_file($this->getLocalExtListFile());
+				if ($remotemd5 !== $localmd5) {
+					$updateNecessity |= self::PROBLEM_EXTENSION_HASH_CHANGED;
+				}
+			} else {
+				$this->throwConnectionException('Could not retrieve extension hash file from remote server.');
+			}
+		}
+		return $updateNecessity;
+	}
+
+	/**
+	 * Method returns UID of the current repository.
+	 *
+	 * @access  public
+	 * @param   boolean	$insertIfMissing  creates repository record in DB if set to TRUE
+	 * @return  integer
+	 */
+	public function getRepositoryUID($insertIfMissing = FALSE) {
+		$uid = NULL;
+		$repos = tx_em_Database::getRepositoryByUID($this->repository->getId());
+
+		if (empty($repos) && $insertIfMissing) {
+			$uid = tx_em_Database::insertRepository($this->repository);
+		} else {
+			$uid = intval($repos[0]['uid']);
+		}
+		return $uid;
+	}
+
+	/**
+	 * Method updates TYPO3 database with up-to-date
+	 * extension version records.
+	 *
+	 * @access  public
+	 * @param   boolean  $renderFlashMessage  if method should return flashmessage or raw integer
+	 * @return  mixed	either sum of imported extensions or instance of t3lib_FlashMessage
+	 * @see	 isExtListUpdateNecessary()
+	 */
+	public function updateExtList($renderFlashMessage = FALSE) {
+
+		if ($renderFlashMessage) {
+			/* @var $flashMessage t3lib_FlashMessage */
+			$flashMessage = t3lib_div::makeInstance('t3lib_FlashMessage', '');
+			$flashMessage->setTitle($GLOBALS['LANG']->getLL('ext_import_list_unchanged'));
+			$flashMessage->setMessage($GLOBALS['LANG']->getLL('ext_import_list_unchanged_header'));
+			$flashMessage->setSeverity(t3lib_FlashMessage::INFO);
+		}
+		$sumRecords = 0;
+
+		$updateNecessity = $this->isExtListUpdateNecessary();
+		if ($updateNecessity != 0) {
+			// retrieval of file necessary
+			$tmpBitmask = (self::PROBLEM_EXTENSION_FILE_NOT_EXISTING | self::PROBLEM_EXTENSION_HASH_CHANGED);
+			if (($tmpBitmask & $updateNecessity) > 0) {
+				$this->fetchExtListFile();
+				$updateNecessity &= ~$tmpBitmask;
+			}
+
+			// database table cleanup
+			if (($updateNecessity & self::PROBLEM_NO_VERSIONS_IN_DATABASE)) {
+				$updateNecessity &= ~self::PROBLEM_NO_VERSIONS_IN_DATABASE;
+			} else {
+				$GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_extensions', 'repository=' . $this->getRepositoryUID());
+			}
+
+			// no further problems - start of import process
+			if ($updateNecessity == 0) {
+				$objExtListImporter = t3lib_div::makeInstance('tx_em_Import_MirrorListImporter');
+				$objExtListImporter->import($this->getLocalExtListFile(), $this->getRepositoryUID(TRUE));
+				$sumRecords = tx_em_Database::getExtensionCountFromRepository($this->getRepositoryUID());
+				if ($renderFlashMessage) {
+					$flashMessage->setTitle($GLOBALS['LANG']->getLL('ext_import_extlist_updated_header'));
+					$flashMessage->setMessage(sprintf($GLOBALS['LANG']->getLL('ext_import_extlist_updated'), tx_em_Database::getExtensionCountFromRepository()));
+					$flashMessage->setSeverity(t3lib_FlashMessage::OK);
+				}
+			}
+		}
+		return $renderFlashMessage ? $flashMessage : $sumRecords;
+	}
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/tasks/class.em_tasks_updateextensionlist.php
===================================================================
--- typo3/sysext/em/classes/tasks/class.em_tasks_updateextensionlist.php	(revision 9222)
+++ typo3/sysext/em/classes/tasks/class.tx_em_tasks_updateextensionlist.php	(revision )
@@ -1,26 +1,26 @@
 <?php
 /***************************************************************
-*  Copyright notice
-*
-*  (c) 2010 Christian Kuhn <lolli@schwarzbu.ch>
-*  All rights reserved
-*
-*  This script is part of the TYPO3 project. The TYPO3 project is
-*  free software; you can redistribute it and/or modify
-*  it under the terms of the GNU General Public License as published by
-*  the Free Software Foundation; either version 2 of the License, or
-*  (at your option) any later version.
-*
-*  The GNU General Public License can be found at
-*  http://www.gnu.org/copyleft/gpl.html.
-*
-*  This script is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  This copyright notice MUST APPEAR in all copies of the script!
-***************************************************************/
+ *  Copyright notice
+ *
+ *  (c) 2010 Christian Kuhn <lolli@schwarzbu.ch>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
 
 /**
  * Update extension list task
@@ -29,23 +29,23 @@
  * @package TYPO3
  * @subpackage em
  */
-class em_tasks_UpdateExtensionList extends tx_scheduler_Task {
+class tx_em_Tasks_UpdateExtensionList extends tx_scheduler_Task {
 	/**
 	 * Public method, usually called by scheduler.
 	 *
 	 * @return boolean True on success
 	 */
 	public function execute() {
-			// Throws exceptions if something goes wrong
+		// Throws exceptions if something goes wrong
 		$this->updateExtensionlist();
 
-		return(TRUE);
+		return (TRUE);
 	}
 
 	/**
 	 * Update extension list
 	 *
-	 * @throws em_connection_Exception if fetch from mirror fails
+	 * @throws tx_em_ConnectionException if fetch from mirror fails
 	 * @return void
 	 */
 	protected function updateExtensionlist() {
@@ -65,7 +65,7 @@
 		$mirror = $extensionManager->getMirrorURL();
 		$remoteMd5 = t3lib_div::getURL($mirror . 'extensions.md5', 0, array(TYPO3_user_agent));
 		if (!$remoteMd5) {
-			throw new em_connection_Exception(
+			throw new tx_em_ConnectionException(
 				'Unable to fetch extension list md5 file from remote mirror.',
 				1288121556
 			);
@@ -77,7 +77,7 @@
 			$remoteXml = t3lib_div::getURL($mirror . 'extensions.xml.gz', 0, array(TYPO3_user_agent));
 
 			if (!$remoteXml) {
-				throw new em_connection_Exception(
+				throw new tx_em_ConnectionException(
 					'Unable to fetch extension list XML file from remote mirror.',
 					1288121557
 				);
@@ -89,8 +89,8 @@
 	}
 }
 
-if (defined('TYPO3_MODE') && $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/em/classes/tasks/class.em_tasks_updateextensionlist.php']) {
-	include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/em/classes/tasks/class.em_tasks_updateextensionlist.php']);
+if (defined('TYPO3_MODE') && $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/em/classes/tasks/class.tx_em_tasks_updateextensionlist.php']) {
+	include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/em/classes/tasks/class.tx_em_tasks_updateextensionlist.php']);
 }
 
 ?>
Index: typo3/sysext/em/classes/conf.php
===================================================================
--- typo3/sysext/em/classes/conf.php	(revision )
+++ typo3/sysext/em/classes/conf.php	(revision )
@@ -0,0 +1,12 @@
+<?php
+define('TYPO3_MOD_PATH', 'typo3/sysext/em/');
+$BACK_PATH='';
+
+$MLANG['default']['tabs_images']['tab'] = 'em.gif';
+$MLANG['default']['ll_ref'] = 'LLL:EXT:em/language/locallang.xml';
+
+$MCONF['script']='_DISPATCH';
+$MCONF['access']='admin';
+$MCONF['name']='tools_em';
+$MCONF['workspaces']='online';
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/connection/class.tx_em_connection_ter.php
===================================================================
--- typo3/sysext/em/classes/connection/class.tx_em_connection_ter.php	(revision )
+++ typo3/sysext/em/classes/connection/class.tx_em_connection_ter.php	(revision )
@@ -0,0 +1,365 @@
+<?php
+/* **************************************************************
+*  Copyright notice
+*
+*  (c) 1999-2010 Kasper Skårhøj (kasperYYYY@typo3.com)
+*  (c) 2006-2010 Karsten Dambekalns <karsten@typo3.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+
+/**
+ * TER2 connection handling class for the TYPO3 Extension Manager.
+ *
+ * It contains methods for downloading and uploading extensions and related code
+ *
+ * @author Karsten Dambekalns <karsten@typo3.org>
+ * @author	Kasper Skårhøj <kasperYYYY@typo3.com>
+ * @package TYPO3
+ * @subpackage EM
+ */
+class tx_em_Connection_Ter {
+	var $wsdlURL;
+
+	/**
+	 * Extension manager module
+	 *
+	 * @var SC_mod_tools_em_index
+	 */
+	var $emObj;
+
+	public function __construct($emObj) {
+		$this->emObj = $emObj;
+	}
+
+	/**
+	 * Fetches an extension from the given mirror
+	 *
+	 * @param	string		$extKey	Extension Key
+	 * @param	string		$version	Version to install
+	 * @param	string		$expectedMD5	Expected MD5 hash of extension file
+	 * @param	string		$mirrorURL	URL of mirror to use
+	 * @return	mixed		T3X data (array) or error message (string)
+	 */
+	function fetchExtension($extKey, $version, $expectedMD5, $mirrorURL) {
+		$extPath = t3lib_div::strtolower($extKey);
+		$mirrorURL .= $extPath{0} . '/' . $extPath{1} . '/' . $extPath . '_' . $version . '.t3x';
+		$t3x = t3lib_div::getURL($mirrorURL, 0, array(TYPO3_user_agent));
+		$MD5 = md5($t3x);
+
+		if ($t3x === FALSE) {
+			return 'The T3X file could not be fetched. Possible reasons: network problems, allow_url_fopen is off, curl is not enabled in Install tool.';
+		}
+
+		if ($MD5 == $expectedMD5) {
+			// Fetch and return:
+			return $this->decodeExchangeData($t3x);
+		} else {
+			return 'Error: MD5 hash of downloaded file not as expected:<br />' . $MD5 . ' != ' . $expectedMD5;
+		}
+	}
+
+	/**
+	 * Fetches an extensions l10n file from the given mirror
+	 *
+	 * @param string $extKey	Extension Key
+	 * @param string $lang	The language code of the translation to fetch
+	 * @param string $mirrorURL	URL of mirror to use
+	 * @return mixed	Array containing l10n data or error message (string)
+	 */
+	function fetchTranslation($extKey, $lang, $mirrorURL) {
+		$extPath = t3lib_div::strtolower($extKey);
+		$mirrorURL .= $extPath{0} . '/' . $extPath{1} . '/' . $extPath . '-l10n/' . $extPath . '-l10n-' . $lang . '.zip';
+		$l10n = t3lib_div::getURL($mirrorURL, 0, array(TYPO3_user_agent));
+
+		if ($l10n !== false) {
+			return array($l10n);
+		} else {
+			return 'Error: Translation could not be fetched.';
+		}
+	}
+
+	/**
+	 * Install translations for all selected languages for an extension
+	 *
+	 * @param string $extKey		The extension key to install the translations for
+	 * @param string $lang		Language code of translation to fetch
+	 * @param string $mirrorURL		Mirror URL to fetch data from
+	 * @return mixed	true on success, error string on fauilure
+	 */
+	function updateTranslation($extKey, $lang, $mirrorURL) {
+		$l10n = $this->fetchTranslation($extKey, $lang, $mirrorURL);
+		if (is_array($l10n)) {
+			$file = PATH_site . 'typo3temp/' . $extKey . '-l10n-' . $lang . '.zip';
+			$path = 'l10n/' . $lang . '/';
+			if (!is_dir(PATH_typo3conf . $path)) {
+				t3lib_div::mkdir_deep(PATH_typo3conf, $path);
+			}
+			t3lib_div::writeFile($file, $l10n[0]);
+			if (tx_em_Tools::unzip($file, PATH_typo3conf . $path)) {
+				return TRUE;
+			}
+		}
+		return FALSE;
+	}
+
+	/**
+	 * Fetches extension l10n status from the given mirror
+	 *
+	 * @param string	 $extKey	Extension Key
+	 * @param string	 $mirrorURL	URL of mirror to use
+	 * @return mixed	Array containing l10n status data or FALSE if no status could be fetched
+	 */
+	function fetchTranslationStatus($extKey, $mirrorURL) {
+		$extPath = t3lib_div::strtolower($extKey);
+		$mirrorURL .= $extPath{0} . '/' . $extPath{1} . '/' . $extPath . '-l10n/' . $extPath . '-l10n.xml';
+		$remote = t3lib_div::getURL($mirrorURL, 0, array(TYPO3_user_agent));
+
+		if ($remote !== false) {
+			$parsed = $this->emObj->xmlhandler->parseL10nXML($remote);
+			return $parsed['languagePackIndex'];
+		}
+
+		return FALSE;
+	}
+
+	/**
+	 * Decode server data
+	 * This is information like the extension list, extension information etc., return data after uploads (new em_conf)
+	 *
+	 * @param	string		Data stream from remove server
+	 * @return	mixed		On success, returns an array with data array and stats array as key 0 and 1. Otherwise returns error string
+	 * @see fetchServerData(), processRepositoryReturnData()
+	 */
+	function decodeServerData($externalData) {
+		$parts = explode(':', $externalData, 4);
+		$dat = base64_decode($parts[2]);
+		// compare hashes ignoring any leading whitespace. See bug #0000365.
+		if (ltrim($parts[0]) == md5($dat)) {
+			if ($parts[1] == 'gzcompress') {
+				if (function_exists('gzuncompress')) {
+					$dat = gzuncompress($dat);
+				} else {
+					return 'Decoding Error: No decompressor available for compressed content. gzuncompress() function is not available!';
+				}
+			}
+			$listArr = unserialize($dat);
+
+			if (is_array($listArr)) {
+				return $listArr;
+			} else {
+				return 'Error: Unserialized information was not an array - strange!';
+			}
+		} else {
+			return 'Error: MD5 hashes in T3X data did not match!';
+		}
+	}
+
+	/**
+	 * Decodes extension upload array.
+	 * This kind of data is when an extension is uploaded to TER
+	 *
+	 * @param	string		Data stream
+	 * @return	mixed		Array with result on success, otherwise an error string.
+	 */
+	function decodeExchangeData($str) {
+		$parts = explode(':', $str, 3);
+		if ($parts[1] == 'gzcompress') {
+			if (function_exists('gzuncompress')) {
+				$parts[2] = gzuncompress($parts[2]);
+			} else {
+				return 'Decoding Error: No decompressor available for compressed content. gzcompress()/gzuncompress() functions are not available!';
+			}
+		}
+		if (md5($parts[2]) == $parts[0]) {
+			$output = unserialize($parts[2]);
+			if (is_array($output)) {
+				return array($output, '');
+			} else {
+				return 'Error: Content could not be unserialized to an array. Strange (since MD5 hashes match!)';
+			}
+		} else {
+			return 'Error: MD5 mismatch. Maybe the extension file was downloaded and saved as a text file by the browser and thereby corrupted!? (Always select "All" filetype when saving extensions)';
+		}
+	}
+
+
+	/**
+	 * Encodes extension upload array
+	 *
+	 * @param	array		Array containing extension
+	 * @return	string		Content stream
+	 */
+	function makeUploadDataFromarray($uploadArray) {
+		if (is_array($uploadArray)) {
+			$serialized = serialize($uploadArray);
+			$md5 = md5($serialized);
+
+			$content = $md5 . ':';
+			$content .= 'gzcompress:';
+			$content .= gzcompress($serialized);
+		}
+		return $content;
+	}
+
+	/**
+	 * [Describe function...]
+	 *
+	 * @param	[type]		$em: ...
+	 * @return	[type]		...
+	 */
+	function uploadToTER($em) {
+		$uArr = $this->emObj->makeUploadarray($em['extKey'], $em['extInfo']);
+		if (!is_array($uArr)) {
+			return $uArr;
+		}
+
+		// Render new version number:
+		$newVersionBase = $em['extInfo']['EM_CONF']['version'];
+		switch ((string) $em['upload']['mode']) {
+			case 'new_dev':
+				$cmd = 'dev';
+				break;
+			case 'new_sub':
+				$cmd = 'sub';
+				break;
+			case 'new_main':
+				$cmd = 'main';
+				break;
+			case 'custom':
+				$newVersionBase = $em['upload']['version'];
+			case 'latest':
+			default:
+				$cmd = '';
+				break;
+		}
+		$versionArr = tx_em_Tools::renderVersion($newVersionBase, $cmd);
+		$em['version'] = $versionArr['version'];
+
+		// Create dependency / conflict information:
+		$dependenciesArr = array();
+		$extKeysArr = $uArr['EM_CONF']['constraints']['depends'];
+
+		if (is_array($extKeysArr)) {
+			foreach ($extKeysArr as $extKey => $version) {
+				if (strlen($extKey)) {
+					$dependenciesArr[] = array(
+						'kind' => 'depends',
+						'extensionKey' => utf8_encode($extKey),
+						'versionRange' => utf8_encode($version),
+					);
+				}
+			}
+		}
+
+		$extKeysArr = $uArr['EM_CONF']['constraints']['conflicts'];
+		if (is_array($extKeysArr)) {
+			foreach ($extKeysArr as $extKey => $version) {
+				if (strlen($extKey)) {
+					$dependenciesArr[] = array(
+						'kind' => 'conflicts',
+						'extensionKey' => utf8_encode($extKey),
+						'versionRange' => utf8_encode($version),
+					);
+				}
+			}
+		}
+		// FIXME: This part must be removed, when the problem is solved on the TER-Server #5919
+		if (count($dependenciesArr) == 1) {
+			$dependenciesArr[] = array(
+				'kind' => 'depends',
+				'extensionKey' => '',
+				'versionRange' => '',
+			);
+		}
+		// END for Bug #5919
+
+		// Compile data for SOAP call:
+		$accountData = array(
+			'username' => $em['user']['fe_u'],
+			'password' => $em['user']['fe_p']
+		);
+		$extensionData = array(
+			'extensionKey' => utf8_encode($em['extKey']),
+			'version' => utf8_encode($em['version']),
+			'metaData' => array(
+				'title' => utf8_encode($uArr['EM_CONF']['title']),
+				'description' => utf8_encode($uArr['EM_CONF']['description']),
+				'category' => utf8_encode($uArr['EM_CONF']['category']),
+				'state' => utf8_encode($uArr['EM_CONF']['state']),
+				'authorName' => utf8_encode($uArr['EM_CONF']['author']),
+				'authorEmail' => utf8_encode($uArr['EM_CONF']['author_email']),
+				'authorCompany' => utf8_encode($uArr['EM_CONF']['author_company']),
+			),
+			'technicalData' => array(
+				'dependencies' => $dependenciesArr,
+				'loadOrder' => utf8_encode($uArr['EM_CONF']['loadOrder']),
+				'uploadFolder' => (boolean) intval($uArr['EM_CONF']['uploadfolder']),
+				'createDirs' => utf8_encode($uArr['EM_CONF']['createDirs']),
+				'shy' => (boolean) intval($uArr['EM_CONF']['shy']),
+				'modules' => utf8_encode($uArr['EM_CONF']['module']),
+				'modifyTables' => utf8_encode($uArr['EM_CONF']['modify_tables']),
+				'priority' => utf8_encode($uArr['EM_CONF']['priority']),
+				'clearCacheOnLoad' => (boolean) intval($uArr['EM_CONF']['clearCacheOnLoad']),
+				'lockType' => utf8_encode($uArr['EM_CONF']['lockType']),
+			),
+			'infoData' => array(
+				'codeLines' => intval($uArr['misc']['codelines']),
+				'codeBytes' => intval($uArr['misc']['codebytes']),
+				'codingGuidelinesCompliance' => utf8_encode($uArr['EM_CONF']['CGLcompliance']),
+				'codingGuidelinesComplianceNotes' => utf8_encode($uArr['EM_CONF']['CGLcompliance_note']),
+				'uploadComment' => utf8_encode($em['upload']['comment']),
+				'techInfo' => $uArr['techInfo'],
+			),
+		);
+
+		$filesData = array();
+		foreach ($uArr['FILES'] as $filename => $infoArr) {
+			$filesData[] = array(
+				'name' => utf8_encode($infoArr['name']),
+				'size' => intval($infoArr['size']),
+				'modificationTime' => intval($infoArr['mtime']),
+				'isExecutable' => intval($infoArr['is_executable']),
+				'content' => $infoArr['content'],
+				'contentMD5' => $infoArr['content_md5'],
+			);
+		}
+
+		$soap = t3lib_div::makeInstance('tx_em_Connection_Soap');
+		$soap->init(array('wsdl' => $this->wsdlURL, 'soapoptions' => array('trace' => 1, 'exceptions' => 0)));
+		$response = $soap->call('uploadExtension', array('accountData' => $accountData, 'extensionData' => $extensionData, 'filesData' => $filesData));
+
+		if ($response===false) {
+			switch (true) {
+				case is_string($soap->error):
+					return $soap->error;
+					break;
+				default:
+					return $soap->error->faultstring;
+			}
+		}
+
+		return $response;
+	}
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/exception/class.tx_em_mirrorxml_exception.php
===================================================================
--- typo3/sysext/em/classes/exception/class.tx_em_mirrorxml_exception.php	(revision )
+++ typo3/sysext/em/classes/exception/class.tx_em_mirrorxml_exception.php	(revision )
@@ -0,0 +1,45 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
+*           Steffen Kamper <info@sk-typo3.de>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+/**
+ * Module: Extension manager - Extension.xml exception
+ *
+ * $Id: class.tx_em_mirrorxml_exception.php 1883 2010-02-19 13:45:32Z mkrause $
+ */
+
+
+/**
+ * Exception for extension.xml handling.
+ *
+ * @author      Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author      Steffen Kamper <info@sk-typo3.de>
+ *
+ * @since       2010-02-18
+ * @package     TYPO3
+ * @subpackage  EM
+ */
+class tx_em_MirrorXmlException extends tx_em_XmlException {
+
+}
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/parser/class.tx_em_parser_mirrorxmlpullparser.php
===================================================================
--- typo3/sysext/em/classes/parser/class.tx_em_parser_mirrorxmlpullparser.php	(revision )
+++ typo3/sysext/em/classes/parser/class.tx_em_parser_mirrorxmlpullparser.php	(revision )
@@ -0,0 +1,228 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
+ *		   Steffen Kamper <info@sk-typo3.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * class.tx_em_parser_mirrorxmlpullparser.php
+ *
+ * Module: Extension manager - mirrors.xml pull-parser
+ *
+ * $Id: class.tx_em_parser_mirrorxmlpullparser.php 1913 2010-02-21 15:47:37Z mkrause $
+ *
+ * @author  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author  Steffen Kamper <info@sk-typo3.de>
+ */
+
+
+/**
+ * Parser for TYPO3's mirrors.xml file.
+ *
+ * Depends on PHP ext/xmlreader which should be available
+ * with PHP >= 5.1.0.
+ *
+ * @author	  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author	  Steffen Kamper <info@sk-typo3.de>
+ *
+ * @since	   2010-02-19
+ * @package	 TYPO3
+ * @subpackage  EM
+ */
+class tx_em_Parser_MirrorXmlPullParser extends tx_em_Parser_MirrorXmlAbstractParser implements SplSubject {
+
+
+	/**
+	 * Keeps list of attached observers.
+	 *
+	 * @var  array
+	 */
+	protected $observers = array();
+
+
+	/**
+	 * Class constructor.
+	 *
+	 * @access  public
+	 * @return  void
+	 */
+	function __construct() {
+		$this->requiredPHPExt = 'xmlreader';
+
+		if ($this->isAvailable()) {
+			$this->objXML = new XMLReader();
+		}
+	}
+
+	/**
+	 * Method parses an extensions.xml file.
+	 *
+	 * @access  public
+	 * @param   string  $file  file resource, typically a stream
+	 * @return  void
+	 * @throws  em_mirrorxml_Exception  in case of XML parser errors
+	 */
+	public function parseXML($file) {
+		if (!(is_object($this->objXML) && (get_class($this->objXML) == 'XMLReader'))) {
+			$this->throwException('Unable to create XML parser.');
+		}
+		$this->objXML->open($file, 'utf-8') || $this->throwException(sprintf('Unable to open file ressource %s.', htmlspecialchars($file)));
+
+		while ($this->objXML->read()) {
+
+			if ($this->objXML->nodeType == XMLReader::ELEMENT) {
+				$this->startElement($this->objXML->name);
+			} else {
+				if ($this->objXML->nodeType == XMLReader::END_ELEMENT) {
+					$this->endElement($this->objXML->name);
+				} else {
+					continue;
+				}
+			}
+		}
+		$this->objXML->close();
+	}
+
+	/**
+	 * Method is invoked when parser accesses start tag of an element.
+	 *
+	 * @access  protected
+	 * @param   string	 $elementName  element name at parser's current position
+	 * @return  void
+	 * @see	 endElement()
+	 */
+	protected function startElement($elementName) {
+		switch ($elementName) {
+			case 'title':
+				$this->title = $this->getElementValue($elementName);
+				break;
+			case 'host':
+				$this->host = $this->getElementValue($elementName);
+				break;
+			case 'path':
+				$this->path = $this->getElementValue($elementName);
+				break;
+			case 'country':
+				$this->country = $this->getElementValue($elementName);
+				break;
+			case 'name':
+				$this->sponsorname = $this->getElementValue($elementName);
+				break;
+			case 'link':
+				$this->sponsorlink = $this->getElementValue($elementName);
+				break;
+			case 'logo':
+				$this->sponsorlogo = $this->getElementValue($elementName);
+				break;
+		}
+	}
+
+	/**
+	 * Method is invoked when parser accesses end tag of an element.
+	 *
+	 * @access  protected
+	 * @param   string	 $elementName  element name at parser's current position
+	 * @return  void
+	 * @see	 startElement()
+	 */
+	protected function endElement($elementName) {
+		switch ($elementName) {
+			case 'mirror':
+				$this->notify();
+				$this->resetProperties();
+				break;
+		}
+	}
+
+	/**
+	 * Method returns the value of an element at XMLReader's current
+	 * position.
+	 *
+	 * Method will read until it finds the end of the given element.
+	 * If element has no value, method returns NULL.
+	 *
+	 * @access  protected
+	 * @param   string	 $elementName  name of element to retrieve it's value from
+	 * @return  string	 an element's value if it has a value, otherwise NULL
+	 */
+	protected function getElementValue(&$elementName) {
+		$value = NULL;
+		if (!$this->objXML->isEmptyElement) {
+			$value = '';
+			while ($this->objXML->read()) {
+				if ($this->objXML->nodeType == XMLReader::TEXT
+						|| $this->objXML->nodeType == XMLReader::CDATA
+						|| $this->objXML->nodeType == XMLReader::WHITESPACE
+						|| $this->objXML->nodeType == XMLReader::SIGNIFICANT_WHITESPACE) {
+					$value .= $this->objXML->value;
+				} else {
+					if ($this->objXML->nodeType == XMLReader::END_ELEMENT
+							&& $this->objXML->name === $elementName) {
+						break;
+					}
+				}
+			}
+		}
+		return $value;
+	}
+
+	/**
+	 * Method attaches an observer.
+	 *
+	 * @access  public
+	 * @param   SplObserver  $observer  an observer to attach
+	 * @return  void
+	 * @see	 $observers, detach(), notify()
+	 */
+	public function attach(SplObserver $observer) {
+		$this->observers[] = $observer;
+	}
+
+	/**
+	 * Method detaches an attached observer
+	 *
+	 * @access  public
+	 * @param   SplObserver  $observer  an observer to detach
+	 * @return  void
+	 * @see	 $observers, attach(), notify()
+	 */
+	public function detach(SplObserver $observer) {
+		$key = array_search($observer, $this->observers, true);
+		if (!($key === false)) {
+			unset($this->observers[$key]);
+		}
+	}
+
+	/**
+	 * Method notifies attached observers.
+	 *
+	 * @access  public
+	 * @return  void
+	 * @see	 $observers, attach(), detach()
+	 */
+	public function notify() {
+		foreach ($this->observers as $observer) {
+			$observer->update($this);
+		}
+	}
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/parser/class.tx_em_parser_extensionxmlabstractparser.php
===================================================================
--- typo3/sysext/em/classes/parser/class.tx_em_parser_extensionxmlabstractparser.php	(revision )
+++ typo3/sysext/em/classes/parser/class.tx_em_parser_extensionxmlabstractparser.php	(revision )
@@ -0,0 +1,431 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
+ *		   Steffen Kamper <info@sk-typo3.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * class.tx_em_parser_extensionxmlabstractparser.php
+ *
+ * Module: Extension manager - Extension.xml abstract parser
+ *
+ * $Id: class.tx_em_parser_extensionxmlabstractparser.php 1913 2010-02-21 15:47:37Z mkrause $
+ *
+ * @author  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author  Steffen Kamper <info@sk-typo3.de>
+ */
+
+/**
+ * Abstract parser for TYPO3's extension.xml file.
+ *
+ * @author	  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author	  Steffen Kamper <info@sk-typo3.de>
+ *
+ * @since	   2010-02-09
+ * @package	 TYPO3
+ * @subpackage  EM
+ */
+abstract class tx_em_Parser_ExtensionXmlAbstractParser extends tx_em_Parser_XmlAbstractParser {
+
+
+	/**
+	 * Keeps current author company of an extension's version.
+	 *
+	 * @var  string
+	 */
+	protected $authorcompany = NULL;
+
+	/**
+	 * Keeps current author mail address of an extension's version.
+	 *
+	 * @var  string
+	 */
+	protected $authoremail = NULL;
+
+	/**
+	 * Keeps current author name of an extension's version.
+	 *
+	 * @var  string
+	 */
+	protected $authorname = NULL;
+
+	/**
+	 * Keeps current category of an extension's version.
+	 *
+	 * @var  string
+	 */
+	protected $category = NULL;
+
+	/**
+	 * Keeps current dependencies of an extension's version.
+	 *
+	 * @var  string
+	 */
+	protected $dependencies = NULL;
+
+	/**
+	 * Keeps current description of an extension's version.
+	 *
+	 * @var  string
+	 */
+	protected $description = NULL;
+
+	/**
+	 * Keeps current download number sum of all extension's versions.
+	 *
+	 * @var  string
+	 */
+	protected $extensionDLCounter = NULL;
+
+	/**
+	 * Keeps current key of an extension.
+	 *
+	 * @var string
+	 */
+	protected $extensionKey = NULL;
+
+	/**
+	 * Keeps current upload date of an extension's version.
+	 *
+	 * @var  string
+	 */
+	protected $lastuploaddate = NULL;
+
+	/**
+	 * Keeps current owner username of an extension's version.
+	 *
+	 * @var  string
+	 */
+	protected $ownerusername = NULL;
+
+	/**
+	 * Keeps current reviewstate of an extension's version.
+	 *
+	 * @var  string
+	 */
+	protected $reviewstate = NULL;
+
+	/**
+	 * Keeps current state of an extension's version.
+	 *
+	 * @var  string
+	 */
+	protected $state = NULL;
+
+	/**
+	 * Keeps current t3x file hash of an extension's version.
+	 *
+	 * @var  string
+	 */
+	protected $t3xfilemd5 = NULL;
+
+	/**
+	 * Keeps current title of an extension's version.
+	 *
+	 * @var  string
+	 */
+	protected $title = NULL;
+
+	/**
+	 * Keeps current upload comment of an extension's version.
+	 *
+	 * @var  string
+	 */
+	protected $uploadcomment = NULL;
+
+	/**
+	 * Keeps current version number.
+	 *
+	 * @var string
+	 */
+	protected $version = NULL;
+
+	/**
+	 * Keeps current download number of an extension's version.
+	 *
+	 * @var  string
+	 */
+	protected $versionDLCounter = NULL;
+
+
+	/**
+	 * Returns an assoziative array of all extension version properties.
+	 *
+	 * Valid array keys of returned array are:
+	 * extkey, version, alldownloadcounter, downloadcounter, title, description,
+	 * state, reviewstate, category, lastuploaddate, uploadcomment, dependencies,
+	 * authorname, authoremail, authorcompany, ownerusername, t3xfilemd5
+	 *
+	 * @access  public
+	 * @see	 $extensionKey, $version, $extensionDLCounter, $versionDLCounter,
+	 *		  $title, $description, $state, $reviewstate, $category,
+	 *		  $lastuploaddate, $uploadcomment, $dependencies, $authorname,
+	 *		  $authoremail, $authorcompany, $ownerusername, $t3xfilemd5
+	 * @return  array  assoziative array of an extension version's properties
+	 */
+	public function getAll() {
+		$versionProperties = array();
+		$versionProperties['extkey'] = $this->extensionKey;
+		$versionProperties['version'] = $this->version;
+		$versionProperties['alldownloadcounter'] = $this->extensionDLCounter;
+		$versionProperties['downloadcounter'] = $this->versionDLCounter;
+		$versionProperties['title'] = $this->title;
+		$versionProperties['description'] = $this->description;
+		$versionProperties['state'] = $this->state;
+		$versionProperties['reviewstate'] = $this->reviewstate;
+		$versionProperties['category'] = $this->category;
+		$versionProperties['lastuploaddate'] = $this->lastuploaddate;
+		$versionProperties['uploadcomment'] = $this->uploadcomment;
+		$versionProperties['dependencies'] = $this->dependencies;
+		$versionProperties['authorname'] = $this->authorname;
+		$versionProperties['authoremail'] = $this->authoremail;
+		$versionProperties['authorcompany'] = $this->authorcompany;
+		$versionProperties['ownerusername'] = $this->ownerusername;
+		$versionProperties['t3xfilemd5'] = $this->t3xfilemd5;
+		return $versionProperties;
+	}
+
+	/**
+	 * Returns download number sum of all extension's versions.
+	 *
+	 * @access  public
+	 * @return  string  download number sum
+	 * @see	 $extensionDLCounter, getAll()
+	 */
+	public function getAlldownloadcounter() {
+		return $this->extensionDLCounter;
+	}
+
+	/**
+	 * Returns company name of extension author.
+	 *
+	 * @access  public
+	 * @return  string  company name of extension author
+	 * @see	 $authorcompany, getAll()
+	 */
+	public function getAuthorcompany() {
+		return $this->authorcompany;
+	}
+
+	/**
+	 * Returns e-mail address of extension author.
+	 *
+	 * @access  public
+	 * @return  string  e-mail address of extension author
+	 * @see	 $authoremail, getAll()
+	 */
+	public function getAuthoremail() {
+		return $this->authoremail;
+	}
+
+	/**
+	 * Returns name of extension author.
+	 *
+	 * @access  public
+	 * @return  string  name of extension author
+	 * @see	 $authorname, getAll()
+	 */
+	public function getAuthorname() {
+		return $this->authorname;
+	}
+
+	/**
+	 * Returns category of an extension.
+	 *
+	 * @access  public
+	 * @return  string  extension category
+	 * @see	 $category, getAll()
+	 */
+	public function getCategory() {
+		return $this->category;
+	}
+
+	/**
+	 * Returns dependencies of an extension's version.
+	 *
+	 * @access  public
+	 * @return  string  extension dependencies
+	 * @see	 $dependencies, getAll()
+	 */
+	public function getDependencies() {
+		return $this->dependencies;
+	}
+
+	/**
+	 * Returns description of an extension's version.
+	 *
+	 * @access  public
+	 * @return  string  extension description
+	 * @see	 $description, getAll()
+	 */
+	public function getDescription() {
+		return $this->description;
+	}
+
+	/**
+	 * Returns download number of an extension's version.
+	 *
+	 * @access  public
+	 * @return  string  download number
+	 * @see	 $versionDLCounter, getAll()
+	 */
+	public function getDownloadcounter() {
+		return $this->versionDLCounter;
+	}
+
+	/**
+	 * Returns key of an extension.
+	 *
+	 * @access  public
+	 * @return  string  extension key
+	 * @see	 $extensionKey, getAll()
+	 */
+	public function getExtkey() {
+		return $this->extensionKey;
+	}
+
+	/**
+	 * Returns last uploaddate of an extension's version.
+	 *
+	 * @access  public
+	 * @return  string  last upload date of an extension's version
+	 * @see	 $lastuploaddate, getAll()
+	 */
+	public function getLastuploaddate() {
+		return $this->lastuploaddate;
+	}
+
+	/**
+	 * Returns username of extension owner.
+	 *
+	 * @access  public
+	 * @return  string  extension owner's username
+	 * @see	 $ownerusername, getAll()
+	 */
+	public function getOwnerusername() {
+		return $this->ownerusername;
+	}
+
+	/**
+	 * Returns review state of an extension's version.
+	 *
+	 * @access  public
+	 * @return  string  extension review state
+	 * @see	 $reviewstate, getAll()
+	 */
+	public function getReviewstate() {
+		return $this->reviewstate;
+	}
+
+	/**
+	 * Returns state of an extension's version.
+	 *
+	 * @access  public
+	 * @return  string  extension state
+	 * @see	 $state, getAll()
+	 */
+	public function getState() {
+		return $this->state;
+	}
+
+	/**
+	 * Returns t3x file hash of an extension's version.
+	 *
+	 * @access  public
+	 * @return  string  t3x file hash	 *
+	 * @see	 $t3xfilemd5, getAll()
+	 */
+	public function getT3xfilemd5() {
+		return $this->t3xfilemd5;
+	}
+
+	/**
+	 * Returns title of an extension's version.
+	 *
+	 * @access  public
+	 * @return  string  extension title
+	 * @see	 $title, getAll()
+	 */
+	public function getTitle() {
+		return $this->title;
+	}
+
+	/**
+	 * Returns extension upload comment.
+	 *
+	 * @access  public
+	 * @return  string  extension upload comment
+	 * @see	 $uploadcomment, getAll()
+	 */
+	public function getUploadcomment() {
+		return $this->uploadcomment;
+	}
+
+	/**
+	 * Returns version number.
+	 *
+	 * @access  public
+	 * @return  string  version number
+	 * @see	 $version, getAll()
+	 */
+	public function getVersion() {
+		return $this->version;
+	}
+
+	/**
+	 * Method resets version class properties.
+	 *
+	 * @access  protected
+	 * @param   boolean	$all  if true, additionally extension properties are reset
+	 * @return  void
+	 * @see	 $extensionKey, $version, $extensionDLCounter, $versionDLCounter,
+	 *		  $title, $description, $state, $reviewstate, $category,
+	 *		  $lastuploaddate, $uploadcomment, $dependencies, $authorname,
+	 *		  $authoremail, $authorcompany, $ownerusername, $t3xfilemd5
+	 */
+	protected function resetProperties($resetAll = FALSE) {
+		// resetting at least class property "version" is mandatory
+		// as we need to do some magic in regards to
+		// an extension's and version's child node "downloadcounter"
+		$this->version = $this->title = $this->versionDLCounter =
+				$this->description = $this->state = $this->reviewstate =
+						$this->category = $this->lastuploaddate = $this->uploadcomment =
+								$this->dependencies = $this->authorname = $this->authoremail =
+										$this->authorcompany = $this->ownerusername = $this->t3xfilemd5 = NULL;
+		if ($resetAll) {
+			$this->extensionKey = $this->extensionDLCounter = NULL;
+		}
+	}
+
+	/**
+	 * Method provides a wrapper for an exception call
+	 *
+	 * @access  protected
+	 * @param   string	 $message  the exception message to throw.
+	 * @param   integer	$code  the exception code
+	 * @return  void
+	 */
+	protected function throwException($message = "", $code = 0) {
+		throw new tx_em_ExtensionXmlException(get_class($this) . ': ' . $message, $code);
+	}
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/tools/class.tx_em_tools_xmlhandler.php
===================================================================
--- typo3/sysext/em/classes/tools/class.tx_em_tools_xmlhandler.php	(revision )
+++ typo3/sysext/em/classes/tools/class.tx_em_tools_xmlhandler.php	(revision )
@@ -0,0 +1,612 @@
+<?php
+/* **************************************************************
+*  Copyright notice
+*
+*  (c) 2006-2010 Karsten Dambekalns <karsten@typo3.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * XML handling class for the TYPO3 Extension Manager.
+ *
+ * It contains methods for handling the XML files involved with the EM,
+ * such as the list of extension mirrors and the list of available extensions.
+ *
+ * @author Karsten Dambekalns <karsten@typo3.org>
+ * @package TYPO3
+ * @subpackage EM
+ */
+class tx_em_Tools_XmlHandler {
+
+	/**
+	 * Enxtension Manager module
+	 *
+	 * @var SC_mod_tools_em_index
+	 */
+	var $emObj;
+
+	/**
+	 * Holds the parsed XML from extensions.xml.gz
+	 * @see parseExtensionsXML()
+	 *
+	 * @var array
+	 */
+	var $extXMLResult = array();
+	var $extensionsXML = array();
+	var $reviewStates = null;
+	var $useObsolete = false;
+
+	/**
+	 * Reduces the entries in $this->extensionsXML to the latest version per extension and removes entries not matching the search parameter
+	 *
+	 * @param	string		$search		The list of extensions is reduced to entries matching this. If empty, the full list is returned.
+	 * @param	string		$owner		If set only extensions of that user are fetched
+	 * @param	string		$order		A field to order the result by
+	 * @param	boolean		$allExt		If set also unreviewed and obsolete extensions are shown
+	 * @param	boolean		$allVer		If set returns all version of an extension, otherwise only the last
+	 * @param	integer		$offset		Offset to return result from (goes into LIMIT clause)
+	 * @param	integer		$limit		Maximum number of entries to return (goes into LIMIT clause)
+	 * @param	boolean		$exactMatch If set search is done for exact matches of extension keys only
+	 * @return	void
+	 */
+	function searchExtensionsXML($search, $owner = '', $order = '', $allExt = false, $allVer = false, $offset = 0, $limit = 500, $exactMatch = false) {
+		$where = '1=1';
+		if ($search && $exactMatch) {
+			$where .= ' AND extkey=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($search, 'cache_extensions');
+		} elseif ($search) {
+			$quotedSearch = $GLOBALS['TYPO3_DB']->escapeStrForLike(
+				$GLOBALS['TYPO3_DB']->quoteStr($search, 'cache_extensions'),
+				'cache_extensions'
+			);
+			$where .= ' AND (extkey LIKE \'%' . $quotedSearch . '%\' OR title LIKE \'%' . $quotedSearch . '%\')';
+
+		}
+		if ($owner) {
+			$where .= ' AND ownerusername=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($owner, 'cache_extensions');
+		}
+
+		// Show extensions without a review or that have passed a review, but not insecure extensions
+		$where .= ' AND reviewstate >= 0';
+
+		if (!$this->useObsolete) {
+			// 5 == obsolete
+			$where .= ' AND state != 5';
+		}
+
+		switch ($order) {
+			case 'author_company':
+				$forder = 'authorname, authorcompany';
+				break;
+			case 'state':
+				$forder = 'state';
+				break;
+			case 'cat':
+			default:
+				$forder = 'category';
+				break;
+		}
+		$order = $forder . ', title';
+		if (!$allVer) {
+			$where .= ' AND lastversion > 0';
+		}
+		$this->catArr = array();
+		$idx = 0;
+		foreach ($this->emObj->defaultCategories['cat'] as $catKey => $tmp) {
+			$this->catArr[$idx] = $catKey;
+			$idx++;
+		}
+		$this->stateArr = array();
+		$idx = 0;
+		foreach ($this->emObj->states as $state => $tmp) {
+			$this->stateArr[$idx] = $state;
+			$idx++;
+		}
+
+		// Fetch count
+		$count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', 'cache_extensions', $where);
+		$this->matchingCount = $count;
+
+		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'cache_extensions', $where, '', $order, $offset . ',' . $limit);
+		$this->extensionsXML = array();
+		while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
+			$row['category'] = $this->catArr[$row['category']];
+			$row['state'] = $this->stateArr[$row['state']];
+
+			if (!is_array($this->extensionsXML[$row['extkey']])) {
+				$this->extensionsXML[$row['extkey']] = array();
+				$this->extensionsXML[$row['extkey']]['downloadcounter'] = $row['alldownloadcounter'];
+			}
+			if (!is_array($this->extensionsXML[$row['extkey']]['versions'])) {
+				$this->extensionsXML[$row['extkey']]['versions'] = array();
+			}
+			$row['dependencies'] = unserialize($row['dependencies']);
+			$this->extensionsXML[$row['extkey']]['versions'][$row['version']] = $row;
+		}
+		$GLOBALS['TYPO3_DB']->sql_free_result($res);
+	}
+
+	/**
+	 * Reduces the entries in $this->extensionsXML to the latest version per extension and removes entries not matching the search parameter
+	 * The extension key has to be a valid one as search is done for exact matches only.
+	 *
+	 * @param	string		$search	The list of extensions is reduced to entries with exactely this extension key. If empty, the full list is returned.
+	 * @param	string		$owner	If set only extensions of that user are fetched
+	 * @param	string		$order	A field to order the result by
+	 * @param	boolean		$allExt	If set also unreviewed and obsolete extensions are shown
+	 * @param	boolean		$allVer	If set returns all version of an extension, otherwise only the last
+	 * @param	integer		$offset	Offset to return result from (goes into LIMIT clause)
+	 * @param	integer		$limit	Maximum number of entries to return (goes into LIMIT clause)
+	 * @return	void
+	 */
+	function searchExtensionsXMLExact($search, $owner = '', $order = '', $allExt = false, $allVer = false, $offset = 0, $limit = 500) {
+		$this->searchExtensionsXML($search, $owner, $order, $allExt, $allVer, $offset, $limit, true);
+	}
+
+	function countExtensions() {
+		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('extkey', 'cache_extensions', '1=1', 'extkey');
+		$cnt = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
+		$GLOBALS['TYPO3_DB']->sql_free_result($res);
+		return $cnt;
+	}
+
+	/**
+	 * Loads the pre-parsed extension list
+	 *
+	 * @return	boolean		true on success, false on error
+	 */
+	function loadExtensionsXML() {
+		$this->searchExtensionsXML('', '', '', true);
+	}
+
+	/**
+	 * Frees the pre-parsed extension list
+	 *
+	 * @return	void
+	 */
+	function freeExtensionsXML() {
+		unset($this->extensionsXML);
+		$this->extensionsXML = array();
+	}
+
+	/**
+	 * Removes all extension with a certain state from the list
+	 *
+	 * @param	array		&$extensions	The "versions" subpart of the extension list
+	 * @return	void
+	 */
+	function removeObsolete(&$extensions) {
+		if ($this->useObsolete) {
+			return;
+		}
+
+		foreach ($extensions as $version => $data) {
+			if ($data['state'] == 'obsolete') {
+				unset($extensions[$version]);
+			}
+		}
+	}
+
+	/**
+	 * Returns the reviewstate of a specific extension-key/version
+	 *
+	 * @param	string		$extKey
+	 * @param	string		$version: ...
+	 * @return	integer		Review state, if none is set 0 is returned as default.
+	 */
+	function getReviewState($extKey, $version) {
+		$where = 'extkey=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($extKey, 'cache_extensions') . ' AND version=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($version, 'cache_extensions');
+		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('reviewstate', 'cache_extensions', $where);
+		if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
+			return $row['reviewstate'];
+		}
+		$GLOBALS['TYPO3_DB']->sql_free_result($res);
+		return 0;
+	}
+
+
+	/**
+	 * ***************PARSING METHODS***********************
+	 */
+	/**
+	 * Enter description here...
+	 *
+	 * @param	unknown_type		$parser
+	 * @param	unknown_type		$name
+	 * @param	unknown_type		$attrs
+	 * @return	[type]		...
+	 */
+	function startElement($parser, $name, $attrs) {
+		switch ($name) {
+			case 'extensions':
+				break;
+			case 'extension':
+				$this->currentExt = $attrs['extensionkey'];
+				break;
+			case 'version':
+				$this->currentVersion = $attrs['version'];
+				$this->extXMLResult[$this->currentExt]['versions'][$this->currentVersion] = array();
+				break;
+			default:
+				$this->currentTag = $name;
+		}
+	}
+
+	/**
+	 * Enter description here...
+	 *
+	 * @param	unknown_type		$parser
+	 * @param	unknown_type		$name
+	 * @return	[type]		...
+	 */
+	function endElement($parser, $name) {
+		switch ($name) {
+			case 'extension':
+				unset($this->currentExt);
+				break;
+			case 'version':
+				unset($this->currentVersion);
+				break;
+			default:
+				unset($this->currentTag);
+		}
+	}
+
+	/**
+	 * Enter description here...
+	 *
+	 * @param	unknown_type		$parser
+	 * @param	unknown_type		$data
+	 * @return	[type]		...
+	 */
+	function characterData($parser, $data) {
+		if (isset($this->currentTag)) {
+			if (!isset($this->currentVersion) && $this->currentTag == 'downloadcounter') {
+				$this->extXMLResult[$this->currentExt]['downloadcounter'] = trim($data);
+			} elseif ($this->currentTag == 'dependencies') {
+				$data = @unserialize($data);
+				if (is_array($data)) {
+					$dep = array();
+					foreach ($data as $v) {
+						$dep[$v['kind']][$v['extensionKey']] = $v['versionRange'];
+					}
+					$this->extXMLResult[$this->currentExt]['versions'][$this->currentVersion]['dependencies'] = $dep;
+				}
+			} elseif ($this->currentTag == 'reviewstate') {
+				$this->reviewStates[$this->currentExt][$this->currentVersion] = (int) trim($data);
+				$this->extXMLResult[$this->currentExt]['versions'][$this->currentVersion]['reviewstate'] = (int) trim($data);
+			} else {
+				$this->extXMLResult[$this->currentExt]['versions'][$this->currentVersion][$this->currentTag] .= trim($data);
+			}
+		}
+	}
+
+	/**
+	 * Parses content of mirrors.xml into a suitable array
+	 *
+	 * @param	string		XML data file to parse
+	 * @return	string		HTLML output informing about result
+	 */
+	function parseExtensionsXML($filename) {
+
+		$parser = xml_parser_create();
+		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
+		xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
+		xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'utf-8');
+		xml_set_element_handler($parser, array(&$this, 'startElement'), array(&$this, 'endElement'));
+		xml_set_character_data_handler($parser, array(&$this, 'characterData'));
+
+		$fp = gzopen($filename, 'rb');
+		if (!$fp) {
+			$content .= 'Error opening XML extension file "' . $filename . '"';
+			return $content;
+		}
+		$string = gzread($fp, 0xffff); // Read 64KB
+
+		$this->revCatArr = array();
+		$idx = 0;
+		foreach ($this->emObj->defaultCategories['cat'] as $catKey => $tmp) {
+			$this->revCatArr[$catKey] = $idx++;
+		}
+
+		$this->revStateArr = array();
+		$idx = 0;
+		foreach ($this->emObj->states as $state => $tmp) {
+			$this->revStateArr[$state] = $idx++;
+		}
+
+		$GLOBALS['TYPO3_DB']->exec_TRUNCATEquery('cache_extensions');
+
+		$extcount = 0;
+		@ini_set('pcre.backtrack_limit', 500000);
+		do {
+			if (preg_match('/.*(<extension\s+extensionkey="[^"]+">.*<\/extension>)/suU', $string, $match)) {
+				// Parse content:
+				if (!xml_parse($parser, $match[0], 0)) {
+					$content .= 'Error in XML parser while decoding extensions XML file. Line ' . xml_get_current_line_number($parser) . ': ' . xml_error_string(xml_get_error_code($parser));
+					$error = true;
+					break;
+				}
+				$this->storeXMLResult();
+				$this->extXMLResult = array();
+				$extcount++;
+				$string = substr($string, strlen($match[0]));
+			} elseif (function_exists('preg_last_error') && preg_last_error()) {
+				$errorcodes = array(
+					0 => 'PREG_NO_ERROR',
+					1 => 'PREG_INTERNAL_ERROR',
+					2 => 'PREG_BACKTRACK_LIMIT_ERROR',
+					3 => 'PREG_RECURSION_LIMIT_ERROR',
+					4 => 'PREG_BAD_UTF8_ERROR'
+				);
+				$content .= 'Error in regular expression matching, code: ' . $errorcodes[preg_last_error()] . '<br />See <a href="http://www.php.net/manual/en/function.preg-last-error.php" target="_blank">http://www.php.net/manual/en/function.preg-last-error.php</a>';
+				$error = true;
+				break;
+			} else {
+				if (gzeof($fp)) {
+					break;
+				} // Nothing more can be read
+				$string .= gzread($fp, 0xffff); // Read another 64KB
+			}
+		} while (true);
+
+		xml_parser_free($parser);
+		gzclose($fp);
+
+		if (!$error) {
+			$flashMessage = t3lib_div::makeInstance(
+				't3lib_FlashMessage',
+				sprintf($GLOBALS['LANG']->getLL('ext_import_extlist_updated'), $extcount),
+				$GLOBALS['LANG']->getLL('ext_import_extlist_updated_header')
+			);
+			$content .= $flashMessage->render();
+		}
+
+		return $content;
+	}
+
+	function storeXMLResult() {
+		foreach ($this->extXMLResult as $extkey => $extArr) {
+			$max = -1;
+			$maxrev = -1;
+			$last = '';
+			$lastrev = '';
+			$usecat = '';
+			$usetitle = '';
+			$usestate = '';
+			$useauthorcompany = '';
+			$useauthorname = '';
+			$verArr = array();
+			foreach ($extArr['versions'] as $version => $vArr) {
+				$iv = tx_em_Tools::makeVersion($version, 'int');
+				if ($vArr['title'] && !$usetitle) {
+					$usetitle = $vArr['title'];
+				}
+				if ($vArr['state'] && !$usestate) {
+					$usestate = $vArr['state'];
+				}
+				if ($vArr['authorcompany'] && !$useauthorcompany) {
+					$useauthorcompany = $vArr['authorcompany'];
+				}
+				if ($vArr['authorname'] && !$useauthorname) {
+					$useauthorname = $vArr['authorname'];
+				}
+				$verArr[$version] = $iv;
+				if ($iv > $max) {
+					$max = $iv;
+					$last = $version;
+					if ($vArr['title']) {
+						$usetitle = $vArr['title'];
+					}
+					if ($vArr['state']) {
+						$usestate = $vArr['state'];
+					}
+					if ($vArr['authorcompany']) {
+						$useauthorcompany = $vArr['authorcompany'];
+					}
+					if ($vArr['authorname']) {
+						$useauthorname = $vArr['authorname'];
+					}
+					$usecat = $vArr['category'];
+				}
+				if ($vArr['reviewstate'] && ($iv > $maxrev)) {
+					$maxrev = $iv;
+					$lastrev = $version;
+				}
+			}
+			if (!strlen($usecat)) {
+				$usecat = 4; // Extensions without a category end up in "misc"
+			} else {
+				if (isset($this->revCatArr[$usecat])) {
+					$usecat = $this->revCatArr[$usecat];
+				} else {
+					$usecat = 4; // Extensions without a category end up in "misc"
+				}
+			}
+			if (isset($this->revStateArr[$usestate])) {
+				$usestate = $this->revCatArr[$usestate];
+			} else {
+				$usestate = 999; // Extensions without a category end up in "misc"
+			}
+			foreach ($extArr['versions'] as $version => $vArr) {
+				$vArr['version'] = $version;
+				$vArr['intversion'] = $verArr[$version];
+				$vArr['extkey'] = $extkey;
+				$vArr['alldownloadcounter'] = $extArr['downloadcounter'];
+				$vArr['dependencies'] = serialize($vArr['dependencies']);
+				$vArr['category'] = $usecat;
+				$vArr['title'] = $usetitle;
+				if ($version == $last) {
+					$vArr['lastversion'] = 1;
+				}
+				if ($version == $lastrev) {
+					$vArr['lastreviewedversion'] = 1;
+				}
+				$vArr['state'] = isset($this->revStateArr[$vArr['state']]) ? $this->revStateArr[$vArr['state']] : $usestate; // 999 = not set category
+				$GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_extensions', $vArr);
+			}
+		}
+	}
+
+	/**
+	 * Parses content of mirrors.xml into a suitable array
+	 *
+	 * @param	string		$string: XML data to parse
+	 * @return	string		HTLML output informing about result
+	 */
+	function parseMirrorsXML($string) {
+		global $TYPO3_CONF_VARS;
+
+		// Create parser:
+		$parser = xml_parser_create();
+		$vals = array();
+		$index = array();
+
+		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
+		xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
+
+		$preg_result = array();
+		preg_match('/^[[:space:]]*<\?xml[^>]*encoding[[:space:]]*=[[:space:]]*"([^"]*)"/', substr($string, 0, 200), $preg_result);
+		$theCharset = $preg_result[1] ? $preg_result[1] : ($TYPO3_CONF_VARS['BE']['forceCharset'] ? $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
+
+		// Parse content:
+		xml_parse_into_struct($parser, $string, $vals, $index);
+
+		// If error, return error message:
+		if (xml_get_error_code($parser)) {
+			$line = xml_get_current_line_number($parser);
+			$error = xml_error_string(xml_get_error_code($parser));
+			xml_parser_free($parser);
+			return 'Error in XML parser while decoding mirrors XML file. Line ' . $line . ': ' . $error;
+		} else {
+			// Init vars:
+			$stack = array(array());
+			$stacktop = 0;
+			$mirrornumber = 0;
+			$current = array();
+			$tagName = '';
+			$documentTag = '';
+
+			// Traverse the parsed XML structure:
+			foreach ($vals as $val) {
+
+				// First, process the tag-name (which is used in both cases, whether "complete" or "close")
+				$tagName = ($val['tag'] == 'mirror' && $val['type'] == 'open') ? '__plh' : $val['tag'];
+				if (!$documentTag) {
+					$documentTag = $tagName;
+				}
+
+				// 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
+						$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:
+						if ($tagName == 'mirror') {
+							unset($current['__plh']);
+							$current[$oldCurrent['host']] = $oldCurrent;
+						} else {
+							$current[key($current)] = $oldCurrent;
+						}
+						unset($oldCurrent);
+						break;
+					case 'complete': // If "complete", then it's a value. If the attribute "base64" is set, then decode the value, otherwise just set it.
+						$current[$tagName] = (string) $val['value']; // Had to cast it as a string - otherwise it would be evaluate false if tested with isset()!!
+						break;
+				}
+			}
+			return $current[$tagName];
+		}
+	}
+
+	/**
+	 * Parses content of *-l10n.xml into a suitable array
+	 *
+	 * @param	string		$string: XML data to parse
+	 * @return	array		Array representation of XML data
+	 */
+	function parseL10nXML($string) {
+		// Create parser:
+		$parser = xml_parser_create();
+		$vals = array();
+		$index = array();
+
+		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
+		xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
+
+		// Parse content:
+		xml_parse_into_struct($parser, $string, $vals, $index);
+
+		// If error, return error message:
+		if (xml_get_error_code($parser)) {
+			$line = xml_get_current_line_number($parser);
+			$error = xml_error_string(xml_get_error_code($parser));
+			xml_parser_free($parser);
+			return 'Error in XML parser while decoding l10n XML file. Line ' . $line . ': ' . $error;
+		} else {
+			// Init vars:
+			$stack = array(array());
+			$stacktop = 0;
+			$mirrornumber = 0;
+			$current = array();
+			$tagName = '';
+			$documentTag = '';
+
+			// Traverse the parsed XML structure:
+			foreach ($vals as $val) {
+
+				// First, process the tag-name (which is used in both cases, whether "complete" or "close")
+				$tagName = ($val['tag'] == 'languagepack' && $val['type'] == 'open') ? $val['attributes']['language'] : $val['tag'];
+				if (!$documentTag) {
+					$documentTag = $tagName;
+				}
+
+				// 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
+						$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:
+						$current[key($current)] = $oldCurrent;
+						unset($oldCurrent);
+						break;
+					case 'complete': // If "complete", then it's a value. If the attribute "base64" is set, then decode the value, otherwise just set it.
+						$current[$tagName] = (string) $val['value']; // Had to cast it as a string - otherwise it would be evaluate false if tested with isset()!!
+						break;
+				}
+			}
+			return $current[$tagName];
+		}
+	}
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/parser/class.tx_em_parser_extensionxmlpullparser.php
===================================================================
--- typo3/sysext/em/classes/parser/class.tx_em_parser_extensionxmlpullparser.php	(revision )
+++ typo3/sysext/em/classes/parser/class.tx_em_parser_extensionxmlpullparser.php	(revision )
@@ -0,0 +1,244 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
+ *		   Steffen Kamper <info@sk-typo3.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * Module: Extension manager - Extension.xml pull-parser
+ *
+ * $Id: class.tx_em_parser_extensionxmlpullparser.php 1913 2010-02-21 15:47:37Z mkrause $
+ */
+
+/**
+ * Parser for TYPO3's extension.xml file.
+ *
+ * Depends on PHP ext/xmlreader which should be available
+ * with PHP >= 5.1.0.
+ *
+ * @author	  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author	  Steffen Kamper <info@sk-typo3.de>
+ *
+ * @since	   2010-02-09
+ * @package	 TYPO3
+ * @subpackage  EM
+ */
+class tx_em_Parser_ExtensionXmlPullParser extends tx_em_Parser_ExtensionXmlAbstractParser implements SplSubject {
+
+
+	/**
+	 * Keeps list of attached observers.
+	 *
+	 * @var  array
+	 */
+	protected $observers = array();
+
+	/**
+	 * Class constructor.
+	 *
+	 * @return void
+	 */
+	function __construct() {
+		$this->requiredPHPExt = 'xmlreader';
+
+		if ($this->isAvailable()) {
+			$this->objXML = new XMLReader();
+		}
+	}
+
+	/**
+	 * Method parses an extensions.xml file.
+	 *
+	 * @param   string  $file: GZIP stream resource
+	 * @return  void
+	 * @throws  em_extensionxml_Exception  in case of XML parser errors
+	 */
+	public function parseXML($file) {
+		if (!(is_object($this->objXML) && (get_class($this->objXML) == 'XMLReader'))) {
+			$this->throwException('Unable to create XML parser.');
+		}
+		$this->objXML->open($file, 'utf-8') || $this->throwException(sprintf('Unable to open file ressource %s.', htmlspecialchars($file)));
+
+		while ($this->objXML->read()) {
+
+			if ($this->objXML->nodeType == XMLReader::ELEMENT) {
+				$this->startElement($this->objXML->name);
+			} else {
+				if ($this->objXML->nodeType == XMLReader::END_ELEMENT) {
+					$this->endElement($this->objXML->name);
+				} else {
+					continue;
+				}
+			}
+		}
+		$this->objXML->close();
+	}
+
+	/**
+	 * Method is invoked when parser accesses start tag of an element.
+	 *
+	 * @param   string	 $elementName: element name at parser's current position
+	 * @return  void
+	 */
+	protected function startElement($elementName) {
+		switch ($elementName) {
+			case 'extension':
+				$this->extensionKey = $this->objXML->getAttribute('extensionkey');
+				break;
+			case 'version':
+				$this->version = $this->objXML->getAttribute('version');
+				break;
+			case 'downloadcounter':
+				// downloadcounter could be a child node of
+				// extension or version
+				if ($this->version == NULL) {
+					$this->extensionDLCounter = $this->getElementValue($elementName);
+				} else {
+					$this->versionDLCounter = $this->getElementValue($elementName);
+				}
+				break;
+			case 'title':
+				$this->title = $this->getElementValue($elementName);
+				break;
+			case 'description':
+				$this->description = $this->getElementValue($elementName);
+				break;
+			case 'state':
+				$this->state = $this->getElementValue($elementName);
+				break;
+			case 'reviewstate':
+				$this->reviewstate = $this->getElementValue($elementName);
+				break;
+			case 'category':
+				$this->category = $this->getElementValue($elementName);
+				break;
+			case 'lastuploaddate':
+				$this->lastuploaddate = $this->getElementValue($elementName);
+				break;
+			case 'uploadcomment':
+				$this->uploadcomment = $this->getElementValue($elementName);
+				break;
+			case 'dependencies':
+				$this->dependencies = $this->getElementValue($elementName);
+				break;
+			case 'authorname':
+				$this->authorname = $this->getElementValue($elementName);
+				break;
+			case 'authoremail':
+				$this->authoremail = $this->getElementValue($elementName);
+				break;
+			case 'authorcompany':
+				$this->authorcompany = $this->getElementValue($elementName);
+				break;
+			case 'ownerusername':
+				$this->ownerusername = $this->getElementValue($elementName);
+				break;
+			case 't3xfilemd5':
+				$this->t3xfilemd5 = $this->getElementValue($elementName);
+				break;
+		}
+	}
+
+	/**
+	 * Method is invoked when parser accesses end tag of an element.
+	 *
+	 * @param   string	 $elementName: element name at parser's current position
+	 * @return  void
+	 */
+	protected function endElement($elementName) {
+		switch ($elementName) {
+			case 'extension':
+				$this->resetProperties(TRUE);
+				break;
+			case 'version':
+				$this->notify();
+				$this->resetProperties();
+				break;
+		}
+	}
+
+	/**
+	 * Method returns the value of an element at XMLReader's current
+	 * position.
+	 *
+	 * Method will read until it finds the end of the given element.
+	 * If element has no value, method returns NULL.
+	 *
+	 * @param   string  $elementName: name of element to retrieve it's value from
+	 * @return  string  an element's value if it has a value, otherwise NULL
+	 */
+	protected function getElementValue(&$elementName) {
+		$value = NULL;
+		if (!$this->objXML->isEmptyElement) {
+			$value = '';
+			while ($this->objXML->read()) {
+				if ($this->objXML->nodeType == XMLReader::TEXT
+						|| $this->objXML->nodeType == XMLReader::CDATA
+						|| $this->objXML->nodeType == XMLReader::WHITESPACE
+						|| $this->objXML->nodeType == XMLReader::SIGNIFICANT_WHITESPACE) {
+					$value .= $this->objXML->value;
+				} else {
+					if ($this->objXML->nodeType == XMLReader::END_ELEMENT
+							&& $this->objXML->name === $elementName) {
+						break;
+					}
+				}
+			}
+		}
+		return $value;
+	}
+
+	/**
+	 * Method attaches an observer.
+	 *
+	 * @param   SplObserver  $observer: an observer to attach
+	 * @return  void
+	 */
+	public function attach(SplObserver $observer) {
+		$this->observers[] = $observer;
+	}
+
+	/**
+	 * Method detaches an attached observer
+	 *
+	 * @param   SplObserver  $observer: an observer to detach
+	 * @return  void
+	 */
+	public function detach(SplObserver $observer) {
+		$key = array_search($observer, $this->observers, true);
+		if (!($key === false)) {
+			unset($this->observers[$key]);
+		}
+	}
+
+	/**
+	 * Method notifies attached observers.
+	 *
+	 * @return  void
+	 */
+	public function notify() {
+		foreach ($this->observers as $observer) {
+			$observer->update($this);
+		}
+	}
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/parser/class.tx_em_parser_xmlabstractparser.php
===================================================================
--- typo3/sysext/em/classes/parser/class.tx_em_parser_xmlabstractparser.php	(revision )
+++ typo3/sysext/em/classes/parser/class.tx_em_parser_xmlabstractparser.php	(revision )
@@ -0,0 +1,105 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Marcus Krause <marcus#exp2010@t3sec.info>
+ *		   Steffen Kamper <info@sk-typo3.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * class.tx_em_parser_xmlabstractparser.php
+ *
+ * Module: Extension manager - Extension.xml abstract parser
+ *
+ * $Id: class.tx_em_parser_xmlabstractparser.php 1910 2010-02-21 14:31:07Z mkrause $
+ *
+ * @author  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author  Steffen Kamper <info@sk-typo3.de>
+ */
+
+/**
+ * Abstract parser for EM related TYPO3 xml files.
+ *
+ * @author	  Marcus Krause <marcus#exp2010@t3sec.info>
+ * @author	  Steffen Kamper <info@sk-typo3.de>
+ *
+ * @since	   2010-02-09
+ * @package	 TYPO3
+ * @subpackage  EM
+ */
+abstract class tx_em_Parser_XmlAbstractParser {
+
+
+	/**
+	 * Keeps XML parser instance.
+	 *
+	 * @var  mixed
+	 */
+	protected $objXML;
+
+	/**
+	 * Keeps name of required PHP extension
+	 * for this class to work properly.
+	 *
+	 * @var  string
+	 */
+	protected $requiredPHPExt;
+
+
+	/**
+	 * Method determines if a necessary PHP extension is available.
+	 *
+	 * Method tries to load the extension if necessary and possible.
+	 *
+	 * @access  public
+	 * @return  boolean  true, if PHP extension is available, otherwise false
+	 */
+	public function isAvailable() {
+		$isAvailable = TRUE;
+		if (!extension_loaded($this->requiredPHPExt)) {
+			$prefix = (PHP_SHLIB_SUFFIX === 'dll') ? 'php_' : '';
+			if (!((bool) ini_get('enable_dl') && !(bool) ini_get('safe_mode') && function_exists('dl') && dl($prefix . $this->requiredPHPExt . PHP_SHLIB_SUFFIX))) {
+				$isAvailable = FALSE;
+			}
+		}
+		return $isAvailable;
+	}
+
+	/**
+	 * Method parses an XML file.
+	 *
+	 * @access  public
+	 * @param   string  $file: GZIP stream resource
+	 * @return  void
+	 * @throws  em_xml_Exception  in case of XML parser errors
+	 */
+	abstract public function parseXML($file);
+
+	/**
+	 * Method provides a wrapper for an exception call
+	 *
+	 * @access  protected
+	 * @param   string	 $message  the exception message to throw
+	 * @param   integer	$code  the exception code
+	 * @return  void
+	 */
+	abstract protected function throwException($message = "", $code = 0);
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/install/class.tx_em_install.php
===================================================================
--- typo3/sysext/em/classes/install/class.tx_em_install.php	(revision )
+++ typo3/sysext/em/classes/install/class.tx_em_install.php	(revision )
@@ -0,0 +1,1307 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Steffen Kamper (info@sk-typo3.de)
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * Module: Extension manager, (un-)install extensions
+ *
+ * $Id: class.tx_em_install.php 2073 2010-03-19 10:42:38Z steffenk $
+ *
+ * @author	Steffen Kamper <info@sk-typo3.de>
+ */
+
+
+class tx_em_Install {
+
+	/**
+	 * Parent module object
+	 *
+	 * @var SC_mod_tools_em_index
+	 */
+	protected $parentObject;
+
+	/**
+	 *
+	 * @var t3lib_install
+	 */
+	protected $install;
+
+
+	protected $systemInstall = 0; // If "1" then installs in the sysext directory is allowed. Default: 0
+
+	/**
+	 * Constructor
+	 *
+	 * @param SC_mod_tools_em_index $parentObject
+	 */
+	public function __construct($parentObject = NULL) {
+		$GLOBALS['LANG']->includeLLFile(t3lib_extMgm::extPath('em', 'language/locallang.xml'));
+		$this->parentObject = $parentObject;
+		$this->install = t3lib_div::makeInstance('t3lib_install');
+		$this->install->INSTALL = t3lib_div::_GP('TYPO3_INSTALL');
+		$this->systemInstall = isset($GLOBALS['TYPO3_CONF_VARS']['EXT']['allowSystemInstall']) && $GLOBALS['TYPO3_CONF_VARS']['EXT']['allowSystemInstall'];
+	}
+
+	/**
+	 * @param  $uploadedTempFile
+	 * @param  $location
+	 * @param bool $uploadOverwrite
+	 * @return array
+	 */
+	public function uploadExtensionFile($uploadedTempFile, $location, $uploadOverwrite = FALSE) {
+		$error = '';
+		$fileContent = t3lib_div::getUrl($uploadedTempFile);
+		if (!$fileContent) {
+			return array(
+				'success' => FALSE,
+				'error' => $GLOBALS['LANG']->getLL('ext_import_file_empty')
+			);
+		}
+
+		// Decode file data:
+		$terConnection = t3lib_div::makeInstance('tx_em_Connection_Ter', $this);
+		$fetchData = $terConnection->decodeExchangeData($fileContent);
+		if (is_array($fetchData)) {
+			$extKey = $fetchData[0]['extKey'];
+			if ($extKey) {
+				if (!$uploadOverwrite) {
+					$comingExtPath = tx_em_Tools::typePath($location) . $extKey . '/';
+					if (@is_dir($comingExtPath)) {
+						$error = sprintf($GLOBALS['LANG']->getLL('ext_import_ext_present_no_overwrite'), $comingExtPath) .
+								'<br />' . $GLOBALS['LANG']->getLL('ext_import_ext_present_nothing_done');
+
+					} // ... else go on, install...
+				} // ... else go on, install...
+			} else {
+				$error = $GLOBALS['LANG']->getLL('ext_import_no_key');
+			}
+		} else {
+			$error = sprintf($GLOBALS['LANG']->getLL('ext_import_wrong_file_format'), $fetchData);
+		}
+
+		if ($error) {
+			return array(FALSE, $error);
+		} else {
+			return array(TRUE, $fetchData);
+		}
+
+	}
+
+	/**
+	 * Installs an extension.
+	 *
+	 * @param  $fetchData
+	 * @param  $loc
+	 * @param  $version
+	 * @param  $uploadedTempFile
+	 * @param  $dontDelete
+	 * @return mixed|string
+	 */
+	public function installExtension($fetchData, $loc, $version, $uploadedTempFile, $dontDelete) {
+		$xmlhandler =& $this->parentObject->xmlhandler;
+		$extensionList =& $this->parentObject->extensionList;
+		$extensionDetails =& $this->parentObject->extensionDetails;
+
+		if (tx_em_Tools::importAsType($loc)) {
+			if (is_array($fetchData)) { // There was some data successfully transferred
+				if ($fetchData[0]['extKey'] && is_array($fetchData[0]['FILES'])) {
+					$extKey = $fetchData[0]['extKey'];
+					if (!isset($fetchData[0]['EM_CONF']['constraints'])) {
+						$fetchData[0]['EM_CONF']['constraints'] = $xmlhandler->extensionsXML[$extKey]['versions'][$version]['dependencies'];
+					}
+					$EM_CONF = tx_em_Tools::fixEMCONF($fetchData[0]['EM_CONF']);
+					if (!$EM_CONF['lockType'] || !strcmp($EM_CONF['lockType'], $loc)) {
+						// check dependencies, act accordingly if ext is loaded
+						list($instExtInfo,) = $extensionList->getInstalledExtensions();
+						$depStatus = $this->checkDependencies($extKey, $EM_CONF, $instExtInfo);
+						if (t3lib_extMgm::isLoaded($extKey) && !$depStatus['returnCode']) {
+							$this->content .= $depStatus['html'];
+							if ($uploadedTempFile) {
+								$this->content .= '<input type="hidden" name="CMD[alreadyUploaded]" value="' . $uploadedTempFile . '" />';
+							}
+						} else {
+							$res = $this->clearAndMakeExtensionDir($fetchData[0], $loc, $dontDelete);
+							if (is_array($res)) {
+								$extDirPath = trim($res[0]);
+								if ($extDirPath && @is_dir($extDirPath) && substr($extDirPath, -1) == '/') {
+
+									$emConfFile = $extensionDetails->construct_ext_emconf_file($extKey, $EM_CONF);
+									$dirs = tx_em_Tools::extractDirsFromFileList(array_keys($fetchData[0]['FILES']));
+
+									$res = tx_em_Tools::createDirsInPath($dirs, $extDirPath);
+									if (!$res) {
+										$writeFiles = $fetchData[0]['FILES'];
+										$writeFiles['ext_emconf.php']['content'] = $emConfFile;
+										$writeFiles['ext_emconf.php']['content_md5'] = md5($emConfFile);
+
+										// Write files:
+										foreach ($writeFiles as $theFile => $fileData) {
+											t3lib_div::writeFile($extDirPath . $theFile, $fileData['content']);
+											if (!@is_file($extDirPath . $theFile)) {
+												$content .= sprintf($GLOBALS['LANG']->getLL('ext_import_file_not_created'),
+														$extDirPath . $theFile) . '<br />';
+											} elseif (md5(t3lib_div::getUrl($extDirPath . $theFile)) != $fileData['content_md5']) {
+												$content .= sprintf($GLOBALS['LANG']->getLL('ext_import_file_corrupted'),
+														$extDirPath . $theFile) . '<br />';
+											}
+										}
+
+										t3lib_div::fixPermissions($extDirPath, TRUE);
+
+										// No content, no errors. Create success output here:
+										if (!$content) {
+											$messageContent = sprintf($GLOBALS['LANG']->getLL('ext_import_success_folder'), $extDirPath) . '<br />';
+
+											$uploadSucceed = true;
+
+											// Fix TYPO3_MOD_PATH for backend modules in extension:
+											$modules = t3lib_div::trimExplode(',', $EM_CONF['module'], 1);
+											if (count($modules)) {
+												foreach ($modules as $mD) {
+													$confFileName = $extDirPath . $mD . '/conf.php';
+													if (@is_file($confFileName)) {
+														$messageContent .= tx_em_Tools::writeTYPO3_MOD_PATH($confFileName, $loc, $extKey . '/' . $mD . '/') . '<br />';
+													} else {
+														$messageContent .= sprintf($GLOBALS['LANG']->getLL('ext_import_no_conf_file'),
+															$confFileName) . '<br />';
+													}
+												}
+											}
+											// NOTICE: I used two hours trying to find out why a script, ext_emconf.php, written twice and in between included by PHP did not update correct the second time. Probably something with PHP-A cache and mtime-stamps.
+											// But this order of the code works.... (using the empty Array with type, EMCONF and files hereunder).
+
+											// Writing to ext_emconf.php:
+											$sEMD5A = $extensionDetails->serverExtensionMD5array($extKey, array('type' => $loc, 'EM_CONF' => array(), 'files' => array()));
+											$EM_CONF['_md5_values_when_last_written'] = serialize($sEMD5A);
+											$emConfFile = $extensionDetails->construct_ext_emconf_file($extKey, $EM_CONF);
+											t3lib_div::writeFile($extDirPath . 'ext_emconf.php', $emConfFile);
+
+											$messageContent .= 'ext_emconf.php: ' . $extDirPath . 'ext_emconf.php<br />';
+											$messageContent .= $GLOBALS['LANG']->getLL('ext_import_ext_type') . ' ';
+											$messageContent .= $this->typeLabels[$loc] . '<br />';
+											$messageContent .= '<br />';
+
+											// Remove cache files:
+											$updateContent = '';
+											if (t3lib_extMgm::isLoaded($extKey)) {
+												if (t3lib_extMgm::removeCacheFiles()) {
+													$messageContent .= $GLOBALS['LANG']->getLL('ext_import_cache_files_removed') . '<br />';
+												}
+
+												list($new_list) = $this->parentObject->extensionList->getInstalledExtensions();
+												$updateContent = $this->updatesForm($extKey, $new_list[$extKey], 1, t3lib_div::linkThisScript(array(
+													'CMD[showExt]' => $extKey,
+													'SET[singleDetails]' => 'info'
+												)));
+											}
+
+											$flashMessage = t3lib_div::makeInstance(
+												't3lib_FlashMessage',
+												$messageContent,
+												$GLOBALS['LANG']->getLL('ext_import_success')
+											);
+											$content = $flashMessage->render() . $updateContent;
+
+
+											// Install / Uninstall:
+											if (!$this->parentObject->CMD['standAlone']) {
+												$content .= '<h3>' . $GLOBALS['LANG']->getLL('ext_import_install_uninstall') . '</h3>';
+												$content .= $new_list[$extKey] ?
+														'<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
+															'CMD[showExt]' => $extKey,
+															'CMD[remove]' => 1,
+															'CMD[clrCmd]' => 1,
+															'SET[singleDetails]' => 'info'
+														))) . '">' .
+																tx_em_Tools::removeButton() . ' ' . $GLOBALS['LANG']->getLL('ext_import_uninstall') . '</a>' :
+														'<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
+															'CMD[showExt]' => $extKey,
+															'CMD[load]' => 1,
+															'CMD[clrCmd]' => 1,
+															'SET[singleDetails]' => 'info'
+														))) . '">' .
+																tx_em_Tools::installButton() . ' ' . $GLOBALS['LANG']->getLL('ext_import_install') . '</a>';
+											} else {
+												$content = $GLOBALS['LANG']->getLL('ext_import_imported') .
+														'<br /><br /><a href="javascript:opener.top.list.iframe.document.forms[0].submit();window.close();">' .
+														$GLOBALS['LANG']->getLL('ext_import_close_check') . '</a>';
+											}
+										}
+									} else {
+										$content = $res;
+									}
+								} else {
+									$content = sprintf($GLOBALS['LANG']->getLL('ext_import_ext_path_different'), $extDirPath);
+								}
+							} else {
+								$content = $res;
+							}
+						}
+					} else {
+						$content = sprintf($GLOBALS['LANG']->getLL('ext_import_ext_only_here'),
+							tx_em_Tools::typePath($EM_CONF['lockType']), $EM_CONF['lockType']);
+					}
+				} else {
+					$content = $GLOBALS['LANG']->getLL('ext_import_no_ext_key_files');
+				}
+			} else {
+				$content = sprintf($GLOBALS['LANG']->getLL('ext_import_data_transfer'), $fetchData);
+			}
+		} else {
+			$content = sprintf($GLOBALS['LANG']->getLL('ext_import_no_install_here'), tx_em_Tools::typePath($loc));
+		}
+
+		return $content;
+	}
+
+	/**
+	 * Enter description here...
+	 *
+	 * @param	string		$extKey
+	 * @param	array		$conf
+	 * @param	array		$instExtInfo
+	 * @return	array
+	 */
+	function checkDependencies($extKey, $conf, $instExtInfo) {
+		$content = '';
+		$depError = false;
+		$depIgnore = false;
+		$msg = array();
+		$depsolver = t3lib_div::_POST('depsolver');
+
+		if (isset($conf['constraints']['depends']) && is_array($conf['constraints']['depends'])) {
+			foreach ($conf['constraints']['depends'] as $depK => $depV) {
+				if ($depsolver['ignore'][$depK]) {
+					$msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_ignored'),
+						$depK) . '
+						<input type="hidden" value="1" name="depsolver[ignore][' . $depK . ']" />';
+					$depIgnore = true;
+					continue;
+				}
+				if ($depK == 'php') {
+					if (!$depV) {
+						continue;
+					}
+					$versionRange = tx_em_Tools::splitVersionRange($depV);
+					$phpv = strstr(PHP_VERSION, '-') ? substr(PHP_VERSION, 0, strpos(PHP_VERSION, '-')) : PHP_VERSION; // Linux distributors like to add suffixes, like in 5.1.2-1. Those must be ignored!
+					if ($versionRange[0] != '0.0.0' && version_compare($phpv, $versionRange[0], '<')) {
+						$msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_php_too_low'),
+							$phpv, $versionRange[0]);
+						$msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $depK . ']" id="checkIgnore_' . $depK . '" />
+							<label for="checkIgnore_' . $depK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_requirement') . '</label>';
+						$depError = true;
+						continue;
+					} elseif ($versionRange[1] != '0.0.0' && version_compare($phpv, $versionRange[1], '>')) {
+						$msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_php_too_high'),
+							$phpv, $versionRange[1]);
+						$msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $depK . ']" id="checkIgnore_' . $depK . '" />
+							<label for="checkIgnore_' . $depK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_requirement') . '</label>';
+						$depError = true;
+						continue;
+					}
+
+				} elseif ($depK == 'typo3') {
+					if (!$depV) {
+						continue;
+					}
+
+					// if the current TYPO3 version is a development version (like TYPO3 4.4-dev),
+					// then it should behave like TYPO3 4.4.0
+					$t3version = TYPO3_version;
+					if (stripos($t3version, '-dev')
+							|| stripos($t3version, '-alpha')
+							|| stripos($t3version, '-beta')
+							|| stripos($t3version, '-RC')) {
+						// find the last occurence of "-" and replace that part with a ".0"
+						$t3version = substr($t3version, 0, strrpos($t3version, '-')) . '.0';
+					}
+
+					$versionRange = tx_em_Tools::splitVersionRange($depV);
+					if ($versionRange[0] != '0.0.0' && version_compare($t3version, $versionRange[0], '<')) {
+						$msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_typo3_too_low'),
+							$t3version, $versionRange[0]);
+						$msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $depK . ']" id="checkIgnore_' . $depK . '" />
+							<label for="checkIgnore_' . $depK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_requirement') . '</label>';
+						$depError = true;
+						continue;
+					} elseif ($versionRange[1] != '0.0.0' && version_compare($t3version, $versionRange[1], '>')) {
+						$msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_typo3_too_high'),
+							$t3version, $versionRange[1]);
+						$msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $depK . ']" id="checkIgnore_' . $depK . '" />
+							<label for="checkIgnore_' . $depK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_requirement') . '</label>';
+						$depError = true;
+						continue;
+					}
+				} elseif (strlen($depK) && !t3lib_extMgm::isLoaded($depK)) { // strlen check for braindead empty dependencies coming from extensions...
+					if (!isset($instExtInfo[$depK])) {
+						$msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_ext_not_available'),
+							$depK);
+						$msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;' . t3lib_iconWorks::getSpriteIcon('actions-system-extension-import', array('title' => $GLOBALS['LANG']->getLL('checkDependencies_import_ext'))) . '&nbsp;
+							<a href="' . t3lib_div::linkThisUrl($this->parentObject->script, array(
+							'CMD[importExt]' => $depK,
+							'CMD[loc]' => 'L',
+							'CMD[standAlone]' => 1
+						)) . '" target="_blank">' . $GLOBALS['LANG']->getLL('checkDependencies_import_now') . '</a>';
+						$msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $depK . ']" id="checkIgnore_' . $depK . '" />
+							<label for="checkIgnore_' . $depK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_ext_requirement') . '</label>';
+					} else {
+						$msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_ext_not_installed'),
+							$depK, $instExtInfo[$depK]['EM_CONF']['title']);
+						$msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;' . tx_em_Tools::installButton() . '&nbsp;
+							<a href="' . t3lib_div::linkThisUrl($this->parentObject->script, array(
+							'CMD[showExt]' => $depK,
+							'CMD[load]' => 1,
+							'CMD[clrCmd]' => 1,
+							'CMD[standAlone]' => 1,
+							'SET[singleDetails]' => 'info'
+						)) .
+								'" target="_blank">' . $GLOBALS['LANG']->getLL('checkDependencies_install_now') . '</a>';
+						$msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $depK . ']" id="checkIgnore_' . $depK . '" />
+							<label for="checkIgnore_' . $depK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_ext_requirement') . '</label>';
+					}
+					$depError = true;
+				} else {
+					$versionRange = tx_em_Tools::splitVersionRange($depV);
+					if ($versionRange[0] != '0.0.0' && version_compare($instExtInfo[$depK]['EM_CONF']['version'], $versionRange[0], '<')) {
+						$msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_ext_too_low'),
+							$depK, $instExtInfo[$depK]['EM_CONF']['version'], $versionRange[0]);
+						$msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $depK . ']" id="checkIgnore_' . $depK . '" />
+							<label for="checkIgnore_' . $depK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_requirement') . '</label>';
+						$depError = true;
+						continue;
+					} elseif ($versionRange[1] != '0.0.0' && version_compare($instExtInfo[$depK]['EM_CONF']['version'], $versionRange[1], '>')) {
+						$msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_ext_too_high'),
+							$depK, $instExtInfo[$depK]['EM_CONF']['version'], $versionRange[1]);
+						$msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $depK . ']" id="checkIgnore_' . $depK . '" />
+							<label for="checkIgnore_' . $depK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_requirement') . '</label>';
+						$depError = true;
+						continue;
+					}
+				}
+			}
+		}
+		if ($depError || $depIgnore) {
+			$content .= $GLOBALS['TBE_TEMPLATE']->section(
+				$GLOBALS['LANG']->getLL('removeExtFromList_dependency_error'),
+				implode('<br />', $msg), 0, 1, 2
+			);
+		}
+
+		// Check conflicts with other extensions:
+		$conflictError = false;
+		$conflictIgnore = false;
+		$msg = array();
+
+		if (isset($conf['constraints']['conflicts']) && is_array($conf['constraints']['conflicts'])) {
+			foreach ((array) $conf['constraints']['conflicts'] as $conflictK => $conflictV) {
+				if ($depsolver['ignore'][$conflictK]) {
+					$msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_conflict_ignored'),
+						$conflictK) . '
+						<input type="hidden" value="1" name="depsolver[ignore][' . $conflictK . ']" />';
+					$conflictIgnore = true;
+					continue;
+				}
+				if (t3lib_extMgm::isLoaded($conflictK)) {
+					$versionRange = tx_em_Tools::splitVersionRange($conflictV);
+					if ($versionRange[0] != '0.0.0' && version_compare($instExtInfo[$conflictK]['EM_CONF']['version'], $versionRange[0], '<')) {
+						continue;
+					}
+					elseif ($versionRange[1] != '0.0.0' && version_compare($instExtInfo[$conflictK]['EM_CONF']['version'], $versionRange[1], '>')) {
+						continue;
+					}
+					$msg[] = sprintf($GLOBALS['LANG']->getLL('checkDependencies_conflict_remove'),
+						$extKey, $conflictK, $instExtInfo[$conflictK]['EM_CONF']['title'], $conflictK, $extKey);
+					$msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;' . tx_em_Tools::removeButton() . '&nbsp;
+						<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
+						'CMD[showExt]' => $conflictK,
+						'CMD[remove]' => 1,
+						'CMD[clrCmd]' => 1,
+						'CMD[standAlone]' => 1,
+						'SET[singleDetails]' => 'info'
+					))) .
+							'" target="_blank">' . $GLOBALS['LANG']->getLL('checkDependencies_remove_now') . '</a>';
+					$msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $conflictK . ']" id="checkIgnore_' . $conflictK . '" />
+						<label for="checkIgnore_' . $conflictK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_conflict') . '</label>';
+					$conflictError = true;
+				}
+			}
+		}
+		if ($conflictError || $conflictIgnore) {
+			$content .= $GLOBALS['TBE_TEMPLATE']->section(
+				$GLOBALS['LANG']->getLL('checkDependencies_conflict_error'), implode('<br />', $msg), 0, 1, 2
+			);
+		}
+
+		// Check suggests on other extensions:
+		if (isset($conf['constraints']['suggests']) && is_array($conf['constraints']['suggests'])) {
+			$suggestion = false;
+			$suggestionIgnore = false;
+			$msg = array();
+			foreach ($conf['constraints']['suggests'] as $suggestK => $suggestV) {
+				if ($depsolver['ignore'][$suggestK]) {
+					$msg[] = '<br />' . sprintf($GLOBALS['LANG']->getLL('checkDependencies_suggestion_ignored'),
+						$suggestK) . '
+				<input type="hidden" value="1" name="depsolver[ignore][' . $suggestK . ']" />';
+					$suggestionIgnore = true;
+					continue;
+				}
+				if (!t3lib_extMgm::isLoaded($suggestK)) {
+					if (!isset($instExtInfo[$suggestK])) {
+						$msg[] = sprintf($GLOBALS['LANG']->getLL('checkDependencies_suggest_import'),
+							$suggestK);
+						$msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;' . t3lib_iconWorks::getSpriteIcon('actions-system-extension-import', array('title' => $GLOBALS['LANG']->getLL('checkDependencies_import_ext'))) . '&nbsp;
+							<a href="' . t3lib_div::linkThisScript(array(
+							'CMD[importExt]' => $suggestK,
+							'CMD[loc]' => 'L',
+							'CMD[standAlone]' => 1
+						)) . '" target="_blank">' . $GLOBALS['LANG']->getLL('checkDependencies_import_now') . '</a>';
+						$msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $suggestK . ']" id="checkIgnore_' . $suggestK . '" />
+							<label for="checkIgnore_' . $suggestK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_suggestion') . '</label>';
+					} else {
+						$msg[] = sprintf($GLOBALS['LANG']->getLL('checkDependencies_suggest_installation'),
+							$suggestK, $instExtInfo[$suggestK]['EM_CONF']['title']);
+						$msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;' . tx_em_Tools::installButton() . '&nbsp;
+							<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
+							'CMD[showExt]' => $suggestK,
+							'CMD[load]' => 1,
+							'CMD[clrCmd]' => 1,
+							'CMD[standAlone]' => 1,
+							'SET[singleDetails]' => 'info'
+						))) .
+								'" target="_blank">' . $GLOBALS['LANG']->getLL('checkDependencies_install_now') . '</a>';
+						$msg[] = '&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" value="1" name="depsolver[ignore][' . $suggestK . ']" id="checkIgnore_' . $suggestK . '" />
+							<label for="checkIgnore_' . $suggestK . '">' . $GLOBALS['LANG']->getLL('checkDependencies_ignore_suggestion') . '</label>';
+					}
+					$suggestion = true;
+				}
+			}
+			if ($suggestion || $suggestionIgnore) {
+				$content .= $GLOBALS['TBE_TEMPLATE']->section(
+					sprintf($GLOBALS['LANG']->getLL('checkDependencies_exts_suggested_by_ext'), $extKey),
+					implode('<br />', $msg), 0, 1, 1
+				);
+			}
+		}
+
+		if ($depError || $conflictError || $suggestion) {
+			foreach ($this->parentObject->CMD as $k => $v) {
+				$content .= '<input type="hidden" name="CMD[' . $k . ']" value="' . $v . '" />';
+			}
+			$content .= '<br /><br /><input type="submit" value="' . $GLOBALS['LANG']->getLL('checkDependencies_try_again') . '" />';
+
+			return array(
+				'returnCode' => FALSE,
+				'html' => '<form action="' . $this->parentObject->script . '" method="post" name="depform">' . $content . '</form>');
+		}
+
+		return array(
+			'returnCode' => TRUE
+		);
+	}
+
+
+	/**
+	 * Delete extension from the file system
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension info array
+	 * @return	string		Returns message string about the status of the operation
+	 */
+	function extDelete($extKey, $extInfo, $command) {
+		$absPath = tx_em_Tools::getExtPath($extKey, $extInfo['type']);
+		if (t3lib_extMgm::isLoaded($extKey)) {
+			return $GLOBALS['LANG']->getLL('extDelete_ext_active');
+		} elseif (!tx_em_Tools::deleteAsType($extInfo['type'])) {
+			return sprintf($GLOBALS['LANG']->getLL('extDelete_wrong_scope'),
+				$this->typeLabels[$extInfo['type']]
+			);
+		} elseif (t3lib_div::inList('G,L', $extInfo['type'])) {
+			if ($command['doDelete'] && !strcmp($absPath, $command['absPath'])) {
+				$res = $this->removeExtDirectory($absPath);
+				if ($res) {
+					$flashMessage = t3lib_div::makeInstance(
+						't3lib_FlashMessage',
+						nl2br($res),
+						sprintf($GLOBALS['LANG']->getLL('extDelete_remove_dir_failed'), $absPath),
+						t3lib_FlashMessage::ERROR
+					);
+					return $flashMessage->render();
+				} else {
+					$flashMessage = t3lib_div::makeInstance(
+						't3lib_FlashMessage',
+						sprintf($GLOBALS['LANG']->getLL('extDelete_removed'), $absPath),
+						$GLOBALS['LANG']->getLL('extDelete_removed_header'),
+						t3lib_FlashMessage::OK
+					);
+					return $flashMessage->render();
+				}
+			} else {
+				$areYouSure = $GLOBALS['LANG']->getLL('extDelete_sure');
+				$deleteFromServer = $GLOBALS['LANG']->getLL('extDelete_from_server');
+				$onClick = "if (confirm('$areYouSure')) {window.location.href='" . t3lib_div::linkThisScript(array(
+					'CMD[showExt]' => $extKey,
+					'CMD[doDelete]' => 1,
+					'CMD[absPath]' => rawurlencode($absPath)
+				)) . "';}";
+				$content .= '<a class="t3-link" href="#" onclick="' . htmlspecialchars($onClick) .
+						' return false;"><strong>' . $deleteFromServer . '</strong> ' .
+						sprintf($GLOBALS['LANG']->getLL('extDelete_from_location'),
+							$this->typeLabels[$extInfo['type']],
+							substr($absPath, strlen(PATH_site))
+						) . '</a>';
+				$content .= '<br /><br />' . $GLOBALS['LANG']->getLL('extDelete_backup');
+				return $content;
+			}
+		} else {
+			return $GLOBALS['LANG']->getLL('extDelete_neither_global_nor_local');
+		}
+	}
+
+	/**
+	 * Removes the extension directory (including content)
+	 *
+	 * @param	string		Extension directory to remove (with trailing slash)
+	 * @param	boolean		If set, will leave the extension directory
+	 * @return	boolean		False on success, otherwise error string.
+	 */
+	function removeExtDirectory($removePath, $removeContentOnly = 0) {
+		$errors = array();
+		if (@is_dir($removePath) && substr($removePath, -1) == '/' && (
+				t3lib_div::isFirstPartOfStr($removePath, tx_em_Tools::typePath('G')) ||
+						t3lib_div::isFirstPartOfStr($removePath, tx_em_Tools::typePath('L')) ||
+						(t3lib_div::isFirstPartOfStr($removePath, tx_em_Tools::typePath('S')) && $this->systemInstall) ||
+						t3lib_div::isFirstPartOfStr($removePath, PATH_site . $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . '_temp_/')) // Playing-around directory...
+		) {
+
+			// All files in extension directory:
+			$fileArr = t3lib_div::getAllFilesAndFoldersInPath(array(), $removePath, '', 1);
+			if (is_array($fileArr)) {
+
+				// Remove files in dirs:
+				foreach ($fileArr as $removeFile) {
+					if (!@is_dir($removeFile)) {
+						if (@is_file($removeFile) && t3lib_div::isFirstPartOfStr($removeFile, $removePath) && strcmp($removeFile, $removePath)) { // ... we are very paranoid, so we check what cannot go wrong: that the file is in fact within the prefix path!
+							@unlink($removeFile);
+							clearstatcache();
+							if (@is_file($removeFile)) {
+								$errors[] = sprintf($GLOBALS['LANG']->getLL('rmExtDir_could_not_be_deleted'),
+									$removeFile
+								);
+							}
+						} else {
+							$errors[] = sprintf($GLOBALS['LANG']->getLL('rmExtDir_error_file'),
+								$removeFile, $removePath
+							);
+						}
+					}
+				}
+
+				// Remove directories:
+				$remDirs = tx_em_Tools::extractDirsFromFileList(t3lib_div::removePrefixPathFromList($fileArr, $removePath));
+				$remDirs = array_reverse($remDirs); // Must delete outer directories first...
+				foreach ($remDirs as $removeRelDir) {
+					$removeDir = $removePath . $removeRelDir;
+					if (@is_dir($removeDir)) {
+						@rmdir($removeDir);
+						clearstatcache();
+						if (@is_dir($removeDir)) {
+							$errors[] = sprintf($GLOBALS['LANG']->getLL('rmExtDir_error_files_left'),
+								$removeDir
+							);
+						}
+					} else {
+						$errors[] = sprintf($GLOBALS['LANG']->getLL('rmExtDir_error_no_dir'),
+							$removeDir
+						);
+					}
+				}
+
+				// If extension dir should also be removed:
+				if (!$removeContentOnly) {
+					@rmdir($removePath);
+					clearstatcache();
+					if (@is_dir($removePath)) {
+						$errors[] = sprintf($GLOBALS['LANG']->getLL('rmExtDir_error_folders_left'),
+							$removePath
+						);
+					}
+				}
+			} else {
+				$errors[] = $GLOBALS['LANG']->getLL('rmExtDir_error') . ' ' . $fileArr;
+			}
+		} else {
+			$errors[] = $GLOBALS['LANG']->getLL('rmExtDir_error_unallowed_path') . ' ' . $removePath;
+		}
+
+		// Return errors if any:
+		return implode(LF, $errors);
+	}
+
+	/**
+	 * Validates the database according to extension requirements
+	 * Prints form for changes if any. If none, returns blank. If an update is ordered, empty is returned as well.
+	 * DBAL compliant (based on Install Tool code)
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @param	boolean		If true, returns array with info.
+	 * @return	mixed		If $infoOnly, returns array with information. Otherwise performs update.
+	 */
+	function checkDBupdates($extKey, $extInfo, $infoOnly = 0) {
+
+
+		$dbStatus = array();
+
+		// Updating tables and fields?
+		if (is_array($extInfo['files']) && in_array('ext_tables.sql', $extInfo['files'])) {
+			$fileContent = t3lib_div::getUrl(tx_em_Tools::getExtPath($extKey, $extInfo['type']) . 'ext_tables.sql');
+
+			$FDfile = $this->install->getFieldDefinitions_fileContent($fileContent);
+			if (count($FDfile)) {
+				$FDdb = $this->install->getFieldDefinitions_database(TYPO3_db);
+				$diff = $this->install->getDatabaseExtra($FDfile, $FDdb);
+				$update_statements = $this->install->getUpdateSuggestions($diff);
+
+				$dbStatus['structure']['tables_fields'] = $FDfile;
+				$dbStatus['structure']['diff'] = $diff;
+
+				// Updating database...
+				if (!$infoOnly && is_array($this->install->INSTALL['database_update'])) {
+					$this->install->performUpdateQueries($update_statements['add'], $this->install->INSTALL['database_update']);
+					$this->install->performUpdateQueries($update_statements['change'], $this->install->INSTALL['database_update']);
+					$this->install->performUpdateQueries($update_statements['create_table'], $this->install->INSTALL['database_update']);
+				} else {
+					$content .= $this->install->generateUpdateDatabaseForm_checkboxes(
+						$update_statements['add'], $GLOBALS['LANG']->getLL('checkDBupdates_add_fields'));
+					$content .= $this->install->generateUpdateDatabaseForm_checkboxes(
+						$update_statements['change'], $GLOBALS['LANG']->getLL('checkDBupdates_changing_fields'), 1, 0, $update_statements['change_currentValue']);
+					$content .= $this->install->generateUpdateDatabaseForm_checkboxes(
+						$update_statements['create_table'], $GLOBALS['LANG']->getLL('checkDBupdates_add_tables'));
+				}
+			}
+		}
+
+		// Importing static tables?
+		if (is_array($extInfo['files']) && in_array('ext_tables_static+adt.sql', $extInfo['files'])) {
+			$fileContent = t3lib_div::getUrl(tx_em_Tools::getExtPath($extKey, $extInfo['type']) . 'ext_tables_static+adt.sql');
+
+			$statements = $this->install->getStatementarray($fileContent, 1);
+			list($statements_table, $insertCount) = $this->install->getCreateTables($statements, 1);
+
+			// Execute import of static table content:
+			if (!$infoOnly && is_array($this->install->INSTALL['database_import'])) {
+
+				// Traverse the tables
+				foreach ($this->install->INSTALL['database_import'] as $table => $md5str) {
+					if ($md5str == md5($statements_table[$table])) {
+						$GLOBALS['TYPO3_DB']->admin_query('DROP TABLE IF EXISTS ' . $table);
+						$GLOBALS['TYPO3_DB']->admin_query($statements_table[$table]);
+
+						if ($insertCount[$table]) {
+							$statements_insert = $this->install->getTableInsertStatements($statements, $table);
+
+							foreach ($statements_insert as $v) {
+								$GLOBALS['TYPO3_DB']->admin_query($v);
+							}
+						}
+					}
+				}
+			} else {
+				$whichTables = $this->install->getListOfTables();
+				if (count($statements_table)) {
+					$out = '';
+					foreach ($statements_table as $table => $definition) {
+						$exist = isset($whichTables[$table]);
+
+						$dbStatus['static'][$table]['exists'] = $exist;
+						$dbStatus['static'][$table]['count'] = $insertCount[$table];
+
+						$out .= '<tr>
+							<td><input type="checkbox" name="TYPO3_INSTALL[database_import][' . $table . ']" checked="checked" value="' . md5($definition) . '" /></td>
+							<td><strong>' . $table . '</strong></td>
+							<td><img src="clear.gif" width="10" height="1" alt="" /></td>
+							<td nowrap="nowrap">' .
+								($insertCount[$table] ?
+										$GLOBALS['LANG']->getLL('checkDBupdates_rows') . ' ' . $insertCount[$table]
+										: '') .
+								'</td>
+							<td><img src="clear.gif" width="10" height="1" alt="" /></td>
+							<td nowrap="nowrap">' .
+								($exist ?
+										t3lib_iconWorks::getSpriteIcon('status-dialog-warning') .
+												$GLOBALS['LANG']->getLL('checkDBupdates_table_exists')
+										: '') .
+								'</td>
+							</tr>';
+					}
+					$content .= '
+						<br />
+						<h3>' . $GLOBALS['LANG']->getLL('checkDBupdates_import_static_data') . '</h3>
+						<table border="0" cellpadding="0" cellspacing="0">' . $out . '</table>
+						';
+				}
+			}
+		}
+
+		// Return array of information if $infoOnly, otherwise content.
+		return $infoOnly ? $dbStatus : $content;
+	}
+
+	/**
+	 * Removes the current extension of $type and creates the base folder for the new one (which is going to be imported)
+	 *
+	 * @param	array		Data for imported extension
+	 * @param	string		Extension installation scope (L,G,S)
+	 * @param	boolean		If set, nothing will be deleted (neither directory nor files)
+	 * @return	mixed		Returns array on success (with extension directory), otherwise an error string.
+	 */
+	function clearAndMakeExtensionDir($importedData, $type, $dontDelete = 0) {
+		if (!$importedData['extKey']) {
+			return $GLOBALS['LANG']->getLL('clearMakeExtDir_no_ext_key');
+		}
+
+		// Setting install path (L, G, S or fileadmin/_temp_/)
+		$path = '';
+		switch ((string) $type) {
+			case 'G':
+			case 'L':
+				$path = tx_em_Tools::typePath($type);
+				$suffix = '';
+
+				// Creates the typo3conf/ext/ directory if it does NOT already exist:
+				if ((string) $type == 'L' && !@is_dir($path)) {
+					t3lib_div::mkdir($path);
+				}
+				break;
+			default:
+				if ($this->systemInstall && (string) $type == 'S') {
+					$path = tx_em_Tools::typePath($type);
+					$suffix = '';
+				} else {
+					$path = PATH_site . $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'] . '_temp_/';
+					$suffix = '_' . date('dmy-His');
+				}
+				break;
+		}
+
+		// If the install path is OK...
+		if ($path && @is_dir($path)) {
+
+			// Set extension directory:
+			$extDirPath = $path . $importedData['extKey'] . $suffix . '/';
+
+			// Install dir was found, remove it then:
+			if (@is_dir($extDirPath)) {
+				if ($dontDelete) {
+					return array($extDirPath);
+				}
+				$res = $this->removeExtDirectory($extDirPath);
+				if ($res) {
+					$flashMessage = t3lib_div::makeInstance(
+						't3lib_FlashMessage',
+						nl2br($res),
+						sprintf($GLOBALS['LANG']->getLL('clearMakeExtDir_could_not_remove_dir'), $extDirPath),
+						t3lib_FlashMessage::ERROR
+					);
+					return $flashMessage->render();
+				}
+			}
+
+			// We go create...
+			t3lib_div::mkdir($extDirPath);
+			if (!is_dir($extDirPath)) {
+				return sprintf($GLOBALS['LANG']->getLL('clearMakeExtDir_could_not_create_dir'),
+					$extDirPath);
+			}
+			return array($extDirPath);
+		} else {
+			return sprintf($GLOBALS['LANG']->getLL('clearMakeExtDir_no_dir'),
+				$path);
+		}
+	}
+
+
+	/*******************************
+	 *
+	 * Extension analyzing (detailed information)
+	 *
+	 ******************************/
+
+	/**
+	 * Perform a detailed, technical analysis of the available extension on server!
+	 * Includes all kinds of verifications
+	 * Takes some time to process, therfore use with care, in particular in listings.
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information
+	 * @param	boolean		If set, checks for validity of classes etc.
+	 * @return	array		Information in an array.
+	 */
+	function makeDetailedExtensionAnalysis($extKey, $extInfo, $validity = 0) {
+
+		// Get absolute path of the extension
+		$absPath = tx_em_Tools::getExtPath($extKey, $extInfo['type']);
+		$extensionDetails = t3lib_div::makeInstance('tx_em_Extensions_Details', $this);
+		$infoArray = array();
+
+		$table_class_prefix = substr($extKey, 0, 5) == 'user_' ? 'user_' : 'tx_' . str_replace('_', '', $extKey) . '_';
+		$module_prefix = substr($extKey, 0, 5) == 'user_' ? 'u' : 'tx' . str_replace('_', '', $extKey);
+
+		// Database status:
+		$dbInfo = $this->checkDBupdates($extKey, $extInfo, 1);
+
+		// Database structure required:
+		if (is_array($dbInfo['structure']['tables_fields'])) {
+			$modify_tables = t3lib_div::trimExplode(',', $extInfo['EM_CONF']['modify_tables'], 1);
+			$infoArray['dump_tf'] = array();
+
+			foreach ($dbInfo['structure']['tables_fields'] as $tN => $d) {
+				if (in_array($tN, $modify_tables)) {
+					$infoArray['fields'][] = $tN . ': <i>' .
+							(is_array($d['fields']) ? implode(', ', array_keys($d['fields'])) : '') .
+							(is_array($d['keys']) ?
+									' + ' . count($d['keys']) . ' ' . $GLOBALS['LANG']->getLL('detailedExtAnalysis_keys') : '') .
+							'</i>';
+					if (is_array($d['fields'])) {
+						foreach ($d['fields'] as $fN => $value) {
+							$infoArray['dump_tf'][] = $tN . '.' . $fN;
+							if (!t3lib_div::isFirstPartOfStr($fN, $table_class_prefix)) {
+								$infoArray['NSerrors']['fields'][$fN] = $fN;
+							} else {
+								$infoArray['NSok']['fields'][$fN] = $fN;
+							}
+						}
+					}
+					if (is_array($d['keys'])) {
+						foreach ($d['keys'] as $fN => $value) {
+							$infoArray['dump_tf'][] = $tN . '.KEY:' . $fN;
+						}
+					}
+				} else {
+					$infoArray['dump_tf'][] = $tN;
+					$infoArray['tables'][] = $tN;
+					if (!t3lib_div::isFirstPartOfStr($tN, $table_class_prefix)) {
+						$infoArray['NSerrors']['tables'][$tN] = $tN;
+					} else {
+						$infoArray['NSok']['tables'][$tN] = $tN;
+					}
+				}
+			}
+			if (count($dbInfo['structure']['diff']['diff']) || count($dbInfo['structure']['diff']['extra'])) {
+				$msg = array();
+				if (count($dbInfo['structure']['diff']['diff'])) {
+					$msg[] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_tables_are_missing');
+				}
+				if (count($dbInfo['structure']['diff']['extra'])) {
+					$msg[] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_tables_are_of_wrong_type');
+				}
+				$infoArray['tables_error'] = 1;
+				if (t3lib_extMgm::isLoaded($extKey)) {
+					$infoArray['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_tables_are'),
+						implode(' ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:and') . ' ', $msg)
+					);
+				}
+			}
+		}
+
+		// Static tables?
+		if (is_array($dbInfo['static'])) {
+			$infoArray['static'] = array_keys($dbInfo['static']);
+
+			foreach ($dbInfo['static'] as $tN => $d) {
+				if (!$d['exists']) {
+					$infoArray['static_error'] = 1;
+					if (t3lib_extMgm::isLoaded($extKey)) {
+						$infoArray['errors'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_static_tables_missing');
+					}
+					if (!t3lib_div::isFirstPartOfStr($tN, $table_class_prefix)) {
+						$infoArray['NSerrors']['tables'][$tN] = $tN;
+					} else {
+						$infoArray['NSok']['tables'][$tN] = $tN;
+					}
+				}
+			}
+		}
+
+		// Backend Module-check:
+		$knownModuleList = t3lib_div::trimExplode(',', $extInfo['EM_CONF']['module'], 1);
+		foreach ($knownModuleList as $mod) {
+			if (@is_dir($absPath . $mod)) {
+				if (@is_file($absPath . $mod . '/conf.php')) {
+					$confFileInfo = $extensionDetails->modConfFileAnalysis($absPath . $mod . '/conf.php');
+					if (is_array($confFileInfo['TYPO3_MOD_PATH'])) {
+						$shouldBePath = $this->typeRelPaths[$extInfo['type']] . $extKey . '/' . $mod . '/';
+						if (strcmp($confFileInfo['TYPO3_MOD_PATH'][1][1], $shouldBePath)) {
+							$infoArray['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_wrong_mod_path'),
+								$confFileInfo['TYPO3_MOD_PATH'][1][1],
+								$shouldBePath
+							);
+						}
+					} else {
+						// It seems like TYPO3_MOD_PATH and therefore also this warning is no longer needed.
+						// $infoArray['errors'][] = 'No definition of TYPO3_MOD_PATH constant found inside!';
+					}
+					if (is_array($confFileInfo['MCONF_name'])) {
+						$mName = $confFileInfo['MCONF_name'][1][1];
+						$mNameParts = explode('_', $mName);
+						$infoArray['moduleNames'][] = $mName;
+						if (!t3lib_div::isFirstPartOfStr($mNameParts[0], $module_prefix) &&
+								(!$mNameParts[1] || !t3lib_div::isFirstPartOfStr($mNameParts[1], $module_prefix))) {
+							$infoArray['NSerrors']['modname'][] = $mName;
+						} else {
+							$infoArray['NSok']['modname'][] = $mName;
+						}
+					} else {
+						$infoArray['errors'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_mconf_missing');
+					}
+				} else  {
+					$infoArray['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_be_module_conf_missing'),
+							$mod . '/conf.php'
+					);
+				}
+			} else {
+				$infoArray['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_module_folder_missing'),
+						$mod . '/'
+				);
+			}
+		}
+		$dirs = t3lib_div::get_dirs($absPath);
+		if (is_array($dirs)) {
+			reset($dirs);
+			while (list(, $mod) = each($dirs)) {
+				if (!in_array($mod, $knownModuleList) && @is_file($absPath . $mod . '/conf.php')) {
+					$confFileInfo = $extensionDetails->modConfFileAnalysis($absPath . $mod . '/conf.php');
+					if (is_array($confFileInfo)) {
+						$infoArray['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_unconfigured_module'),
+								$mod . '/conf.php'
+						);
+					}
+				}
+			}
+		}
+
+		// ext_tables.php:
+		if (@is_file($absPath . 'ext_tables.php')) {
+			$content = t3lib_div::getUrl($absPath . 'ext_tables.php');
+			if (stristr($content, 't3lib_extMgm::addModule')) {
+				$infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_module');
+			}
+			if (stristr($content, 't3lib_extMgm::insertModuleFunction')) {
+				$infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_module_and_more');
+			}
+			if (stristr($content, 't3lib_div::loadTCA')) {
+				$infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_loadTCA');
+			}
+			if (stristr($content, '$TCA[')) {
+				$infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_TCA');
+			}
+			if (stristr($content, 't3lib_extMgm::addPlugin')) {
+				$infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_plugin');
+			}
+		}
+
+		// ext_localconf.php:
+		if (@is_file($absPath . 'ext_localconf.php')) {
+			$content = t3lib_div::getUrl($absPath . 'ext_localconf.php');
+			if (stristr($content, 't3lib_extMgm::addPItoST43')) {
+				$infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_plugin_st43');
+			}
+			if (stristr($content, 't3lib_extMgm::addPageTSConfig')) {
+				$infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_page_ts');
+			}
+			if (stristr($content, 't3lib_extMgm::addUserTSConfig')) {
+				$infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_user_ts');
+			}
+			if (stristr($content, 't3lib_extMgm::addTypoScriptSetup')) {
+				$infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_ts_setup');
+			}
+			if (stristr($content, 't3lib_extMgm::addTypoScriptConstants')) {
+				$infoArray['flags'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_ts_constants');
+			}
+		}
+
+		if (@is_file($absPath . 'ext_typoscript_constants.txt')) {
+			$infoArray['TSfiles'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_constants');
+		}
+		if (@is_file($absPath . 'ext_typoscript_setup.txt')) {
+			$infoArray['TSfiles'][] = $GLOBALS['LANG']->getLL('detailedExtAnalysis_setup');
+		}
+		if (@is_file($absPath . 'ext_conf_template.txt')) {
+			$infoArray['conf'] = 1;
+		}
+
+		// Classes:
+		if ($validity) {
+			$filesInside = tx_em_Tools::getClassIndexLocallangFiles($absPath, $table_class_prefix, $extKey);
+			if (is_array($filesInside['errors'])) {
+				$infoArray['errors'] = array_merge((array) $infoArray['errors'], $filesInside['errors']);
+			}
+			if (is_array($filesInside['NSerrors'])) {
+				$infoArray['NSerrors'] = array_merge((array) $infoArray['NSerrors'], $filesInside['NSerrors']);
+			}
+			if (is_array($filesInside['NSok'])) {
+				$infoArray['NSok'] = array_merge((array) $infoArray['NSok'], $filesInside['NSok']);
+			}
+			$infoArray['locallang'] = $filesInside['locallang'];
+			$infoArray['classes'] = $filesInside['classes'];
+		}
+
+		// Upload folders
+		if ($extInfo['EM_CONF']['uploadfolder']) {
+			$infoArray['uploadfolder'] = tx_em_Tools::uploadFolder($extKey);
+			if (!@is_dir(PATH_site . $infoArray['uploadfolder'])) {
+				$infoArray['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_no_upload_folder'),
+					$infoArray['uploadfolder']
+				);
+				$infoArray['uploadfolder'] = '';
+			}
+		}
+
+		// Create directories:
+		if ($extInfo['EM_CONF']['createDirs']) {
+			$infoArray['createDirs'] = array_unique(t3lib_div::trimExplode(',', $extInfo['EM_CONF']['createDirs'], 1));
+			foreach ($infoArray['createDirs'] as $crDir) {
+				if (!@is_dir(PATH_site . $crDir)) {
+					$infoArray['errors'][] = sprintf($GLOBALS['LANG']->getLL('detailedExtAnalysis_no_upload_folder'),
+						$crDir
+					);
+				}
+			}
+		}
+
+		// Return result array:
+		return $infoArray;
+	}
+
+
+	/**
+	 * Produces the config form for an extension (if any template file, ext_conf_template.txt is found)
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @param	boolean		If true, the form HTML content is returned, otherwise the content is set in $this->content.
+	 * @param	string		Submit-to URL (supposedly)
+	 * @param	string		Additional form fields to include.
+	 * @return	string		Depending on $output. Can return the whole form.
+	 */
+	function tsStyleConfigForm($extKey, $extInfo, $output = 0, $script = '', $addFields = '') {
+		global $TYPO3_CONF_VARS;
+
+		// Initialize:
+		$absPath = tx_em_Tools::getExtPath($extKey, $extInfo['type']);
+		$relPath = $this->typeRelPaths[$extInfo['type']] . $extKey . '/';
+
+		// Look for template file for form:
+		if (t3lib_extMgm::isLoaded($extKey) && @is_file($absPath . 'ext_conf_template.txt')) {
+
+			// Load tsStyleConfig class and parse configuration template:
+			$tsStyleConfig = t3lib_div::makeInstance('t3lib_tsStyleConfig');
+			$tsStyleConfig->doNotSortCategoriesBeforeMakingForm = TRUE;
+			$theConstants = $tsStyleConfig->ext_initTSstyleConfig(
+				t3lib_div::getUrl($absPath . 'ext_conf_template.txt'),
+				$relPath,
+				$absPath,
+				$GLOBALS['BACK_PATH']
+			);
+
+			// Load the list of resources.
+			$tsStyleConfig->ext_loadResources($absPath . 'res/');
+
+			// Load current value:
+			$arr = unserialize($TYPO3_CONF_VARS['EXT']['extConf'][$extKey]);
+			$arr = is_array($arr) ? $arr : array();
+
+			// Call processing function for constants config and data before write and form rendering:
+			if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/mod/tools/em/index.php']['tsStyleConfigForm'])) {
+				$_params = array('fields' => &$theConstants, 'data' => &$arr, 'extKey' => $extKey);
+				foreach ($TYPO3_CONF_VARS['SC_OPTIONS']['typo3/mod/tools/em/index.php']['tsStyleConfigForm'] as $_funcRef) {
+					t3lib_div::callUserFunction($_funcRef, $_params, $this);
+				}
+				unset($_params);
+			}
+
+			// If saving operation is done:
+			if (t3lib_div::_POST('submit')) {
+				$tsStyleConfig->ext_procesInput(t3lib_div::_POST(), array(), $theConstants, array());
+				$arr = $tsStyleConfig->ext_mergeIncomingWithExisting($arr);
+				$this->writeTsStyleConfig($extKey, $arr);
+			}
+
+			// Setting value array
+			$tsStyleConfig->ext_setValuearray($theConstants, $arr);
+
+			// Getting session data:
+			$MOD_MENU = array();
+			$MOD_MENU['constant_editor_cat'] = $tsStyleConfig->ext_getCategoriesForModMenu();
+			$MOD_SETTINGS = t3lib_BEfunc::getModuleData($MOD_MENU, t3lib_div::_GP('SET'), 'xMod_test');
+			/*
+				   // Resetting the menu (stop)
+			   if (count($MOD_MENU['constant_editor_cat']) > 1) {
+				   $menu = $GLOBALS['LANG']->getLL('extInfoArray_category') . ' ' .
+					   t3lib_BEfunc::getFuncMenu(0, 'SET[constant_editor_cat]', $MOD_SETTINGS['constant_editor_cat'], $MOD_MENU['constant_editor_cat'], '', '&CMD[showExt]=' . $extKey);
+				   $this->content.=$this->doc->section('','<span class="nobr">'.$menu.'</span>');
+				   $this->content.=$this->doc->spacer(10);
+			   }
+   */
+			// Category and constant editor config:
+			$form = '
+				<table border="0" cellpadding="0" cellspacing="0" width="600">
+					<tr>
+						<td>' . $tsStyleConfig->ext_getForm($MOD_SETTINGS['constant_editor_cat'], $theConstants, $script, $addFields) . '</form></td>
+					</tr>
+				</table>';
+		} else {
+			$flashMessage = t3lib_div::makeInstance(
+				't3lib_FlashMessage',
+				$GLOBALS['LANG']->getLL('tsStyleConfigForm_additional_config'),
+				'',
+				t3lib_FlashMessage::INFO
+			);
+
+			$form = '
+				<table border="0" cellpadding="0" cellspacing="0" width="600">
+					<tr>
+						<td>
+							<form action="' . htmlspecialchars($script) . '" method="post">' .
+					$addFields .
+					$flashMessage->render() .
+					'<br /><input type="submit" name="write" value="' . $GLOBALS['LANG']->getLL('updatesForm_make_updates') . '" />
+							</form>
+						</td>
+					</tr>
+				</table>';
+		}
+
+		#if ($output) {
+		return $form;
+		#} else {
+		#	$this->content.=$this->doc->section('', $form);
+		#}
+
+
+	}
+
+	/**
+	 * Writes the TSstyleconf values to "localconf.php"
+	 * Removes the temp_CACHED* files before return.
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Configuration array to write back
+	 * @return	void
+	 */
+	function writeTsStyleConfig($extKey, $arr) {
+
+		// Instance of install tool
+		$instObj = new t3lib_install;
+		$instObj->allowUpdateLocalConf = 1;
+		$instObj->updateIdentity = 'TYPO3 Extension Manager';
+
+		// Get lines from localconf file
+		$lines = $instObj->writeToLocalconf_control();
+		$instObj->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'EXT\'][\'extConf\'][\'' . $extKey . '\']', serialize($arr)); // This will be saved only if there are no linebreaks in it !
+		$instObj->writeToLocalconf_control($lines);
+
+		t3lib_extMgm::removeCacheFiles();
+	}
+
+
+	/**
+	 * Creates a form for an extension which contains all options for configuration, updates of database, clearing of cache etc.
+	 * This form is shown when
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @param	boolean		If set, the form will ONLY show if fields/tables should be updated (suppressing forms like general configuration and cache clearing).
+	 * @param	string		Alternative action=""-script
+	 * @param	string		HTML: Additional form fields
+	 * @return	string		HTML
+	 */
+	function updatesForm($extKey, $extInfo, $notSilent = 0, $script = '', $addFields = '', $addForm = TRUE) {
+		$script = $script ? $script : t3lib_div::linkThisScript();
+		if ($addForm) {
+			$formWrap = array('<form action="' . htmlspecialchars($script) . '" method="POST">', '</form>');
+		} else {
+			$formWrap = array('', '');
+		}
+		$extensionDetails = t3lib_div::makeInstance('tx_em_Extensions_Details', $this);
+
+		$updates .= $this->checkDBupdates($extKey, $extInfo);
+		$uCache = $this->checkClearCache($extInfo);
+		if ($notSilent) {
+			$updates .= $uCache;
+		}
+		$updates .= $extensionDetails->checkUploadFolder($extKey, $extInfo);
+
+		$absPath = tx_em_Tools::getExtPath($extKey, $extInfo['type']);
+		if ($notSilent && @is_file($absPath . 'ext_conf_template.txt')) {
+			$configForm = $this->tsStyleConfigForm($extKey, $extInfo, 1, $script, $updates . $addFields . '<br />');
+		}
+
+		if ($updates || $configForm) {
+			if ($configForm) {
+				$updates = $configForm;
+			} else {
+				$updates = $formWrap[0] . $updates . $addFields . '
+					<br /><input type="submit" name="write" id="update-submit-' . $extKey . '" value="' . $GLOBALS['LANG']->getLL('updatesForm_make_updates') . '" />
+				' . $formWrap[1];
+			}
+		}
+
+		return $updates;
+	}
+
+
+	/**
+	 * Check if clear-cache should be performed, otherwise show form (for installation of extension)
+	 * Shown only if the extension has the clearCacheOnLoad flag set.
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @return	string		HTML output (if form is shown)
+	 */
+	function checkClearCache($extInfo) {
+		if ($extInfo['EM_CONF']['clearCacheOnLoad']) {
+			if (t3lib_div::_POST('_clear_all_cache')) { // Action: Clearing the cache
+				$tce = t3lib_div::makeInstance('t3lib_TCEmain');
+				$tce->stripslashes_values = 0;
+				$tce->start(array(), array());
+				$tce->clear_cacheCmd('all');
+			} else { // Show checkbox for clearing cache:
+				$content .= '
+					<br />
+					<h3>' . $GLOBALS['LANG']->getLL('checkUploadFolder_clear_cache') . '</h3>
+					<p>' . $GLOBALS['LANG']->getLL('checkUploadFolder_clear_cache_requested') . '<br />
+						<label for="check_clear_all_cache">' . $GLOBALS['LANG']->getLL('checkUploadFolder_clear_all_cache') . '</label>
+						<input type="checkbox" name="_clear_all_cache" id="check_clear_all_cache" checked="checked" value="1" /><br />
+					</p>
+				';
+			}
+		}
+		return $content;
+	}
+
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/language/locallang.xml
===================================================================
--- typo3/sysext/em/language/locallang.xml	(revision 9222)
+++ typo3/sysext/em/language/locallang.xml	(revision )
@@ -8,6 +8,505 @@
 		<languageKey index="default" type="array">
 			<label index="tasks_updateExtensionlistTask.name">Update extension list</label>
 			<label index="tasks_updateExtensionlistTask.description">Update extension list on a regular basis. Once a day is a good interval.</label>
+			<label index="mlang_labels_tablabel">TYPO3 Extension Manager</label>
+			<label index="mlang_labels_tabdescr">Manages TYPO3 extensions from a central repository, which includes plugins, modules, class extensions, configuration code etc.</label>
+			<label index="mlang_tabs_tab">Ext Manager</label>
+			<label index="category_BE">Backend</label>
+			<label index="category_BE_modules">Backend Modules</label>
+			<label index="category_FE">Frontend</label>
+			<label index="category_FE_plugins">Frontend Plugins</label>
+			<label index="category_miscellanous">Miscellaneous</label>
+			<label index="category_services">Services</label>
+			<label index="category_templates">Templates</label>
+			<label index="category_examples">Examples</label>
+			<label index="category_documentation">Documentation</label>
+			<label index="state_alpha">Alpha</label>
+			<label index="state_beta">Beta</label>
+			<label index="state_stable">Stable</label>
+			<label index="state_experimental">Experimental</label>
+			<label index="state_test">Test</label>
+			<label index="state_obsolete">Obsolete</label>
+			<label index="state_exclude_from_updates">Exclude From Updates</label>
+			<label index="type_system">System</label>
+			<label index="type_global">Global</label>
+			<label index="type_local">Local</label>
+			<label index="descr_system">System extension (typo3/sysext/) - Always distributed with the TYPO3 source code (static).</label>
+			<label index="descr_global">Global extension (typo3/ext/) - Available for shared source on server (dynamic).</label>
+			<label index="descr_local">Local extension (typo3conf/ext/) - Local for this TYPO3 installation only (dynamic).</label>
+			<label index="privacy_notice">When you interact with the online repository, server information may be sent and stored in the repository for statistics.</label>
+			<label index="security_header">Did you find a security problem?</label>
+			<label index="security_warning_extensions">Please be aware that extensions are third-party software. Installing an extension is a security risk, as the high level of quality and security in the TYPO3 Core can not be assured in these extensions.</label>
+			<label index="security_descr">If you think you have found a security issue in TYPO3 or an extension, please contact the %sTYPO3 security team%s! Thank you!</label>
+			<label index="menu_loaded_extensions">Loaded extensions</label>
+			<label index="menu_install_extensions">Install extensions</label>
+			<label index="menu_import_extensions">Import extensions</label>
+			<label index="menu_translation_handling">Translation handling</label>
+			<label index="menu_settings">Settings</label>
+			<label index="menu_extension_updates">Check for extension updates</label>
+			<label index="menu_extension_develop">Developer Module</label>
+			<label index="list_order_category">Category</label>
+			<label index="list_order_author">Author</label>
+			<label index="list_order_state">State</label>
+			<label index="list_order_type">Type</label>
+			<label index="show_details">Details</label>
+			<label index="show_description">Description</label>
+			<label index="show_more_details">More details</label>
+			<label index="show_technical">Technical (takes time!)</label>
+			<label index="show_validating">Validating (takes time!)</label>
+			<label index="show_changed">Changed? (takes time!)</label>
+			<label index="details_info">Information</label>
+			<label index="details_edit">Edit files</label>
+			<label index="details_backup_delete">Backup/Delete</label>
+			<label index="details_dump_db">Dump DB</label>
+			<label index="details_upload">Upload to TER</label>
+			<label index="details_update">UPDATE!</label>
+			<label index="header">Extension Manager</label>
+			<label index="group_by">Group by:</label>
+			<label index="show">Show:</label>
+			<label index="display_shy">Display shy extensions:</label>
+			<label index="only_my_ext">Only my extensions:</label>
+			<label index="show_obsolete">Show obsolete:</label>
+			<label index="go_back">Go back</label>
+			<label index="look_up">Look up:</label>
+			<label index="loaded_exts">Loaded Extensions</label>
+			<label index="how_to_install">If you want to use an extension in TYPO3, you should simply click the "plus" button %s .</label>
+			<label index="how_to_uninstall">Installed extensions can also be removed again - just click the remove button %s .</label>
+			<label index="available_extensions">Available Extensions - Grouped by: %s</label>
+			<label index="do_update">Update the extension in '%s' from online repository to server</label>
+			<label index="global">global</label>
+			<label index="local">local</label>
+			<label index="excluded_from_updates">The extension is excluded from updates! You can change this in the appropriate ext_emconf.php file.</label>
+			<label index="import_to_local_dir">Import this extension from online repository to the 'local' directory typo3conf/ext/.</label>
+			<label index="list_or_look_up">List or look up %s extensions</label>
+			<label index="list_or_look_up_extensions">Look up extensions:</label>
+			<label index="list_or_look_up_all">all</label>
+			<label index="list_or_look_up_reviewed">reviewed</label>
+			<label index="look_up_button">Look up</label>
+			<label index="privacy_notice_header">PRIVACY NOTICE:</label>
+			<label index="extensions_repository_group_by">Extensions in TYPO3 Extension Repository (online) - Grouped by:</label>
+			<label index="extension_required_short">Rq</label>
+			<label index="list_of_local_extensions">This is the list of extensions which are available locally, but not in the repository.</label>
+			<label index="might_be_user_defined">They might be user-defined and should be prepended user_ then.</label>
+			<label index="only_on_this_server">Extensions found only on this server</label>
+			<label index="no_matching_extensions">No matching extensions found.</label>
+			<label index="connect_to_ter">Connect to the current mirror and retrieve the current list of available plugins from the TYPO3 Extension Repository.</label>
+			<label index="retrieve_update">Retrieve/Update</label>
+			<label index="ext_list_last_updated">(last update: %s)</label>
+			<label index="in_repository">Extensions in TYPO3 Extension Repository</label>
+			<label index="upload_t3x">Upload extension file (.t3x):</label>
+			<label index="upload_to_location">...to location:</label>
+			<label index="local_folder">Local (../typo3conf/ext/)</label>
+			<label index="global_folder">Global (typo3/ext/)</label>
+			<label index="system_folder">System (typo3/sysext/)</label>
+			<label index="overwrite_ext">Overwrite any existing extension!</label>
+			<label index="upload_ext_file">Upload extension file</label>
+			<label index="upload_ext_directly">Upload extension file directly (.t3x):</label>
+			<label index="previous_page">Prev page</label>
+			<label index="next_page">Next page</label>
+			<label index="showing_extensions_from_to">Showing extensions %s to %s</label>
+			<label index="security_settings">Security Settings</label>
+			<label index="show_exts_without_security_check">Enable extensions without review (basic security check):</label>
+			<label index="notice">Notice:</label>
+			<label index="security_notice">Make sure you know what consequences enabling this checkbox might have. Check the %sinformation on typo3.org about security reviews%s!</label>
+			<label index="user_settings">User Settings</label>
+			<label index="enter_repository_username">Enter repository username:</label>
+			<label index="enter_repository_password">Enter repository password:</label>
+			<label index="repository_password_info">This is &lt;em&gt;not&lt;/em&gt; your password to the TYPO3 backend! This user information is what is needed to log in at typo3.org with your account there!</label>
+			<label index="mirror_selection">Mirror selection</label>
+			<label index="mirror_list_url">Enter mirror list URL:</label>
+			<label index="mirror_select">Select a mirror from below. This list is built from the online mirror list retrieved from the URL above.</label>
+			<label index="mirror_list">Mirror list</label>
+			<label index="mirror_list_reload">Click here to reload the list.</label>
+			<label index="mirror_use">Use</label>
+			<label index="mirror_name">Name</label>
+			<label index="mirror_url">URL</label>
+			<label index="mirror_country">Country</label>
+			<label index="mirror_sponsored_by">Sponsored by</label>
+			<label index="mirror_use_random">Random (recommended!)</label>
+			<label index="enter_repository_url">Enter repository URL:</label>
+			<label index="repository_url_hint">If you set a repository URL, this overrides the use of a mirror. Use this to select a specific (private) repository.</label>
+			<label index="repository_settings">Repository settings</label>
+			<label index="translation_settings">Translation Settings</label>
+			<label index="languages_to_fetch">Languages to fetch:</label>
+			<label index="translation_info">For the selected languages the EM tries to download and install translation files if available, whenever an extension is installed. (This replaces the &lt;code&gt;csh_*&lt;/code&gt; extensions that were used to install core translations before TYPO3 version 4!)</label>
+			<label index="translation_loaded_exts">To request an update or installation for already loaded extensions, see below.</label>
+			<label index="translation_save_selection">Save selection</label>
+			<label index="translation_check_status_button">Check status against repository</label>
+			<label index="translation_update_button">Update from repository</label>
+			<label index="translation_status">Translation status</label>
+			<label index="translation_check_status">Checking translation status, please wait...</label>
+			<label index="translation_table_check">This table shows the status of the translations of the loaded extensions.</label>
+			<label index="translation_extension_key">Extension key</label>
+			<label index="translation_checking_extension">Checking translation status for extension \"%s\"...</label>
+			<label index="translation_no_translation">No translation available</label>
+			<label index="translation_n_a">N/A</label>
+			<label index="translation_not_installed">Not installed/Unknown</label>
+			<label index="translation_status_unknown">???</label>
+			<label index="translation_needs_update">Needs update</label>
+			<label index="translation_status_update">UPD</label>
+			<label index="translation_is_ok">Is up to date</label>
+			<label index="translation_status_ok">OK</label>
+			<label index="translation_check_done">Check done.</label>
+			<label index="translation_update_status">Updating translations, please wait...</label>
+			<label index="translation_table_update">This table shows the update results of the translations of the loaded extensions.</label>
+			<label index="translation_full_check_update">If you want to force a full check or update, delete the l10n zip-files from the typo3temp folder.</label>
+			<label index="translation_updating_extension">Updating translation for extension \"%s\"...</label>
+			<label index="translation_has_been_updated">Has been updated</label>
+			<label index="translation_status_error">ERR</label>
+			<label index="translation_problems">Possible reasons: Network problems, allow_url_fopen is off, cURL is not enabled in the Install Tool</label>
+			<label index="translation_status_could_not_fetch">Could not fetch translation status</label>
+			<label index="translation_update_done">Update done.</label>
+			<label index="translation_unpacking_failed">Unpacking the language pack failed!</label>
+			<label index="ext_load_details_button">Load details</label>
+			<label index="ext_or">or</label>
+			<label index="ext_import_update_button">Import/Update</label>
+			<label index="ext_import_update_to">to:</label>
+			<label index="ext_import_global">Global:</label>
+			<label index="ext_import_local">Local:</label>
+			<label index="ext_import_system">System:</label>
+			<label index="ext_import_overwrite">(OVERWRITE)</label>
+			<label index="ext_import_folder_empty">(empty)</label>
+			<label index="ext_import_excluded_from_updates">This extension is excluded from updates! You can change this in the ext_emconf.php file in the extension folder.</label>
+			<label index="ext_import_select_command">Select command</label>
+			<label index="ext_import_remote_ext_details">Remote Extension Details</label>
+			<label index="ext_import_list_not_updated">Error: The list could not be fetched from %s.</label>
+			<label index="ext_import_list_updated">The mirror list has been updated and now contains %s entries.</label>
+			<label index="ext_import_list_empty">The mirror list was not updated as it contained no entries.</label>
+			<label index="ext_import_md5_not_updated">Error: The extension MD5 sum could not be fetched from %s.</label>
+			<label index="ext_import_extlist_updated_header">Extension list updated</label>
+			<label index="ext_import_extlist_updated">The extensions list has been updated and now contains %s extension entries.</label>
+			<label index="ext_import_list_unchanged_header">No updates available</label>
+			<label index="ext_import_list_unchanged">The extension list has not changed remotely, it has thus not been fetched.</label>
+			<label index="ext_import_ext_already_installed_loaded">Extension already installed and loaded.</label>
+			<label index="ext_import_p_localconf">localconf.php is not writable!</label>
+			<label index="ext_import_ext_loaded">Extension was already installed, it has been loaded.</label>
+			<label index="ext_import_ext_n_a">Extension not available in matching version.</label>
+			<label index="ext_import_ext_imported">Extension has been imported from repository and loaded.</label>
+			<label index="ext_import_ext_not_loaded">Extension is in repository, but could not be loaded.</label>
+			<label index="ext_import_ext_n_a_rep">Extension not available in repository.</label>
+			<label index="ext_import_file_not_uploaded">File was not uploaded?!</label>
+			<label index="ext_import_file_empty">File is empty!</label>
+			<label index="ext_import_ext_present_no_overwrite">A version  of the extension was already present in '%s' and the overwrite flag was not set.</label>
+			<label index="ext_import_ext_present_nothing_done">So nothing was done...</label>
+			<label index="ext_import_no_key">No extension key in file. Strange...</label>
+			<label index="ext_import_wrong_file_format">Wrong file format. No data recognized, %s.</label>
+			<label index="ext_import_no_file">No file uploaded! Probably the file was too large for PHPs internal limit for uploadable files.</label>
+			<label index="ext_import_file_not_created">Error: File '%s' could not be created!!!</label>
+			<label index="ext_import_file_corrupted">Error: File '%s' MD5 was different from the md5 of the original file - so the file is corrupted!</label>
+			<label index="ext_import_success">Extension imported</label>
+			<label index="ext_import_success_folder">Folder created: %s</label>
+			<label index="ext_import_no_conf_file">Error: Could not find '%s'.</label>
+			<label index="ext_import_ext_type">Installation Type:</label>
+			<label index="ext_import_cache_files_removed">Cache-files are removed and will be re-written upon next hit.</label>
+			<label index="ext_import_install_uninstall">Install/Uninstall Extension:</label>
+			<label index="ext_import_uninstall">Uninstall extension</label>
+			<label index="ext_import_install">Install extension</label>
+			<label index="ext_import_imported">The extension has been imported.</label>
+			<label index="ext_import_close_check">Close window and recheck dependencies.</label>
+			<label index="ext_import_ext_path_different">Error: The extension path '%s' was different than expected...</label>
+			<label index="ext_import_ext_only_here">Error: The extension can only be installed in the path %s (lockType=%s).</label>
+			<label index="ext_import_no_ext_key_files">Error: No extension key!!! Why? - nobody knows... (Or there are no files in the file array...)</label>
+			<label index="ext_import_data_transfer">Error: The data transfer did not succeed. %s</label>
+			<label index="ext_import_no_install_here">Error: Installation is not allowed in this path (%s).</label>
+			<label index="ext_import_results">Extension import results</label>
+			<label index="ext_details_ext">Extension:</label>
+			<label index="ext_details_new_tables_fields">Before the extension can be installed the database needs to be updated with new tables or fields.</label>
+			<label index="ext_details_new_tables_fields_select">Please select which operations to perform:</label>
+			<label index="ext_details_installing">Installing %s:</label>
+			<label index="ext_details_db_needs_update">Database needs to be updated</label>
+			<label index="ext_details_remove_ext">Remove extension</label>
+			<label index="ext_details_removing">Removing %s:</label>
+			<label index="ext_details_ext_installed_removed">The extension has been %s.</label>
+			<label index="ext_details_ext_installed_with_key">The extension "%s" has been installed.</label>
+			<label index="ext_details_ext_removed_with_key">The extension "%s" has been removed.</label>
+			<label index="ext_details_installed">installed</label>
+			<label index="ext_details_removed">removed</label>
+			<label index="ext_details_write_access_error">Write access error</label>
+			<label index="ext_details_write_error_localconf">typo3conf/localconf.php seems not to be writable, so the extension cannot be installed automatically!</label>
+			<label index="ext_details_error_downloading">Error while trying to download the extension file...</label>
+			<label index="ext_details_md5_previous">MD5: %s (Previous File)</label>
+			<label index="ext_details_no_changes">No changes to the file detected!</label>
+			<label index="ext_details_file">File: %s</label>
+			<label index="ext_details_md5_current">MD5: %s (Current File)</label>
+			<label index="ext_details_md5_submitted">MD5: %s (Submitted File)</label>
+			<label index="ext_details_saving_failed_changes_lost">Saving failed, the content was not correctly written to disk. Changes have been lost!</label>
+			<label index="ext_details_file_saved">File saved.</label>
+			<label index="ext_details_file_save_button">Save file</label>
+			<label index="ext_details_saving_disabled">[SAVING IS DISABLED - It can be enabled with the $TYPO3_CONF_VARS['EXT']['noEdit'] flag]</label>
+			<label index="ext_details_cancel_button">Cancel</label>
+			<label index="ext_details_edit_file">Edit file:</label>
+			<label index="ext_details_filesize_exceeded_kb">Filesize exceeded %s KBytes</label>
+			<label index="ext_details_file_too_large">Files larger than %s KBytes are not allowed to be edited.</label>
+			<label index="ext_details_fatal_edit_error">Fatal Edit error: File '%s' was not inside the correct path of the TYPO3 Extension!</label>
+			<label index="ext_details_loaded_and_running">The extension is installed (loaded and running)!</label>
+			<label index="ext_details_remove_button">Click here to remove the extension:</label>
+			<label index="ext_details_not_loaded">The extension is &lt;strong&gt;not&lt;/strong&gt; installed yet.</label>
+			<label index="ext_details_install_button">Click here to install the extension:</label>
+			<label index="ext_details_always_loaded">This extension is entered in the TYPO3_CONF_VARS['SYS']['requiredExt'] list and is therefore always loaded.</label>
+			<label index="ext_details_current_status">Current status:</label>
+			<label index="ext_details_update_needed">Update needed:</label>
+			<label index="ext_details_notice_static_data">(Notice: "Static data" may not &lt;em&gt;need&lt;/em&gt; to be updated. You will only have to import static data each time you upgrade the extension.)</label>
+			<label index="ext_details_configuration">Configuration:</label>
+			<label index="ext_details_notice_clear_cache">(&lt;em&gt;Notice: You may need to clear the cache after the configuration of the extension. This is required if the extension adds TypoScript depending on these settings.&lt;/em&gt;)</label>
+			<label index="ext_details_details">Details:</label>
+			<label index="ext_details_no_unique_ext">The extensions has an extension key prefixed "user_" which indicates that it is a user-defined extension with no official unique identification. Therefore it cannot be uploaded.</label>
+			<label index="ext_details_no_username">You have not configured a default username/password yet. %sGo to "Settings"%s if you want to do that.</label>
+			<label index="ext_details_upload_to_ter">Upload extension to repository</label>
+			<label index="ext_details_delete">Delete</label>
+			<label index="ext_details_backup">Backup</label>
+			<label index="ext_details_update_em_conf">Update EM_CONF</label>
+			<label index="ext_details_ext_files">Extension files</label>
+			<label index="ext_details_update">Update:</label>
+			<label index="ext_details_no_update_object">No update object</label>
+			<label index="reqInstExt_install_import">Install/Import:</label>
+			<label index="reqInstExt_ext_key">Extension Key:</label>
+			<label index="reqInstExt_import_install_selected">Import and Install selected</label>
+			<label index="reqInstExt_return">Return</label>
+			<label index="reqInstExt_imp_inst_ext">Import/Install Extensions:</label>
+			<label index="updatesForm_make_updates">Make updates</label>
+			<label index="extDumpTables_tables_fields">Table and field structure required</label>
+			<label index="extDumpTables_bytes_written_to">%sbytes written to %s</label>
+			<label index="extDumpTables_dumping_content">Dumping table content for static tables:</label>
+			<label index="extDumpTables_static_tables">Static tables</label>
+			<label index="extDumpTables_write_static">Write current static table contents to ext_tables_static+adt.sql now!</label>
+			<label index="extDumpTables_dumping_db_structure">Dumping current database structure for:</label>
+			<label index="extDumpTables_tables">Tables:</label>
+			<label index="extDumpTables_solo_fields">Solo-fields:</label>
+			<label index="extDumpTables_write_dump">Write this dump to ext_tables.sql now!</label>
+			<label index="extDumpTables_based_on">This dump is based on two factors:</label>
+			<label index="extDumpTables_based_on_one">1) All tablenames in ext_tables.sql which are &lt;em&gt;not&lt;/em&gt; found in the "modify_tables" list in ext_emconf.php are dumped with the current database structure.</label>
+			<label index="extDumpTables_based_on_two">2) For any tablenames which &lt;em&gt;are&lt;/em&gt; listed in "modify_tables" all fields and keys found for the table in ext_tables.sql will be re-dumped with the fresh equivalents from the database.</label>
+			<label index="extDumpTables_bottomline">Bottomline is: Whole tables are dumped from database with no regard to which fields and keys are defined in ext_tables.sql. But for tables which are only modified, any NEW fields added to the database must in some form or the other exist in the ext_tables.sql file as well.</label>
+			<label index="extFileList_file">File:</label>
+			<label index="extFileList_size">Size:</label>
+			<label index="extFileList_edit">Edit:</label>
+			<label index="extFileList_download">Download...</label>
+			<label index="extFileList_edit_file">Edit file</label>
+			<label index="extFileList_total">Total:</label>
+			<label index="extDelete_ext_active">This extension is currently installed (loaded and active) and so cannot be deleted!</label>
+			<label index="extDelete_wrong_scope">You cannot delete (and install/update) extensions in the %s scope.</label>
+			<label index="extDelete_remove_dir_failed">ERROR: Could not remove extension directory '%s'. The following errors occurred:</label>
+			<label index="extDelete_removed_header">Extension deleted</label>
+			<label index="extDelete_removed">Removed extension in path '%s'!</label>
+			<label index="extDelete_sure">Are you sure you want to delete this extension from the server?</label>
+			<label index="extDelete_from_server">DELETE EXTENSION FROM SERVER</label>
+			<label index="extDelete_from_location">(in the '%s' location '%s'!)</label>
+			<label index="extDelete_backup">(Maybe you should make a backup first, see above.)</label>
+			<label index="extDelete_neither_global_nor_local">This extension is neither a global nor a local one and so cannot be removed.</label>
+			<label index="extUpdateEMCONF_sure">Are you sure you want to update EM_CONF?</label>
+			<label index="extUpdateEMCONF_file">Update extension EM_CONF file</label>
+			<label index="extUpdateEMCONF_info_changes">If files are changed, added or removed to an extension this is normally detected and displayed so you know that this extension has been altered locally and may need to be uploaded or at least not overwritten.</label>
+			<label index="extUpdateEMCONF_info_reset">Updating this file will reset this check.</label>
+			<label index="extBackup_select">Make selection:</label>
+			<label index="extBackup_files">Extension files:</label>
+			<label index="extBackup_download">Download extension '%s' as a file.</label>
+			<label index="extBackup_md5">MD5:</label>
+			<label index="extBackup_data_tables">Data tables:</label>
+			<label index="extBackup_static_tables">Static tables:</label>
+			<label index="extBackup_unexpected_error">An unexpected error has occurred. There are problems with your extension key or with the extension data.</label>
+			<label index="extBackup_dump_table">Dump table '%s'</label>
+			<label index="extBackup_number_of_records">%s records</label>
+			<label index="extBackup_table_not_there">Did not exist.</label>
+			<label index="extBackup_dump_all_tables">Dump all existing tables.</label>
+			<label index="extBackup_download_all_data">Download all data from:</label>
+			<label index="extBackup_nothing_to_dump">Nothing to dump...</label>
+			<label index="extInfoArray_general_info">General information:</label>
+			<label index="extInfoArray_title">Title:</label>
+			<label index="extInfoArray_description">Description:</label>
+			<label index="extInfoArray_author">Author:</label>
+			<label index="extInfoArray_version">Version:</label>
+			<label index="extInfoArray_category">Category:</label>
+			<label index="extInfoArray_state">State:</label>
+			<label index="extInfoArray_shy">Shy:</label>
+			<label index="extInfoArray_internal">Internal:</label>
+			<label index="extInfoArray_depends_on">Depends on:</label>
+			<label index="extInfoArray_conflicts_with">Conflicts with:</label>
+			<label index="extInfoArray_suggests">Suggests:</label>
+			<label index="extInfoArray_priority">Priority:</label>
+			<label index="extInfoArray_clear_cache">Clear cache:</label>
+			<label index="extInfoArray_incl_modules">Includes modules:</label>
+			<label index="extInfoArray_lock_type">Lock installation Type:</label>
+			<label index="extInfoArray_load_in_frontend">Load in frontend:</label>
+			<label index="extInfoArray_modifies_tables">Modifies tables:</label>
+			<label index="extInfoArray_inst_status">Installation status:</label>
+			<label index="extInfoArray_inst_type">Type of installation:</label>
+			<label index="extInfoArray_inst_twice">Double installation:</label>
+			<label index="extInfoArray_root_files">Root files:</label>
+			<label index="extInfoArray_table_error">Table error!</label>
+			<label index="extInfoArray_missing_fields">Probably one or more required fields/tables are missing in the database!</label>
+			<label index="extInfoArray_static_table_error">Static table error!</label>
+			<label index="extInfoArray_static_tables_missing_empty">The static tables are missing or empty!</label>
+			<label index="extInfoArray_db_update_needed">The database will need to be updated when this extension is installed.</label>
+			<label index="extInfoArray_tables_ok">All required tables are already in the database!</label>
+			<label index="extInfoArray_db_requirements">Database requirements:</label>
+			<label index="extInfoArray_db_status">Database status:</label>
+			<label index="extInfoArray_flags">Flags:</label>
+			<label index="extInfoArray_config_template">Config template:</label>
+			<label index="extInfoArray_typoscript_files">TypoScript files:</label>
+			<label index="extInfoArray_language_files">Language files:</label>
+			<label index="extInfoArray_upload_folder">Upload folder:</label>
+			<label index="extInfoArray_create_directories">Create directories:</label>
+			<label index="extInfoArray_module_names">Module names:</label>
+			<label index="extInfoArray_class_names">Class names:</label>
+			<label index="extInfoArray_code_warnings">Code warnings:</label>
+			<label index="extInfoArray_dev_relevant">(developer-relevant)</label>
+			<label index="extInfoArray_annoyances">Naming annoyances:</label>
+			<label index="extInfoArray_exception">[exception]</label>
+			<label index="extInfoArray_difference_detected">A difference between the originally installed version and the current one was detected!</label>
+			<label index="extInfoArray_modified_files">Modified files:</label>
+			<label index="extInfoArray_files_changed">Files changed:</label>
+			<label index="extInfoArray_additional_fields">Additional fields:</label>
+			<label index="extInfoArray_double_installation_infotext">A %s extension with this key is also available on the server, but cannot be loaded, because the "%s" version takes precedence.</label>
+			<label index="repositoryUploadForm_username">Repository Username:</label>
+			<label index="repositoryUploadForm_password">Repository Password:</label>
+			<label index="repositoryUploadForm_changelog">Changelog for upload:</label>
+			<label index="repositoryUploadForm_command">Upload command:</label>
+			<label index="repositoryUploadForm_new_bugfix">New bugfix version (latest %s)</label>
+			<label index="repositoryUploadForm_new_sub_version">New sub version (latest %s)</label>
+			<label index="repositoryUploadForm_new_main_version">New main version (latest %s)</label>
+			<label index="repositoryUploadForm_upload">Upload extension</label>
+			<label index="listRowHeader_modifies_tables_short">Mod. Tables:</label>
+			<label index="listRowHeader_modules">Modules:</label>
+			<label index="listRowHeader_clear_cache_short">Cl. Cache?</label>
+			<label index="listRowHeader_tables_fields">Tables/Fields:</label>
+			<label index="listRowHeader_ts_files">TS files:</label>
+			<label index="listRowHeader_affects">Affects:</label>
+			<label index="listRowHeader_config">Config:</label>
+			<label index="listRowHeader_locallang">locallang:</label>
+			<label index="listRowHeader_classes">Classes:</label>
+			<label index="listRowHeader_changed_files">Changed files:</label>
+			<label index="listRowHeader_ext_key">Extension key:</label>
+			<label index="listRowHeader_download_short">DL:</label>
+			<label index="listRowHeader_documentation_short">Doc:</label>
+			<label index="listRowHeader_type">Type:</label>
+			<label index="listRowHeader_title_upload_date">Date of upload of the repository version.</label>
+			<label index="listRowHeader_upload_date">Upload date:</label>
+			<label index="listRowHeader_title_current_version">Current version of the extension on this server. If printed bold, there is a newer version in the repository! Then you should upgrade.</label>
+			<label index="listRowHeader_current_version">Cur. Ver:</label>
+			<label index="listRowHeader_title_current_type">Current type of installation of the extension on this server.</label>
+			<label index="listRowHeader_current_type">Cur. Type:</label>
+			<label index="listRowHeader_title_number_of_downloads">Number of downloads: all versions/this version</label>
+			<label index="listRow_files">Files:</label>
+			<label index="listRow_local_manual">Local Open Office Manual</label>
+			<label index="helperFunction_install_extension">Install extension...</label>
+			<label index="helperFunction_import_not_possible">Import to both local and global path is disabled in TYPO3_CONF_VARS!</label>
+			<label index="detailedExtAnalysis_keys">keys</label>
+			<label index="detailedExtAnalysis_tables_are">Some tables or fields are %s!</label>
+			<label index="detailedExtAnalysis_tables_are_missing">missing</label>
+			<label index="detailedExtAnalysis_tables_are_of_wrong_type">of wrong type</label>
+			<label index="detailedExtAnalysis_static_tables_missing">Static table(s) missing!</label>
+			<label index="detailedExtAnalysis_wrong_mod_path">Configured TYPO3_MOD_PATH "%s" is different from "%s", which it should be.</label>
+			<label index="detailedExtAnalysis_mconf_missing">No definition of MCONF[name] variable found inside!</label>
+			<label index="detailedExtAnalysis_be_module_conf_missing">Backend module conf file "%s" should exist, but does not!</label>
+			<label index="detailedExtAnalysis_module_folder_missing">Backend module folder "%s" should exist, but does not!</label>
+			<label index="detailedExtAnalysis_unconfigured_module">It seems like there is a backend module in "%s" which is not configured in ext_emconf.php.</label>
+			<label index="detailedExtAnalysis_module">Module</label>
+			<label index="detailedExtAnalysis_module_and_more">Module+</label>
+			<label index="detailedExtAnalysis_loadTCA">loadTCA</label>
+			<label index="detailedExtAnalysis_TCA">TCA</label>
+			<label index="detailedExtAnalysis_plugin">Plugin</label>
+			<label index="detailedExtAnalysis_plugin_st43">Plugin/ST43</label>
+			<label index="detailedExtAnalysis_page_ts">Page-TSconfig</label>
+			<label index="detailedExtAnalysis_user_ts">User-TSconfig</label>
+			<label index="detailedExtAnalysis_ts_setup">TS/Setup</label>
+			<label index="detailedExtAnalysis_ts_constants">TS/Constants</label>
+			<label index="detailedExtAnalysis_constants">Constants</label>
+			<label index="detailedExtAnalysis_setup">Setup</label>
+			<label index="detailedExtAnalysis_no_upload_folder">Error: Upload folder "%s" did not exist!</label>
+			<label index="detailedExtAnalysis_class_ok">Class filename "%s" contained the class "%s" just as it should.</label>
+			<label index="detailedExtAnalysis_class_not_ok">Class filename "%s" did NOT contain the class "%s"!</label>
+			<label index="detailedExtAnalysis_xclass_ok">'XCLASS OK in %s.</label>
+			<label index="detailedExtAnalysis_xclass_no_include">Couldn't find the include_once statement for XCLASS!</label>
+			<label index="detailedExtAnalysis_xclass_incorrect">The XCLASS filename-key "%s" was different from "%s" which it should have been!</label>
+			<label index="detailedExtAnalysis_no_xclass_filename">No XCLASS filename-key found in file "%s". Maybe a regex coding error here...</label>
+			<label index="detailedExtAnalysis_no_xclass_found">No XCLASS inclusion code found in file "%s".</label>
+			<label index="rmExtDir_could_not_be_deleted">Error: "%s" could not be deleted!</label>
+			<label index="rmExtDir_error_file">Error: "%s" was either not a file, or it was equal to the removed directory or simply outside the removed directory "%s"!</label>
+			<label index="rmExtDir_error_files_left">Error: "%s" could not be removed (are there files left?)</label>
+			<label index="rmExtDir_error_no_dir">Error: "%s" was no directory!</label>
+			<label index="rmExtDir_error_folders_left">Error: Extension directory "%s" could not be removed (are there files or folders left?)</label>
+			<label index="rmExtDir_error">Error:</label>
+			<label index="rmExtDir_error_unallowed_path">Error: Unallowed path to remove:</label>
+			<label index="clearMakeExtDir_no_ext_key">FATAL ERROR: Extension key was not set for some VERY strange reason. Nothing done...</label>
+			<label index="clearMakeExtDir_could_not_remove_dir">ERROR: Could not remove extension directory "%s". Reasons:</label>
+			<label index="clearMakeExtDir_could_not_create_dir">ERROR: Could not create extension directory "%s"!</label>
+			<label index="clearMakeExtDir_no_dir">ERROR: The extension install path "%s" was no directory!</label>
+			<label index="writeModPath_ok">TYPO3_MOD_PATH and $BACK_PATH were updated in "%s"!</label>
+			<label index="writeModPath_notRequired">Notice: Module "%s" uses module-API to register module, TYPO3_MOD_PATH and $BACK_PATH not required.</label>
+			<label index="writeModPath_error">Error: Either TYPO3_MOD_PATH or $BACK_PATH was not found in the "%s" file. You must manually configure that!</label>
+			<label index="updateLocalEM_CONF_ok">The file "%s" was updated with a cleaned up EM_CONF array.</label>
+			<label index="updateLocalEM_CONF_not_writable">Error: "%s" was not writable!</label>
+			<label index="updateLocalEM_CONF_not_found">Error: No file "%s" found. DON'T PANIC!</label>
+			<label index="updateLocalEM_CONF_no_content">No content to write to "%s"!</label>
+			<label index="makeUploadArray_error_size">Error: The total size of the uncompressed upload (%s) exceeds %s!</label>
+			<label index="makeUploadArray_error_path">Error: Extension path for extension "%s" not found!</label>
+			<label index="checkDependencies_ignored">Dependency on %s ignored as requested.</label>
+			<label index="checkDependencies_php_too_low">The running PHP version (%s) is lower than required (%s).</label>
+			<label index="checkDependencies_ignore_requirement">Ignore this version requirement</label>
+			<label index="checkDependencies_php_too_high">The running PHP version (%s) is higher than allowed (%s).</label>
+			<label index="checkDependencies_typo3_too_low">The running TYPO3 version (%s) is lower than required (%s).</label>
+			<label index="checkDependencies_typo3_too_high">The running TYPO3 version (%s) is higher than allowed (%s).</label>
+			<label index="checkDependencies_ext_not_available">The extension "%s" was not available in the system. Please import it from the TYPO3 Extension Repository.</label>
+			<label index="checkDependencies_import_ext">Import this extension to the 'local' directory typo3conf/ext/ from online repository.</label>
+			<label index="checkDependencies_import_now">Import now (opens a new window)</label>
+			<label index="checkDependencies_ignore_ext_requirement">Ignore this extension requirement</label>
+			<label index="checkDependencies_ext_not_installed">Extension "%s" (%s) was not installed. Please install it first.</label>
+			<label index="checkDependencies_install_now">Install now (opens a new window)</label>
+			<label index="checkDependencies_ext_too_low">The running version of extension "%s" (%s) is lower than required (%s).</label>
+			<label index="checkDependencies_ext_too_high">The running version of extension "%s" (%s) is higher than allowed (%s).</label>
+			<label index="checkDependencies_conflict_ignored">Conflict with %s ignored as requested.</label>
+			<label index="checkDependencies_conflict_remove">The extensions "%s" and "%s" (%s) will conflict with each other. Please remove "%s", if you want to install "%s".</label>
+			<label index="checkDependencies_remove_now">Remove now (opens a new window)</label>
+			<label index="checkDependencies_ignore_conflict">Ignore this conflict error</label>
+			<label index="checkDependencies_conflict_error">Conflict Error</label>
+			<label index="checkDependencies_suggestion_ignored">Suggestion of %s ignored as requested.</label>
+			<label index="checkDependencies_suggest_import">Extension "%s" was not available in the system. You may want to import it from the TYPO3 Extension Repository.</label>
+			<label index="checkDependencies_ignore_suggestion">Ignore this suggestion</label>
+			<label index="checkDependencies_suggest_installation">Extension "%s" (%s) was not installed. You may want to install it.</label>
+			<label index="checkDependencies_exts_suggested_by_ext">Extensions suggested by extension "%s"</label>
+			<label index="checkDependencies_try_again">Try again</label>
+			<label index="removeExtFromList_dependency">The extension(s) '%s' depend(s) on the extension you are trying to remove. The operation was not completed.</label>
+			<label index="removeExtFromList_dependency_error">Dependency Error</label>
+			<label index="checkUploadFolder_clear_cache">Clear cache</label>
+			<label index="checkUploadFolder_clear_cache_requested">This extension requests the cache to be cleared when it is installed/removed.</label>
+			<label index="checkUploadFolder_clear_all_cache">Clear all cache:</label>
+			<label index="checkUploadFolder_create_upload_folder">Create upload folder</label>
+			<label index="checkUploadFolder_upload_folder_needed">The extension requires the upload folder '%s' to exist.</label>
+			<label index="checkUploadFolder_create_dir">Create directory '%s':</label>
+			<label index="checkUploadFolder_error">ERROR: The path '%s' could not be created.</label>
+			<label index="checkUploadFolder_create_folder">Create folder</label>
+			<label index="checkUploadFolder_folder_needed">The extension requires the folder '%s' to exist.</label>
+			<label index="checkDBupdates_add_fields">Add fields</label>
+			<label index="checkDBupdates_changing_fields">Changing fields</label>
+			<label index="checkDBupdates_add_tables">Add tables</label>
+			<label index="checkDBupdates_rows">Rows:</label>
+			<label index="checkDBupdates_table_exists">Table exists!</label>
+			<label index="checkDBupdates_import_static_data">Import static data</label>
+			<label index="tsStyleConfigForm_note">Note</label>
+			<label index="tsStyleConfigForm_additional_config">This extension provides additional configuration options which become available once it is installed.</label>
+			<label index="dumpStaticTables_table_not_found">Fatal error: Table for dump not found in database...</label>
+			<label index="terCommunication_ext_version">The extension is now available in version %s.</label>
+			<label index="display_nle">Include not loaded extensions into listing</label>
+			<label index="display_files">Display the list of changed files</label>
+			<label index="header_upd_ext">There are new versions of the following extensions in the TER</label>
+			<label index="header_vers_ret">Version information</label>
+			<label index="tab_mod_name">Extension</label>
+			<label index="tab_mod_key">Ext-Key</label>
+			<label index="tab_mod_loc_ver">Local</label>
+			<label index="tab_mod_rem_ver">Remote</label>
+			<label index="tab_mod_comment">Upload-Comment</label>
+			<label index="tab_mod_location">Location</label>
+			<label index="msg_warn_diff">A difference between the originally installed version and the current was detected!</label>
+			<label index="msg_modified">Modified Files:</label>
+			<label index="write_protected">(write-protected)</label>
+			<label index="note_last_update">Last update of the list of extensions:</label>
+			<label index="note_last_update_new">Last update of the list of extensions: %s.</label>
+			<label index="note_last_update2">To get and update the list, go to the section "Import extensions" and use the button "Retrieve/Update".</label>
+			<label index="note_last_update2_new">To get and update the list, %sgo to the section "Import extensions" and use the button "Retrieve/Update"%s.</label>
+			<label index="double_inclusion">%1$s takes precedence over %2$s</label>
+			<label index="globalext">Globally installed extension</label>
+			<label index="localext">Locally installed extension</label>
+			<label index="sysext">System extension</label>
 		</languageKey>
 	</data>
 </T3locallang>
Index: typo3/sysext/em/classes/extensions/class.tx_em_extensions_details.php
===================================================================
--- typo3/sysext/em/classes/extensions/class.tx_em_extensions_details.php	(revision )
+++ typo3/sysext/em/classes/extensions/class.tx_em_extensions_details.php	(revision )
@@ -0,0 +1,786 @@
+<?php
+/* **************************************************************
+*  Copyright notice
+*
+*  (c) webservices.nl
+*  (c) 2006-2010 Karsten Dambekalns <karsten@typo3.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+/* $Id: class.tx_em_extensions_details.php 2058 2010-03-17 09:39:15Z steffenk $ */
+
+/**
+ * Enter description here...
+ *
+ */
+
+class tx_em_Extensions_Details {
+
+	protected $maxUploadSize = 31457280;
+	protected $descrTable = '_MOD_tools_em';
+	protected $parentObject;
+
+	/**
+	 * Class for install extensions
+	 *
+	 * @var em_install
+	 */
+	public $install;
+
+	/**
+	 * Consttructor
+	 *
+	 * @param unknown_type $parentObject
+	 */
+	public function __construct($parentObject = NULL) {
+		$this->parentObject = $parentObject;
+		$this->install = t3lib_div::makeInstance('tx_em_Install', $this);
+		$GLOBALS['LANG']->includeLLFile(t3lib_extMgm::extPath('em') . 'language/locallang.xml');
+	}
+
+
+	/**
+	 * Reads $confFilePath (a module $conf-file) and returns information on the existence of TYPO3_MOD_PATH definition and MCONF_name
+	 *
+	 * @param	string		Absolute path to a "conf.php" file of a module which we are analysing.
+	 * @return	array		Information found.
+	 * @see writeTYPO3_MOD_PATH()
+	 */
+	function modConfFileAnalysis($confFilePath) {
+		$lines = explode(LF, t3lib_div::getUrl($confFilePath));
+		$confFileInfo = array();
+		$confFileInfo['lines'] = $lines;
+		$reg = array();
+
+		foreach ($lines as $k => $l) {
+			$line = trim($l);
+
+			unset($reg);
+			if (preg_match('/^define[[:space:]]*\([[:space:]]*["\']TYPO3_MOD_PATH["\'][[:space:]]*,[[:space:]]*["\']([[:alnum:]_\/\.]+)["\'][[:space:]]*\)[[:space:]]*;/', $line, $reg)) {
+				$confFileInfo['TYPO3_MOD_PATH'] = array($k, $reg);
+			}
+
+			unset($reg);
+			if (preg_match('/^\$MCONF\[["\']?name["\']?\][[:space:]]*=[[:space:]]*["\']([[:alnum:]_]+)["\'];/', $line, $reg)) {
+				$confFileInfo['MCONF_name'] = array($k, $reg);
+			}
+		}
+		return $confFileInfo;
+	}
+
+	/**
+	 * Check if upload folder / "createDir" directories should be created.
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @return	string		HTML content.
+	 */
+	function checkUploadFolder($extKey, $extInfo) {
+
+		// Checking for upload folder:
+		$uploadFolder = PATH_site . tx_em_Tools::uploadFolder($extKey);
+		if ($extInfo['EM_CONF']['uploadfolder'] && !@is_dir($uploadFolder)) {
+			if (t3lib_div::_POST('_uploadfolder')) { // CREATE dir:
+				t3lib_div::mkdir($uploadFolder);
+				$indexContent = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<HTML>
+<HEAD>
+	<TITLE></TITLE>
+<META http-equiv=Refresh Content="0; Url=../../">
+</HEAD>
+</HTML>';
+				t3lib_div::writeFile($uploadFolder . 'index.html', $indexContent);
+			} else { // Show checkbox / HTML for creation:
+				$content .= '
+					<br /><h3>' . $GLOBALS['LANG']->getLL('checkUploadFolder_create_upload_folder') . '</h3>
+					<p>' . sprintf($GLOBALS['LANG']->getLL('checkUploadFolder_upload_folder_needed'),
+					tx_em_Tools::uploadFolder($extKey)
+				) . '<br />
+						<label for="check_uploadfolder">' . sprintf($GLOBALS['LANG']->getLL('checkUploadFolder_create_dir'),
+					tx_em_Tools::uploadFolder($extKey)
+				) . '</label>
+						<input type="checkbox" name="_uploadfolder" id="check_uploadfolder" checked="checked" value="1" /><br />
+					</p>
+				';
+			}
+		}
+
+		// Additional directories that should be created:
+		if ($extInfo['EM_CONF']['createDirs']) {
+			$createDirs = array_unique(t3lib_div::trimExplode(',', $extInfo['EM_CONF']['createDirs'], 1));
+
+			foreach ($createDirs as $crDir) {
+				if (!@is_dir(PATH_site . $crDir)) {
+					if (t3lib_div::_POST('_createDir_' . md5($crDir))) { // CREATE dir:
+
+						// Initialize:
+						$crDirStart = '';
+						$dirs_in_path = explode('/', preg_replace('/\/$/', '', $crDir));
+
+						// Traverse each part of the dir path and create it one-by-one:
+						foreach ($dirs_in_path as $dirP) {
+							if (strcmp($dirP, '')) {
+								$crDirStart .= $dirP . '/';
+								if (!@is_dir(PATH_site . $crDirStart)) {
+									t3lib_div::mkdir(PATH_site . $crDirStart);
+									$finalDir = PATH_site . $crDirStart;
+								}
+							} else {
+								throw new RuntimeException(
+									'TYPO3 Fatal Error: ' . sprintf($GLOBALS['LANG']->getLL('checkUploadFolder_error'), PATH_site . $crDir),
+									1270853982
+								);
+							}
+						}
+						if ($finalDir) {
+							$indexContent = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<HTML>
+<HEAD>
+	<TITLE></TITLE>
+<META http-equiv=Refresh Content="0; Url=/">
+</HEAD>
+</HTML>';
+							t3lib_div::writeFile($finalDir . 'index.html', $indexContent);
+						}
+					} else { // Show checkbox / HTML for creation:
+						$md5CrDir = md5($crDir);
+						$content .= '
+							<br />
+							<h3>' . $GLOBALS['LANG']->getLL('checkUploadFolder_create_folder') . '</h3>
+							<p>' . sprintf($GLOBALS['LANG']->getLL('checkUploadFolder_folder_needed'),
+							$crDir
+						) . '<br />
+								<label for="check_createDir_' . $md5CrDir . '">' . sprintf($GLOBALS['LANG']->getLL('checkUploadFolder_create_dir'),
+							$crDir
+						) . '</label>
+								<input type="checkbox" name="_createDir_' . $md5CrDir . '" id="check_createDir_' . $md5CrDir . '" checked="checked" value="1" /><br />
+							</p>
+						';
+					}
+				}
+			}
+		}
+
+		return $content;
+	}
+
+
+	/**
+	 * Processes return-data from online repository.
+	 * Currently only the returned emconf array is written to extension.
+	 *
+	 * @param	array		Command array returned from TER
+	 * @return	string		Message
+	 */
+	function uploadExtensionToTER($em) {
+		$msg = '';
+		$response = $this->terConnection->uploadToTER($em);
+
+		if (!is_array($response)) {
+			return $response;
+		}
+
+		if ($response['resultCode'] == TX_TER_RESULT_EXTENSIONSUCCESSFULLYUPLOADED) {
+			$em['extInfo']['EM_CONF']['version'] = $response['version'];
+			$response['resultMessages'][] = sprintf($GLOBALS['LANG']->getLL('terCommunication_ext_version'),
+				$response['version']
+			);
+			$response['resultMessages'][] = $this->updateLocalEM_CONF($em['extKey'], $em['extInfo']);
+		}
+
+		$msg = '<ul><li>' . implode('</li><li>', $response['resultMessages']) . '</li></ul>';
+		return $msg;
+	}
+
+	/**
+	 * Forces update of local EM_CONF. This will renew the information of changed files.
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @return	string		Status message
+	 */
+	function updateLocalEM_CONF($extKey, $extInfo) {
+		$extInfo['EM_CONF']['_md5_values_when_last_written'] = serialize($this->serverExtensionMD5array($extKey, $extInfo));
+		$emConfFileContent = $this->construct_ext_emconf_file($extKey, $extInfo['EM_CONF']);
+
+		$absPath = tx_em_Tools::getExtPath($extKey, $extInfo['type']);
+		$emConfFileName = $absPath . 'ext_emconf.php';
+		if ($emConfFileContent) {
+
+			if (@is_file($emConfFileName)) {
+				if (t3lib_div::writeFile($emConfFileName, $emConfFileContent) === true) {
+					return sprintf($GLOBALS['LANG']->getLL('updateLocalEM_CONF_ok'),
+						substr($emConfFileName, strlen($absPath)));
+				} else {
+					return '<strong>' . sprintf($GLOBALS['LANG']->getLL('updateLocalEM_CONF_not_writable'),
+						$emConfFileName) . '</strong>';
+				}
+			} else {
+				return ('<strong>' . sprintf($GLOBALS['LANG']->getLL('updateLocalEM_CONF_not_found'),
+					$emConfFileName) . '</strong>');
+			}
+		} else {
+			return sprintf($GLOBALS['LANG']->getLL('updateLocalEM_CONF_no_content'),
+				substr($emConfFileName, strlen($absPath)));
+		}
+	}
+
+	/**
+	 * Creates a MD5-hash array over the current files in the extension
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @return	array		MD5-keys
+	 */
+	function serverExtensionMD5array($extKey, $conf) {
+
+		// Creates upload-array - including filelist.
+		$mUA = $this->makeUploadarray($extKey, $conf);
+
+		$md5Array = array();
+		if (is_array($mUA['FILES'])) {
+
+			// Traverse files.
+			foreach ($mUA['FILES'] as $fN => $d) {
+				if ($fN != 'ext_emconf.php') {
+					$md5Array[$fN] = substr($d['content_md5'], 0, 4);
+				}
+			}
+		} else {
+			debug(array($mUA, $conf), 'serverExtensionMD5Array:' . $extKey);
+		}
+		return $md5Array;
+	}
+
+	/*******************************************
+	 *
+	 * Compiling upload information, emconf-file etc.
+	 *
+	 *******************************************/
+
+	/**
+	 * Compiles the ext_emconf.php file
+	 *
+	 * @param	string		Extension key
+	 * @param	array		EM_CONF array
+	 * @return	string		PHP file content, ready to write to ext_emconf.php file
+	 */
+	function construct_ext_emconf_file($extKey, $EM_CONF) {
+
+		// clean version number:
+		$vDat = tx_em_Tools::renderVersion($EM_CONF['version']);
+		$EM_CONF['version'] = $vDat['version'];
+
+		$code = '<?php
+
+########################################################################
+# Extension Manager/Repository config file for ext "' . $extKey . '".
+#
+# Auto generated ' . date('d-m-Y H:i') . '
+#
+# Manual updates:
+# Only the data in the array - everything else is removed by next
+# writing. "version" and "dependencies" must not be touched!
+########################################################################
+
+$EM_CONF[$_EXTKEY] = ' . tx_em_Tools::arrayToCode($EM_CONF, 0) . ';
+
+?>';
+		return str_replace(CR, '', $code);
+	}
+
+	/**
+	 * Make upload array out of extension
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @return	mixed		Returns array with extension upload array on success, otherwise an error string.
+	 */
+	function makeUploadarray($extKey, $conf) {
+		$extPath = tx_em_Tools::getExtPath($extKey, $conf['type']);
+
+		if ($extPath) {
+
+			// Get files for extension:
+			$fileArr = array();
+			$fileArr = t3lib_div::getAllFilesAndFoldersInPath($fileArr, $extPath, '', 0, 99, $GLOBALS['TYPO3_CONF_VARS']['EXT']['excludeForPackaging']);
+
+			// Calculate the total size of those files:
+			$totalSize = 0;
+			foreach ($fileArr as $file) {
+				$totalSize += filesize($file);
+			}
+
+			// If the total size is less than the upper limit, proceed:
+			if ($totalSize < $this->maxUploadSize) {
+
+				// Initialize output array:
+				$uploadArray = array();
+				$uploadArray['extKey'] = $extKey;
+				$uploadArray['EM_CONF'] = $conf['EM_CONF'];
+				$uploadArray['misc']['codelines'] = 0;
+				$uploadArray['misc']['codebytes'] = 0;
+
+				$uploadArray['techInfo'] = $this->install->makeDetailedExtensionAnalysis($extKey, $conf, 1);
+
+				// Read all files:
+				foreach ($fileArr as $file) {
+					$relFileName = substr($file, strlen($extPath));
+					$fI = pathinfo($relFileName);
+					if ($relFileName != 'ext_emconf.php') { // This file should be dynamically written...
+						$uploadArray['FILES'][$relFileName] = array(
+							'name' => $relFileName,
+							'size' => filesize($file),
+							'mtime' => filemtime($file),
+							'is_executable' => (TYPO3_OS == 'WIN' ? 0 : is_executable($file)),
+							'content' => t3lib_div::getUrl($file)
+						);
+						if (t3lib_div::inList('php,inc', strtolower($fI['extension']))) {
+							$uploadArray['FILES'][$relFileName]['codelines'] = count(explode(LF, $uploadArray['FILES'][$relFileName]['content']));
+							$uploadArray['misc']['codelines'] += $uploadArray['FILES'][$relFileName]['codelines'];
+							$uploadArray['misc']['codebytes'] += $uploadArray['FILES'][$relFileName]['size'];
+
+							// locallang*.php files:
+							if (substr($fI['basename'], 0, 9) == 'locallang' && strstr($uploadArray['FILES'][$relFileName]['content'], '$LOCAL_LANG')) {
+								$uploadArray['FILES'][$relFileName]['LOCAL_LANG'] = tx_em_Tools::getSerializedLocalLang($file, $uploadArray['FILES'][$relFileName]['content']);
+							}
+						}
+						$uploadArray['FILES'][$relFileName]['content_md5'] = md5($uploadArray['FILES'][$relFileName]['content']);
+					}
+				}
+
+				// Return upload-array:
+				return $uploadArray;
+			} else {
+				return sprintf($GLOBALS['LANG']->getLL('makeUploadArray_error_size'),
+					$totalSize, t3lib_div::formatSize($this->maxUploadSize));
+			}
+		} else {
+			return sprintf($GLOBALS['LANG']->getLL('makeUploadArray_error_path'),
+				$extKey);
+		}
+	}
+
+
+	/**
+	 * Prints a table with extension information in it.
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @param	boolean		If set, the information array shows information for a remote extension in TER, not a local one.
+	 * @return	string		HTML content.
+	 */
+	function extInformationarray($extKey, $extInfo, $remote = 0) {
+		$emConf = $extInfo['EM_CONF'];
+
+		$lines = array();
+		$lines[] = '
+			<tr class="t3-row-header"><td colspan="2"><strong>' . $GLOBALS['LANG']->getLL('extInfoArray_general_info') . '</strong></td></tr>';
+
+		// row for the extension title
+		$key = 'title';
+		$dataCol = $emConf['_icon'] . $emConf[$key];
+		$lines[] = array(
+			$this->headerCol($key),
+			$dataCol
+		);
+
+		// row for the extension description
+		$key = 'description';
+		$dataCol = nl2br(htmlspecialchars($emConf[$key]));
+		$lines[] = array(
+			$this->headerCol($key),
+			$dataCol
+		);
+
+		// row for the extension author
+		$key = 'author';
+		$dataCol = tx_em_Tools::wrapEmail($emConf['author'] . ($emConf['author_email'] ? ' <' . $emConf['author_email'] . '>' : ''), $emConf['author_email']);
+		if ($emConf['author_company']) {
+			$dataCol .= ', ' . $emConf['author_company'];
+		}
+		$lines[] = array(
+			$this->headerCol($key),
+			$dataCol
+		);
+
+		// row for the version
+		$key = 'version';
+		$dataCol = $emConf[$key];
+		$lines[] = array(
+			$this->headerCol($key),
+			$dataCol
+		);
+
+		// row for the category
+		$key = 'category';
+		$dataCol = $this->parentObject->categories[$emConf[$key]];
+		$lines[] = array(
+			$this->headerCol($key),
+			$dataCol
+		);
+
+		// row for the state
+		$key = 'state';
+		$dataCol = $this->parentObject->states[$emConf[$key]];
+		$lines[] = array(
+			$this->headerCol($key),
+			$dataCol
+		);
+
+		// row for the shy state
+		$key = 'shy';
+		if ($emConf[$key]) {
+			$dataCol = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes');
+		} else {
+			$dataCol = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:no');
+		}
+		$lines[] = array(
+			$this->headerCol($key),
+			$dataCol
+		);
+
+		// row for the internal state
+		$key = 'internal';
+		if ($emConf[$key]) {
+			$dataCol = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes');
+		} else {
+			$dataCol = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:no');
+		}
+		$lines[] = array(
+			$this->headerCol($key),
+			$dataCol
+		);
+
+		// row for the dependencies
+		$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_depends_on');
+		$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_dependencies', $headerCol);
+		$dataCol = tx_em_Tools::depToString($emConf['constraints']);
+		$lines[] = array(
+			$headerCol,
+			$dataCol
+		);
+
+		// row for the conflicts
+		$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_conflicts_with');
+		$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_conflicts', $headerCol);
+		$dataCol = tx_em_Tools::depToString($emConf['constraints'], 'conflicts');
+		$lines[] = array(
+			$headerCol,
+			$dataCol
+		);
+
+		// row for the suggestions
+		$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_suggests');
+		$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_conflicts', $headerCol);
+		$dataCol = tx_em_Tools::depToString($emConf['constraints'], 'suggests');
+		$lines[] = array(
+			$this->headerCol('suggests'),
+			$dataCol
+		);
+
+		if (!$remote) {
+
+			$key = 'priority';
+			$lines[] = array(
+				$this->headerCol($key),
+				$emConf[$key]
+			);
+
+
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_clear_cache');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_clearCacheOnLoad', $headerCol);
+			if ($emConf['clearCacheOnLoad']) {
+				$dataCol = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes');
+			} else {
+				$dataCol = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:no');
+			}
+			$lines[] = array(
+				$headerCol,
+				$dataCol
+			);
+
+			$key = 'module';
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_incl_modules');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_module', $headerCol);
+			$lines[] = array(
+				$headerCol,
+				$emConf[$key]
+			);
+
+			$key = 'lockType';
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_lock_type');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_lockType', $headerCol);
+			$lines[] = array(
+				$headerCol,
+				($emConf[$key] ? $emConf[$key] : '')
+			);
+
+			$key = 'doNotLoadInFE';
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_load_in_frontend');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_doNotLoadInFE', $headerCol);
+			if (!$emConf['doNotLoadInFE']) {
+				$dataCol = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes');
+			} else {
+				$dataCol = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:no');
+			}
+			$lines[] = array(
+				$headerCol,
+				$dataCol
+			);
+
+			$key = 'modify_tables';
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_modifies_tables');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_modify_tables', $headerCol);
+			$lines[] = array(
+				$headerCol,
+				$emConf[$key]
+			);
+
+
+			// Installation status:
+			$techInfo = $this->install->makeDetailedExtensionAnalysis($extKey, $extInfo, 1);
+			$lines[] = array('<tr><td colspan="2">&nbsp;</td></tr>');
+			$lines[] = array('<tr class="t3-row-header"><td colspan="2"><strong>' . $GLOBALS['LANG']->getLL('extInfoArray_inst_status') . '</strong></td></tr>');
+
+
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_inst_type');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_type', $headerCol);
+			$dataCol = $this->parentObject->typeLabels[$extInfo['type']] . ' - <em>' . $this->parentObject->typeDescr[$extInfo['type']] . '</em>';
+			$lines[] = array($headerCol, $dataCol);
+
+
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_inst_twice');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_doubleInstall', $headerCol);
+			$dataCol = $this->extInformationArray_dbInst($extInfo['doubleInstall'], $extInfo['type']);
+			$lines[] = array($headerCol, $dataCol);
+
+
+			if (is_array($extInfo['files'])) {
+				sort($extInfo['files']);
+				$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_root_files');
+				$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_rootfiles', $headerCol);
+				$dataCol = implode('<br />', $extInfo['files']);
+				$lines[] = array($headerCol, $dataCol);
+			}
+
+			if ($techInfo['tables'] || $techInfo['static'] || $techInfo['fields']) {
+				if (!$remote && t3lib_extMgm::isLoaded($extKey)) {
+					$tableStatus = tx_em_Tools::rfw(($techInfo['tables_error'] ?
+							'<strong>' . $GLOBALS['LANG']->getLL('extInfoArray_table_error') . '</strong><br />' .
+									$GLOBALS['LANG']->getLL('extInfoArray_missing_fields') : '') .
+							($techInfo['static_error'] ?
+									'<strong>' . $GLOBALS['LANG']->getLL('extInfoArray_static_table_error') . '</strong><br />' .
+											$GLOBALS['LANG']->getLL('extInfoArray_static_tables_missing_empty') : ''));
+				} else {
+					$tableStatus = $techInfo['tables_error'] || $techInfo['static_error'] ?
+							$GLOBALS['LANG']->getLL('extInfoArray_db_update_needed') : $GLOBALS['LANG']->getLL('extInfoArray_tables_ok');
+				}
+			}
+
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_db_requirements');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_dbReq', $headerCol);
+			$dataCol = $this->extInformationArray_dbReq($techInfo, 1);
+			$lines[] = array($headerCol, $dataCol);
+
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_db_status');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_dbStatus', $headerCol);
+			$lines[] = array($headerCol, $tableStatus);
+
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_flags');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_flags', $headerCol);
+			$dataCol = (is_array($techInfo['flags']) ? implode('<br />', $techInfo['flags']) : '');
+			$lines[] = array($headerCol, $dataCol);
+
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_config_template');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_conf', $headerCol);
+			$dataCol = ($techInfo['conf'] ? $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes') : '');
+			$lines[] = array($headerCol, $dataCol);
+
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_typoscript_files');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_TSfiles', $headerCol);
+			$dataCol = (is_array($techInfo['TSfiles']) ? implode('<br />', $techInfo['TSfiles']) : '');
+			$lines[] = array($headerCol, $dataCol);
+
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_language_files');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_locallang', $headerCol);
+			$dataCol = (is_array($techInfo['locallang']) ? implode('<br />', $techInfo['locallang']) : '');
+			$lines[] = array($headerCol, $dataCol);
+
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_upload_folder');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_uploadfolder', $headerCol);
+			$dataCol = ($techInfo['uploadfolder'] ? $techInfo['uploadfolder'] : '');
+			$lines[] = array($headerCol, $dataCol);
+
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_create_directories');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_createDirs', $headerCol);
+			$dataCol = (is_array($techInfo['createDirs']) ? implode('<br />', $techInfo['createDirs']) : '');
+			$lines[] = array($headerCol, $dataCol);
+
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_module_names');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_moduleNames', $headerCol);
+			$dataCol = (is_array($techInfo['moduleNames']) ? implode('<br />', $techInfo['moduleNames']) : '');
+			$lines[] = array($headerCol, $dataCol);
+
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_class_names');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_classNames', $headerCol);
+			$dataCol = (is_array($techInfo['classes']) ? implode('<br />', $techInfo['classes']) : '');
+			$lines[] = array($headerCol, $dataCol);
+
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_code_warnings') . '<br />' . $GLOBALS['LANG']->getLL('extInfoArray_dev_relevant');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_errors', $headerCol);
+			$dataCol = (is_array($techInfo['errors']) ? tx_em_Tools::rfw(implode('<br />', $techInfo['errors'])) : '');
+			$lines[] = array($headerCol, $dataCol);
+
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_annoyances') . '<br />' . $GLOBALS['LANG']->getLL('extInfoArray_dev_relevant');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_NSerrors', $headerCol);
+			if (is_array($techInfo['NSerrors'])) {
+				if (!t3lib_div::inList($this->parentObject->nameSpaceExceptions, $extKey)) {
+					$dataCol = t3lib_utility_Debug::viewarray($techInfo['NSerrors']);
+				} else {
+					$dataCol = $GLOBALS['TBE_TEMPLATE']->dfw($GLOBALS['LANG']->getLL('extInfoArray_exception'));
+				}
+
+			}
+			$lines[] = array($headerCol, $dataCol);
+
+			$currentMd5Array = $this->serverExtensionMD5array($extKey, $extInfo);
+			$affectedFiles = '';
+
+			$msgLines = array();
+			if (strcmp($extInfo['EM_CONF']['_md5_values_when_last_written'], serialize($currentMd5Array))) {
+				$msgLines[] = tx_em_Tools::rfw('<br /><strong>' . $GLOBALS['LANG']->getLL('extInfoArray_difference_detected') . '</strong>');
+				$affectedFiles = tx_em_Tools::findMD5ArrayDiff($currentMd5Array, unserialize($extInfo['EM_CONF']['_md5_values_when_last_written']));
+				if (count($affectedFiles)) {
+					$msgLines[] = '<br /><strong>' . $GLOBALS['LANG']->getLL('extInfoArray_modified_files') . '</strong><br />' .
+							tx_em_Tools::rfw(implode('<br />', $affectedFiles));
+				}
+			}
+
+			$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_files_changed');
+			$headerCol = t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_filesChanged', $headerCol);
+			$dataCol = implode('<br />', $msgLines);
+			$lines[] = array($headerCol, $dataCol);
+		}
+
+		$output = '';
+		foreach ($lines as $cols) {
+			// if it's just one line, we assume it's a headline,
+			// thus no need to wrap it in HTML table tags
+			if (count($cols) == 1) {
+				$output .= $cols[0];
+			} else {
+				$output .= '
+					<tr class="bgColor4">
+						<td>' . $cols[0] . '</td>
+						<td>' . $cols[1] . '</td>
+					</tr>';
+			}
+		}
+
+
+		return '<table border="0" cellpadding="1" cellspacing="2">
+					' . $output . '
+				</table>';
+	}
+
+	/**
+	 * Returns HTML with information about database requirements
+	 *
+	 * @param	array		Technical information array
+	 * @param	boolean		Table header displayed
+	 * @return	string		HTML content.
+	 */
+	function extInformationArray_dbReq($techInfo, $tableHeader = 0) {
+		return nl2br(trim((is_array($techInfo['tables']) ?
+				($tableHeader ?
+						"\n\n<strong>" . $GLOBALS['LANG']->getLL('extDumpTables_tables') . "</strong>\n" : '') .
+						implode(LF, $techInfo['tables']) : '') .
+				(is_array($techInfo['static']) ?
+						"\n\n<strong>" . $GLOBALS['LANG']->getLL('extBackup_static_tables') . "</strong>\n" .
+								implode(LF, $techInfo['static']) : '') .
+				(is_array($techInfo['fields']) ?
+						"\n\n<strong>" . $GLOBALS['LANG']->getLL('extInfoArray_additional_fields') . "</strong>\n" .
+								implode('<hr />', $techInfo['fields']) : '')));
+	}
+
+	/**
+	 * Double install warning.
+	 *
+	 * @param	string		Double-install string, eg. "LG" etc.
+	 * @param	string		Current scope, eg. "L" or "G" or "S"
+	 * @return	string		Message
+	 */
+	function extInformationArray_dbInst($dbInst, $current) {
+		if (strlen($dbInst) > 1) {
+			$others = array();
+			for ($a = 0; $a < strlen($dbInst); $a++) {
+				if (substr($dbInst, $a, 1) != $current) {
+					$others[] = '"' . $this->parentObject->typeLabels[substr($dbInst, $a, 1)] . '"';
+				}
+			}
+			return tx_em_Tools::rfw(
+				sprintf($GLOBALS['LANG']->getLL('extInfoArray_double_installation_infotext'),
+					implode(' ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:and') . ' ', $others),
+					$this->parentObject->typeLabels[$current]
+				)
+			);
+		} else {
+			return '';
+		}
+	}
+
+
+	/**
+	 * Returns help text if applicable.
+	 *
+	 * @param	string		Help text key
+	 * @return	string		HTML table cell
+	 * @deprecated since TYPO3 4.5, will be removed in TYPO3 4.7
+	 */
+	function helpCol($key) {
+		global $BE_USER;
+		if ($BE_USER->uc['edit_showFieldHelp']) {
+			if (empty($key)) {
+				return '<td>&nbsp;</td>';
+			}
+			else {
+				return t3lib_BEfunc::cshItem($this->parentObject->descrTable, 'emconf_' . $key, $GLOBALS['BACK_PATH'], '<td>|</td>');
+			}
+		}
+		else {
+			return '';
+		}
+	}
+
+	/**
+	 * Returns the header column (for the extension details item), and applies help text if available
+	 *
+	 * @param	string	field key
+	 * @return	string	HTML ready to go
+	 */
+	function headerCol($key) {
+		$headerCol = $GLOBALS['LANG']->getLL('extInfoArray_' . $key);
+		return t3lib_BEfunc::wrapInHelp($this->parentObject->descrTable, 'emconf_' . $key, $headerCol);
+	}
+}
+
+?>
\ No newline at end of file
Index: typo3/sysext/em/classes/extensions/class.tx_em_extensions_list.php
===================================================================
--- typo3/sysext/em/classes/extensions/class.tx_em_extensions_list.php	(revision )
+++ typo3/sysext/em/classes/extensions/class.tx_em_extensions_list.php	(revision )
@@ -0,0 +1,852 @@
+<?php
+/* **************************************************************
+*  Copyright notice
+*
+*  (c) webservices.nl
+*  (c) 2006-2010 Karsten Dambekalns <karsten@typo3.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+/* $Id: class.tx_em_extensions_list.php 2084 2010-03-22 01:46:37Z steffenk $ */
+
+/**
+ * Enter description here...
+ *
+ */
+class tx_em_Extensions_List {
+
+
+	protected $parentObject;
+
+	protected $categories;
+	protected $types;
+
+	/**
+	 * @param null $parentObject
+ *
+	 */
+	public function __construct($parentObject = NULL) {
+		$this->parentObject = $parentObject;
+		$this->install = t3lib_div::makeInstance('tx_em_Install', $this);
+
+		$this->categories = array(
+			'be' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_BE'),
+			'module' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_BE_modules'),
+			'fe' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_FE'),
+			'plugin' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_FE_plugins'),
+			'misc' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_miscellanous'),
+			'services' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_services'),
+			'templates' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_templates'),
+			'example' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_examples'),
+			'doc' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:category_documentation')
+		);
+		$this->types = array(
+			'S' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:type_system'),
+			'G' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:type_global'),
+			'L' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:type_local'),
+		);
+	}
+
+
+	/**
+	 *
+	 * @param unknown_type $type
+	 * @param unknown_type $format
+	 */
+	function renderListing($type, $format = 'HTML') {
+
+		switch($type) {
+			case 'loaded':
+			break;
+			case 'installed':
+			break;
+		}
+	}
+
+	/**
+	 * Returns the list of available (installed) extensions
+	 *
+	 * @return	array		Array with two arrays, list array (all extensions with info) and category index
+	 * @see getInstExtList()
+	 */
+	function getInstalledExtensions($new = FALSE)	{
+		$list = array();
+
+		if (!$new) {
+			$cat = $this->parentObject->defaultCategories;
+
+			$path = PATH_typo3.'sysext/';
+			$this->getInstExtList($path,$list,$cat,'S');
+
+			$path = PATH_typo3.'ext/';
+			$this->getInstExtList($path,$list,$cat,'G');
+
+			$path = PATH_typo3conf.'ext/';
+			$this->getInstExtList($path,$list,$cat,'L');
+
+			return array($list,$cat);
+		} else {
+			$path = PATH_typo3.'sysext/';
+			$this->getFlatInstExtList($path, $list, 'S');
+
+			$path = PATH_typo3.'ext/';
+			$this->getFlatInstExtList($path, $list, 'G');
+
+			$path = PATH_typo3conf.'ext/';
+			$this->getFlatInstExtList($path, $list, 'L');
+
+			return $list;
+		}
+	}
+
+	/**
+	 * Gathers all extensions in $path
+	 *
+	 * @param	string		Absolute path to local, global or system extensions
+	 * @param	array		Array with information for each extension key found. Notice: passed by reference
+	 * @param	array		Categories index: Contains extension titles grouped by various criteria.
+	 * @param	string		Path-type: L, G or S
+	 * @return	void		"Returns" content by reference
+	 * @see getInstalledExtensions()
+	 */
+	function getInstExtList($path,&$list,&$cat,$type)	{
+
+		if (@is_dir($path))	{
+			$extList = t3lib_div::get_dirs($path);
+			if (is_array($extList))	{
+				foreach($extList as $extKey)	{
+					if (@is_file($path.$extKey.'/ext_emconf.php'))	{
+						$emConf = tx_em_Tools::includeEMCONF($path.$extKey.'/ext_emconf.php', $extKey);
+						if (is_array($emConf))	{
+							if (is_array($list[$extKey]))	{
+								$list[$extKey]=array('doubleInstall'=>$list[$extKey]['doubleInstall']);
+							}
+							$list[$extKey]['extkey'] = $extKey;
+							$list[$extKey]['doubleInstall'].= $type;
+							$list[$extKey]['type'] = $type;
+							$list[$extKey]['installed'] = t3lib_extMgm::isLoaded($extKey);
+							$list[$extKey]['EM_CONF'] = $emConf;
+							$list[$extKey]['files'] = t3lib_div::getFilesInDir($path.$extKey, '', 0, '', $this->excludeForPackaging);
+
+							tx_em_Tools::setCat($cat,$list[$extKey], $extKey);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Gathers all extensions in $path
+	 *
+	 * @param	string		Absolute path to local, global or system extensions
+	 * @param	array		Array with information for each extension key found. Notice: passed by reference
+	 * @param	array		Categories index: Contains extension titles grouped by various criteria.
+	 * @param	string		Path-type: L, G or S
+	 * @return	void		"Returns" content by reference
+	 * @access private
+	 * @see getInstalledExtensions()
+	 */
+	function getFlatInstExtList($path, &$list, $type) {
+
+
+		if (@is_dir($path))	{
+			$extList = t3lib_div::get_dirs($path);
+			if (is_array($extList))	{
+				foreach($extList as $extKey)	{
+					$this->singleExtInfo($extKey, $path, $list, $type);
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param  $extKey
+	 * @param  $path
+	 * @param  $list
+	 * @param string $type
+	 * @return void
+	 */
+	public function singleExtInfo($extKey, $path, &$list, $type='') {
+		if (@is_file($path . $extKey . '/ext_emconf.php')) {
+			$relPath = '../../../../' . substr($path, strlen(PATH_site));
+			$emConf = tx_em_Tools::includeEMCONF($path . $extKey . '/ext_emconf.php', $extKey);
+			$manual = $path . $extKey . '/doc/manual.sxw';
+			if ($type === '') {
+				$type = tx_em_Tools::getExtTypeFromPath($path);
+			}
+			if (is_array($emConf))	{
+				$key = count($list);
+				$loaded = t3lib_extMgm::isLoaded($extKey);
+				if (is_array($list[$key]))	{
+					$list[$key]=array('doubleInstall'=>$list[$key]['doubleInstall']);
+				}
+				$list[$key]['extkey'] = $extKey;
+				$list[$key]['path'] = $path . $extKey;
+				$list[$key]['nodePath'] = substr($path . $extKey, strlen(PATH_site));
+				$list[$key]['doubleInstall'].= $this->types[$type];
+
+				$list[$key]['type'] = $this->types[$type];
+				$list[$key]['typeShort'] = $type;
+				$list[$key]['installed'] = $loaded ? 1 : 0;
+					// FIXME: raises PHP warning
+					// "Core: Error handler (BE): PHP Warning: htmlspecialchars() expects parameter 1 to be string, array given in [...]/typo3/mod/tools/em/classes/class.tx_em_extensions_list.php line 185
+				$list[$key] = t3lib_div::array_merge_recursive_overrule($list[$key], $emConf);
+				$list[$key]['title'] = htmlspecialchars($list[$key]['title']);
+				$list[$key]['description'] = htmlspecialchars($list[$key]['description']);
+				$list[$key]['files'] = t3lib_div::getFilesInDir($path . $extKey, '', 0, '', $this->excludeForPackaging);
+				$list[$key]['install'] = $loaded? '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array(
+					'CMD[showExt]' => $extKey,
+					'CMD[remove]' => 1,
+					'CMD[clrCmd]' => 1,
+					'SET[singleDetails]' => 'info'
+				))).'">'.tx_em_Tools::removeButton().'</a>':
+					'<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array(
+						'CMD[showExt]' => $extKey,
+						'CMD[load]' => 1,
+						'CMD[clrCmd]' => 1,
+						'SET[singleDetails]' => 'info'
+					))).'">'.tx_em_Tools::installButton().'</a>';
+
+				$list[$key]['install'] = $loaded? tx_em_Tools::removeButton() : tx_em_Tools::installButton();
+
+				$list[$key]['download'] = '<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
+					'CMD[doBackup]' => 1,
+					'SET[singleDetails]' => 'backup',
+					'CMD[showExt]' => $extKey
+				))) . '">' .
+					t3lib_iconWorks::getSpriteIcon('actions-system-extension-download') . ' title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:download') . '" alt=""></a>';
+
+				$list[$key]['doc'] = '';
+				if (@is_file($manual)) {
+					$list[$key]['doc'] = '<a href="' . htmlspecialchars($relPath . $extKey . '/doc/manual.sxw'). '" target="_blank">
+					<img src="res/icons/oodoc.gif" width="13" height="16" title="' . $GLOBALS['LANG']->getLL('listRow_local_manual') . '" alt="" /></a>';
+				}
+				$list[$key]['icon'] = @is_file($path . $extKey . '/ext_icon.gif') ? '<img src="' . $relPath . $extKey . '/ext_icon.gif" alt="" width="16" height="16" />' : '<img src="clear.gif" alt="" width="16" height="16" />';
+
+				$list[$key]['categoryShort'] = $list[$key]['category'];
+				$list[$key]['category'] = $this->categories[$list[$key]['category']];
+
+				unset($list[$key]['_md5_values_when_last_written']);
+			}
+		}
+	}
+
+
+	/**
+	 * Listing of loaded (installed) extensions
+	 *
+	 * @return	void
+	 */
+	function extensionList_loaded()	{
+		global $TYPO3_LOADED_EXT;
+
+		list($list, $cat) = $this->getInstalledExtensions();
+
+		// Loaded extensions
+		$content = '';
+		$lines = array();
+
+		// Available extensions
+		if (is_array($cat[$this->parentObject->MOD_SETTINGS['listOrder']]))	{
+			$content='';
+			$lines=array();
+			$lines[] = $this->extensionListRowHeader(' class="t3-row-header"',array('<td><img src="clear.gif" width="1" height="1" alt="" /></td>'));
+
+			foreach($cat[$this->parentObject->MOD_SETTINGS['listOrder']] as $catName => $extEkeys)	{
+
+				natcasesort($extEkeys);
+				$extensions = array();
+				foreach($extEkeys as $extKey => $data) {
+					if (array_key_exists($extKey, $TYPO3_LOADED_EXT) && ($this->parentObject->MOD_SETTINGS['display_shy'] || !$list[$extKey]['EM_CONF']['shy']) && $this->parentObject->searchExtension($extKey,$list[$extKey]))	{
+						if (in_array($extKey, $this->parentObject->requiredExt))	{
+							$loadUnloadLink = '<strong>' . $GLOBALS['TBE_TEMPLATE']->rfw($GLOBALS['LANG']->getLL('extension_required_short')) . '</strong>';
+						} else {
+							$loadUnloadLink = '<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array(
+								'CMD[showExt]' => $extKey,
+								'CMD[remove]' => 1
+							))).'">'.tx_em_Tools::removeButton().'</a>';
+						}
+
+						$extensions[] = $this->extensionListRow($extKey,$list[$extKey],array('<td class="bgColor">'.$loadUnloadLink.'</td>'));
+
+					}
+				}
+				if(count($extensions)) {
+					$lines[]='<tr><td colspan="'.(3+$this->parentObject->detailCols[$this->parentObject->MOD_SETTINGS['display_details']]).'"><br /></td></tr>';
+					$lines[]='<tr><td colspan="'.(3+$this->parentObject->detailCols[$this->parentObject->MOD_SETTINGS['display_details']]).'">' . t3lib_iconWorks::getSpriteIcon('apps-filetree-folder-default') . '<strong>'.htmlspecialchars($this->parentObject->listOrderTitle($this->parentObject->MOD_SETTINGS['listOrder'],$catName)).'</strong></td></tr>';
+					$lines[] = implode(LF,$extensions);
+				}
+			}
+		}
+
+		$content.= '<form action="' . $this->parentObject->script . '" method="post" name="lookupform">';
+		$content.= '<label for="lookUp">' . $GLOBALS['LANG']->getLL('look_up') . '</label> <input type="text" id="lookUp" name="lookUp" value="' . htmlspecialchars($this->lookUpStr) . '" /><input type="submit" value="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:search') . '" /><br /><br />';
+
+		$content.= '</form>
+
+			<!-- Loaded Extensions List -->
+			<table border="0" cellpadding="2" cellspacing="1">'.implode('',$lines).'</table>';
+
+		return $content;
+	}
+
+	/**
+	 * Listing of available (installed) extensions
+	 *
+	 * @return	void
+	 */
+	function extensionList_installed()	{
+		global $TYPO3_LOADED_EXT;
+
+		list($list,$cat)=$this->getInstalledExtensions();
+
+		// Available extensions
+		if (is_array($cat[$this->parentObject->MOD_SETTINGS['listOrder']]))	{
+			$content='';
+			$lines=array();
+			$lines[]=$this->extensionListRowHeader(' class="t3-row-header"',array('<td><img src="clear.gif" width="18" height="1" alt="" /></td>'));
+
+			$allKeys=array();
+			foreach($cat[$this->parentObject->MOD_SETTINGS['listOrder']] as $catName => $extEkeys)	{
+				if(!$this->parentObject->MOD_SETTINGS['display_obsolete'] && $catName=='obsolete') continue;
+
+				$allKeys[]='';
+				$allKeys[]='TYPE: '.$catName;
+
+				natcasesort($extEkeys);
+				$extensions = array();
+				foreach ($extEkeys as $extKey => $value) {
+					$allKeys[]=$extKey;
+					if ((!$list[$extKey]['EM_CONF']['shy'] || $this->parentObject->MOD_SETTINGS['display_shy']) &&
+							($list[$extKey]['EM_CONF']['state']!='obsolete' || $this->parentObject->MOD_SETTINGS['display_obsolete'])
+							&& $this->parentObject->searchExtension($extKey,$list[$extKey])) {
+						$loadUnloadLink = t3lib_extMgm::isLoaded($extKey)?
+						'<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array(
+							'CMD[showExt]' => $extKey,
+							'CMD[remove]' => 1,
+							'CMD[clrCmd]' => 1,
+							'SET[singleDetails]' => 'info'
+						))).'">'.tx_em_Tools::removeButton().'</a>':
+						'<a href="'.htmlspecialchars(t3lib_div::linkThisScript(array(
+							'CMD[showExt]' => $extKey,
+							'CMD[load]' => 1,
+							'CMD[clrCmd]' => 1,
+							'SET[singleDetails]' => 'info'
+						))).'">'.tx_em_Tools::installButton().'</a>';
+						if (in_array($extKey,$this->parentObject->requiredExt))	{
+							$loadUnloadLink = '<strong>' . $GLOBALS['TBE_TEMPLATE']->rfw($GLOBALS['LANG']->getLL('extension_required_short')) . '</strong>';
+						}
+						$theRowClass = t3lib_extMgm::isLoaded($extKey)? 'em-listbg1' : 'em-listbg2';
+						$extensions[]=$this->extensionListRow($extKey,$list[$extKey],array('<td class="bgColor">'.$loadUnloadLink.'</td>'),$theRowClass);
+					}
+				}
+				if(count($extensions)) {
+					$lines[]='<tr><td colspan="'.(3+$this->parentObject->detailCols[$this->parentObject->MOD_SETTINGS['display_details']]).'"><br /></td></tr>';
+					$lines[]='<tr><td colspan="'.(3+$this->parentObject->detailCols[$this->parentObject->MOD_SETTINGS['display_details']]).'">' . t3lib_iconWorks::getSpriteIcon('apps-filetree-folder-default') . '<strong>'.htmlspecialchars($this->parentObject->listOrderTitle($this->parentObject->MOD_SETTINGS['listOrder'],$catName)).'</strong></td></tr>';
+					$lines[] = implode(LF,$extensions);
+				}
+			}
+
+			$content.='
+
+
+<!--
+EXTENSION KEYS:
+
+'.trim(implode(LF,$allKeys)).'
+
+-->
+
+';
+
+			$content.= sprintf($GLOBALS['LANG']->getLL('how_to_install'), tx_em_Tools::installButton()) . ' <br />' .
+						sprintf($GLOBALS['LANG']->getLL('how_to_uninstall'), tx_em_Tools::removeButton()). ' <br /><br />';
+			$content .= '<form action="'. $this->parentObject->script . '" method="post" name="lookupform">';
+			$content .= '<label for="lookUp">' . $GLOBALS['LANG']->getLL('look_up') . '</label> <input type="text" id="lookUp" name="lookUp" value="' . htmlspecialchars($this->parentObject->lookUpStr) . '" /><input type="submit" value="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:search') . '" /></form><br /><br />';
+			$content.= $this->securityHint.'<br /><br />';
+
+			$content.= '<table border="0" cellpadding="2" cellspacing="1">'.implode('',$lines).'</table>';
+
+			return $content;
+		}
+	}
+
+
+
+/**
+	 * Prints the header row for the various listings
+	 *
+	 * @param	string		Attributes for the <tr> tag
+	 * @param	array		Preset cells in the beginning of the row. Typically a blank cell with a clear-gif
+	 * @param	boolean		If set, the list is coming from remote server.
+	 * @return	string		HTML <tr> table row
+	 */
+	function extensionListRowHeader($trAttrib,$cells,$import=0)	{
+		$cells[] = '<td></td>';
+		$cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_title') . '</td>';
+
+		if (!$this->parentObject->MOD_SETTINGS['display_details'])	{
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_description') . '</td>';
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_author') . '</td>';
+		} elseif ($this->parentObject->MOD_SETTINGS['display_details']==2)	{
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_priority') . '</td>';
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_modifies_tables_short') . '</td>';
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_modules') . '</td>';
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_clear_cache_short') . '</td>';
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_internal') . '</td>';
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_shy') . '</td>';
+		} elseif ($this->parentObject->MOD_SETTINGS['display_details']==3)	{
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_tables_fields') . '</td>';
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_ts_files') . '</td>';
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_affects') . '</td>';
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_modules') . '</td>';
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_config') . '</td>';
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_code_warnings') . '</td>';
+		} elseif ($this->parentObject->MOD_SETTINGS['display_details']==4)	{
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_locallang') . '</td>';
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_classes') . '</td>';
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_code_warnings') . '</td>';
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_annoyances') . '</td>';
+		} elseif ($this->parentObject->MOD_SETTINGS['display_details']==5)	{
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_changed_files') . '</td>';
+		} else {
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_ext_key') . '</td>';
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_version') . '</td>';
+			if (!$import) {
+				$cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_download_short') . '</td>';
+				$cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_documentation_short') . '</td>';
+				$cells[] = '<td>' . $GLOBALS['LANG']->getLL('listRowHeader_type') . '</td>';
+			} else {
+				$cells[] = '<td' . tx_em_Tools::labelInfo($GLOBALS['LANG']->getLL('listRowHeader_title_upload_date')) . '>' .
+							$GLOBALS['LANG']->getLL('listRowHeader_upload_date') . '</td>';
+				$cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_author') . '</td>';
+				$cells[] = '<td' . tx_em_Tools::labelInfo($GLOBALS['LANG']->getLL('listRowHeader_title_current_version')) . '>' .
+							$GLOBALS['LANG']->getLL('listRowHeader_current_version') . '</td>';
+				$cells[] = '<td' . tx_em_Tools::labelInfo($GLOBALS['LANG']->getLL('listRowHeader_title_current_type')) . '>' .
+							$GLOBALS['LANG']->getLL('listRowHeader_current_type') . '</td>';
+				$cells[] = '<td' . tx_em_Tools::labelInfo($GLOBALS['LANG']->getLL('listRowHeader_title_number_of_downloads')) . '>' .
+							$GLOBALS['LANG']->getLL('listRowHeader_download_short') . '</td>';
+			}
+			$cells[] = '<td>' . $GLOBALS['LANG']->getLL('extInfoArray_state') . '</td>';
+		}
+		return '
+			<tr'.$trAttrib.'>
+				'.implode('
+				',$cells).'
+			</tr>';
+	}
+
+
+/**
+	 * Prints a row with data for the various extension listings
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array
+	 * @param	array		Preset table cells, eg. install/uninstall icons.
+	 * @param	string		<tr> tag class
+	 * @param	array		Array with installed extension keys (as keys)
+	 * @param	boolean		If set, the list is coming from remote server.
+	 * @param	string		Alternative link URL
+	 * @return	string		HTML <tr> content
+	 */
+	function extensionListRow($extKey,$extInfo,$cells,$bgColorClass='',$inst_list=array(),$import=0,$altLinkUrl='')	{
+			// Icon:
+		$imgInfo = @getImageSize(tx_em_Tools::getExtPath($extKey, $extInfo['type']) . '/ext_icon.gif');
+		if (is_array($imgInfo))	{
+			$cells[] = '<td><img src="'.$GLOBALS['BACK_PATH'].$this->parentObject->typeRelPaths[$extInfo['type']].$extKey.'/ext_icon.gif'.'" '.$imgInfo[3].' alt="" /></td>';
+		} elseif ($extInfo['_ICON']) {
+			$cells[] = '<td>'.$extInfo['_ICON'].'</td>';
+		} else {
+			$cells[] = '<td><img src="clear.gif" width="1" height="1" alt="" /></td>';
+		}
+
+			// Extension title:
+		$cells[] = '<td nowrap="nowrap"><a href="' . htmlspecialchars($altLinkUrl ? $altLinkUrl : t3lib_div::linkThisScript(array(
+				'CMD[showExt]' => $extKey,
+				'SET[singleDetails]' => 'info'
+			))) . '" title="' . htmlspecialchars($extInfo['EM_CONF']['description']) . '">'
+			. t3lib_div::fixed_lgd_cs($extInfo['EM_CONF']['title'] ? htmlspecialchars($extInfo['EM_CONF']['title']) : '<em>' . $extKey . '</em>', 40) . '</a></td>';
+
+			// Based on the display mode you will see more or less details:
+		if (!$this->parentObject->MOD_SETTINGS['display_details'])	{
+			$cells[] = '<td>'.htmlspecialchars(t3lib_div::fixed_lgd_cs($extInfo['EM_CONF']['description'],400)).'<br /><img src="clear.gif" width="300" height="1" alt="" /></td>';
+			$cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['author_email'] ? '<a href="mailto:'.htmlspecialchars($extInfo['EM_CONF']['author_email']).'">' : '').htmlspecialchars($extInfo['EM_CONF']['author']).(htmlspecialchars($extInfo['EM_CONF']['author_email']) ? '</a>' : '').($extInfo['EM_CONF']['author_company'] ? '<br />'.htmlspecialchars($extInfo['EM_CONF']['author_company']) : '').'</td>';
+		} elseif ($this->parentObject->MOD_SETTINGS['display_details']==2)	{
+			$cells[] = '<td nowrap="nowrap">'.$extInfo['EM_CONF']['priority'].'</td>';
+			$cells[] = '<td nowrap="nowrap">'.implode('<br />',t3lib_div::trimExplode(',',$extInfo['EM_CONF']['modify_tables'],1)).'</td>';
+			$cells[] = '<td nowrap="nowrap">'.$extInfo['EM_CONF']['module'].'</td>';
+			$cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['clearCacheOnLoad'] ? $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes') : '').'</td>';
+			$cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['internal'] ? $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes') : '').'</td>';
+			$cells[] = '<td nowrap="nowrap">'.($extInfo['EM_CONF']['shy'] ? $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes') : '').'</td>';
+		} elseif ($this->parentObject->MOD_SETTINGS['display_details']==3)	{
+			$techInfo = $this->install->makeDetailedExtensionAnalysis($extKey,$extInfo);
+
+			$cells[] = '<td>'.$this->parentObject->extensionDetails->extInformationArray_dbReq($techInfo).
+			'</td>';
+			$cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['TSfiles']) ? implode('<br />',$techInfo['TSfiles']) : '').'</td>';
+			$cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['flags']) ? implode('<br />',$techInfo['flags']) : '').'</td>';
+			$cells[] = '<td nowrap="nowrap">'.(is_array($techInfo['moduleNames']) ? implode('<br />',$techInfo['moduleNames']) : '').'</td>';
+			$cells[] = '<td nowrap="nowrap">'.($techInfo['conf'] ? $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes') : '').'</td>';
+			$cells[] = '<td>'.
+			$GLOBALS['TBE_TEMPLATE']->rfw((t3lib_extMgm::isLoaded($extKey) && $techInfo['tables_error'] ?
+				'<strong>' . $GLOBALS['LANG']->getLL('extInfoArray_table_error') . '</strong><br />' .
+				$GLOBALS['LANG']->getLL('extInfoArray_missing_fields') : '') .
+			(t3lib_extMgm::isLoaded($extKey) && $techInfo['static_error'] ?
+				'<strong>' . $GLOBALS['LANG']->getLL('extInfoArray_static_table_error') . '</strong><br />' .
+				$GLOBALS['LANG']->getLL('extInfoArray_static_tables_missing_empty') : '')) .
+			'</td>';
+		} elseif ($this->parentObject->MOD_SETTINGS['display_details']==4)	{
+			$techInfo=$this->install->makeDetailedExtensionAnalysis($extKey,$extInfo,1);
+
+			$cells[] = '<td>'.(is_array($techInfo['locallang']) ? implode('<br />',$techInfo['locallang']) : '').'</td>';
+			$cells[] = '<td>'.(is_array($techInfo['classes']) ? implode('<br />',$techInfo['classes']) : '').'</td>';
+			$cells[] = '<td>'.(is_array($techInfo['errors']) ? $GLOBALS['TBE_TEMPLATE']->rfw(implode('<hr />',$techInfo['errors'])) : '').'</td>';
+			$cells[] = '<td>'.(is_array($techInfo['NSerrors']) ?
+						(!t3lib_div::inList($this->parentObject->nameSpaceExceptions, $extKey) ?
+							t3lib_utility_Debug::viewarray($techInfo['NSerrors']) :
+							$GLOBALS['TBE_TEMPLATE']->dfw($GLOBALS['LANG']->getLL('extInfoArray_exception'))) : '') . '</td>';
+		} elseif ($this->parentObject->MOD_SETTINGS['display_details']==5)	{
+			$currentMd5Array = $this->parentObject->extensionDetails->serverExtensionMD5array($extKey,$extInfo);
+			$affectedFiles = '';
+			$msgLines = array();
+			$msgLines[] = $GLOBALS['LANG']->getLL('listRow_files') . ' ' . count($currentMd5Array);
+			if (strcmp($extInfo['EM_CONF']['_md5_values_when_last_written'],serialize($currentMd5Array)))	{
+				$msgLines[] = $GLOBALS['TBE_TEMPLATE']->rfw('<br /><strong>' . $GLOBALS['LANG']->getLL('extInfoArray_difference_detected') . '</strong>');
+				$affectedFiles = tx_em_Tools::findMD5ArrayDiff($currentMd5Array,unserialize($extInfo['EM_CONF']['_md5_values_when_last_written']));
+				if (count($affectedFiles)) {
+					$msgLines[] = '<br /><strong>' . $GLOBALS['LANG']->getLL('extInfoArray_modified_files') . '</strong><br />' .
+								$GLOBALS['TBE_TEMPLATE']->rfw(implode('<br />', $affectedFiles));
+				}
+			}
+			$cells[] = '<td>'.implode('<br />',$msgLines).'</td>';
+		} else {
+				// Default view:
+			$verDiff = $inst_list[$extKey] && tx_em_Tools::versionDifference($extInfo['EM_CONF']['version'],$inst_list[$extKey]['EM_CONF']['version'],$this->parentObject->versionDiffFactor);
+
+			$cells[] = '<td nowrap="nowrap"><em>'.$extKey.'</em></td>';
+			$cells[] = '<td nowrap="nowrap">'.($verDiff ? '<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw(htmlspecialchars($extInfo['EM_CONF']['version'])).'</strong>' : $extInfo['EM_CONF']['version']).'</td>';
+			if (!$import) {		// Listing extension on LOCAL server:
+					// Extension Download:
+				$cells[] = '<td nowrap="nowrap"><a href="' . htmlspecialchars(t3lib_div::linkThisScript(array(
+					'CMD[doBackup]' => 1,
+					'SET[singleDetails]' => 'backup',
+					'CMD[showExt]' => $extKey
+				))) . '" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:download') . '">' .
+					t3lib_iconWorks::getSpriteIcon('actions-system-extension-download') .
+				'</a></td>';
+
+					// Manual download
+				$fileP = PATH_site.$this->parentObject->typePaths[$extInfo['type']].$extKey.'/doc/manual.sxw';
+				$cells[] = '<td nowrap="nowrap">'.
+				($this->parentObject->typePaths[$extInfo['type']] && @is_file($fileP) ?
+					'<a href="' . htmlspecialchars(t3lib_div::resolveBackPath($this->parentObject->doc->backPath . '../' . $this->parentObject->typePaths[$extInfo['type']] . $extKey . '/doc/manual.sxw')).'" target="_blank" title="' . $GLOBALS['LANG']->getLL('listRow_local_manual') . '">' .
+						t3lib_iconWorks::getSpriteIcon('actions-system-extension-documentation') . '</a>' : '') .
+				'</td>';
+
+					// Double installation (inclusion of an extension in more than one of system, global or local scopes)
+				$doubleInstall = '';
+				if (strlen($extInfo['doubleInstall']) > 1) {
+						// Separate the "SL" et al. string into an array and replace L by Local, G by Global etc.
+					$doubleInstallations = str_replace(
+						array('S', 'G', 'L'),
+						array(
+							$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:sysext'),
+							$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:globalext'),
+							$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:localext')
+						),
+						str_split($extInfo['doubleInstall'])
+					);
+						// Last extension is the one actually used
+					$usedExtension = array_pop($doubleInstallations);
+						// Next extension is overridden
+					$overriddenExtensions = array_pop($doubleInstallations);
+						// If the array is not yet empty, the extension is actually installed 3 times (SGL)
+					if (count($doubleInstallations) > 0) {
+						$lastExtension = array_pop($doubleInstallations);
+						$overriddenExtensions .= ' ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:and') . ' ' . $lastExtension;
+					}
+					$doubleInstallTitle = sprintf(
+						$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:double_inclusion'),
+						$usedExtension,
+						$overriddenExtensions
+					);
+					$doubleInstall = ' <strong><abbr title="' . $doubleInstallTitle .'">' . $GLOBALS['TBE_TEMPLATE']->rfw($extInfo['doubleInstall']) . '</abbr></strong>';
+				}
+				$cells[] = '<td nowrap="nowrap">' . $this->parentObject->typeLabels[$extInfo['type']] . $doubleInstall . '</td>';
+			} else {	// Listing extensions from REMOTE repository:
+				$inst_curVer = $inst_list[$extKey]['EM_CONF']['version'];
+				if (isset($inst_list[$extKey]))	{
+					if ($verDiff)	$inst_curVer = '<strong>'.$GLOBALS['TBE_TEMPLATE']->rfw($inst_curVer).'</strong>';
+				}
+				$cells[] = '<td nowrap="nowrap">' . t3lib_befunc::date($extInfo['EM_CONF']['lastuploaddate']) . '</td>';
+				$cells[] = '<td nowrap="nowrap">' . htmlspecialchars(t3lib_div::fixed_lgd_cs($extInfo['EM_CONF']['author'], $GLOBALS['BE_USER']->uc[titleLen])) . '</td>';
+				$cells[] = '<td nowrap="nowrap">'.$inst_curVer.'</td>';
+				$cells[] = '<td nowrap="nowrap">'.$this->parentObject->typeLabels[$inst_list[$extKey]['type']].(strlen($inst_list[$extKey]['doubleInstall'])>1?'<strong> '.$GLOBALS['TBE_TEMPLATE']->rfw($inst_list[$extKey]['doubleInstall']).'</strong>':'').'</td>';
+				$cells[] = '<td nowrap="nowrap">'.($extInfo['downloadcounter_all']?$extInfo['downloadcounter_all']:'&nbsp;&nbsp;').'/'.($extInfo['downloadcounter']?$extInfo['downloadcounter']:'&nbsp;').'</td>';
+			}
+			$cells[] = '<td nowrap="nowrap" class="extstate" style="background-color:'.$this->parentObject->stateColors[$extInfo['EM_CONF']['state']].';">'.$this->parentObject->states[$extInfo['EM_CONF']['state']].'</td>';
+		}
+
+			// show a different background through a different class for insecure (-1) extensions,
+			// for unreviewed (0) and reviewed extensions (1), just use the regular class
+		if($this->parentObject->xmlhandler->getReviewState($extKey,$extInfo['EM_CONF']['version']) < 0) {
+			$bgclass = ' class="unsupported-ext"';
+		} else {
+			$bgclass = ' class="' . ($bgColorClass ? $bgColorClass : 'em-listbg1') . '"';
+		}
+
+		return '
+			<tr'.$bgclass.'>
+				'.implode('
+				',$cells).'
+			</tr>';
+	}
+
+
+	/**
+	 *  Displays a list of extensions where a newer version is available
+	 *  in the TER than the one that is installed right now
+	 *  integrated from the extension "ter_update_check" for TYPO3 4.2 by Christian Welzel
+	 *
+	 * @return	nothing
+	 */
+	function showExtensionsToUpdate() {
+		global $LANG;
+		$extList = $this->getInstalledExtensions();
+
+		$content = '<table border="0" cellpadding="2" cellspacing="1">'.
+		'<tr class="t3-row-header">'.
+			'<td></td>'.
+			'<td>'.$LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_name').'</td>'.
+			'<td>'.$LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_key').'</td>'.
+			'<td>'.$LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_loc_ver').'</td>'.
+			'<td>'.$LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_rem_ver').'</td>'.
+			'<td>'.$LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_location').'</td>'.
+			'<td>'.$LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:tab_mod_comment').'</td>'.
+		'</tr>';
+
+		foreach ($extList[0] as $name => $data)	{
+			$this->parentObject->xmlhandler->searchExtensionsXMLExact($name, '', '', TRUE, TRUE);
+			if (!is_array($this->parentObject->xmlhandler->extensionsXML[$name]))	{
+				continue;
+			}
+
+			$v = $this->parentObject->xmlhandler->extensionsXML[$name]['versions'];
+			$versions = array_keys($v);
+			natsort($versions);
+			$lastversion = end($versions);
+
+			if ((t3lib_extMgm::isLoaded($name) || $this->parentObject->MOD_SETTINGS['display_installed']) &&
+				($data['EM_CONF']['shy'] == 0 || $this->parentObject->MOD_SETTINGS['display_shy']) &&
+				tx_em_Tools::versionDifference($lastversion, $data['EM_CONF']['version'], 1))	{
+
+				$imgInfo = @getImageSize(tx_em_Tools::getExtPath($name, $data['type']) . '/ext_icon.gif');
+				if (is_array($imgInfo)) {
+					$icon = '<img src="'.$GLOBALS['BACK_PATH'].$this->parentObject->typeRelPaths[$data['type']].$name.'/ext_icon.gif'.'" '.$imgInfo[3].' alt="" />';
+				} elseif ($data['_ICON']) { //TODO: see if this can be removed, seems to be wrong in this context
+					$icon = $data['_ICON'];
+				} else {
+					$icon = '<img src="clear.gif" width="1" height="1" alt="" />';
+				}
+				$comment = '<table cellpadding="0" cellspacing="0" width="100%">';
+				foreach ($versions as $vk) {
+					$va = & $v[$vk];
+					if (t3lib_div::int_from_ver($vk) <= t3lib_div::int_from_ver($data['EM_CONF']['version']))	{
+						continue;
+					}
+					$comment .= '<tr><td valign="top" style="padding-right:2px;border-bottom:1px dotted gray">'.$vk.'</td>'.'<td valign="top" style="border-bottom:1px dotted gray">'.nl2br($va[uploadcomment]).'</td></tr>';
+				}
+				$comment .= '</table>';
+
+				$serverMD5Array = $this->parentObject->extensionDetails->serverExtensionMD5array($name,$data);
+				if (is_array($serverMD5Array))	{
+					ksort($serverMD5Array);
+				}
+				$currentMD5Array = unserialize($data['EM_CONF']['_md5_values_when_last_written']);
+				if (is_array($currentMD5Array))	{
+					@ksort($currentMD5Array);
+				}
+				$warn = '';
+				if (strcmp(serialize($currentMD5Array), serialize($serverMD5Array)))	{
+					$warn = '<tr class="bgColor4" style="color:red"><td colspan="7">'.$GLOBALS['TBE_TEMPLATE']->rfw('<br /><strong>'.$name.': '.$LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:msg_warn_diff').'</strong>').'</td></tr>'.LF;
+					if ($this->parentObject->MOD_SETTINGS['display_files'] == 1) {
+						$affectedFiles = tx_em_Tools::findMD5ArrayDiff($serverMD5Array,$currentMD5Array);
+						if (count($affectedFiles)) {
+							$warn .= '<tr class="bgColor4"><td colspan="7"><strong>'.$LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:msg_modified').'</strong><br />'.$GLOBALS['TBE_TEMPLATE']->rfw(implode('<br />',$affectedFiles)).'</td></tr>'.LF;
+						}
+					}
+				}
+					//TODO: $extInfo is unknown in this context
+				$content .= '<tr class="bgColor4"><td valign="top">'.$icon.'</td>'.
+'<td valign="top">' . ($data['EM_CONF']['state'] == 'excludeFromUpdates' ? '<span style="color:#cf7307">' . $data['EM_CONF']['title'] . ' ' . $LANG->sL('LLL:EXT:lang/locallang_mod_tools_em.xml:write_protected') . '</span>' : '<a href="?CMD[importExtInfo]='.$name.'">'.$data[EM_CONF][title].'</a>') . '</td>'.
+'<td valign="top">'.$name.'</td>'.
+'<td valign="top" align="right">'.$data[EM_CONF][version].'</td>'.
+'<td valign="top" align="right">'.$lastversion.'</td>'.
+'<td valign="top" nowrap="nowrap">'.$this->parentObject->typeLabels[$data['type']].(strlen($data['doubleInstall'])>1?'<strong> '.$GLOBALS['TBE_TEMPLATE']->rfw($extInfo['doubleInstall']).'</strong>':'').'</td>'.
+'<td valign="top">'.$comment.'</td></tr>'.LF.
+$warn.
+'<tr class="bgColor4"><td colspan="7"><hr style="margin:0px" /></td></tr>'.LF;
+			}
+		}
+
+		return $content . '</table><br />';
+	}
+
+	/**
+	 * Maps remote extensions information into $cat/$list arrays for listing
+	 *
+	 * @param	boolean		If set the info in the internal extensionsXML array will be unset before returning the result.
+	 * @return	array		List array and category index as key 0 / 1 in an array.
+	 */
+	function prepareImportExtList($unsetProc = false) {
+		$list = array();
+		$cat = $this->parentObject->defaultCategories;
+		$filepath = $this->parentObject->getMirrorURL();
+
+		foreach ($this->parentObject->xmlhandler->extensionsXML as $extKey => $data) {
+			$GLOBALS['LANG']->csConvObj->convarray($data,'utf-8',$GLOBALS['LANG']->charSet); // is there a better place for conversion?
+			$list[$extKey]['type'] = '_';
+			$version = array_keys($data['versions']);
+			$extPath = t3lib_div::strtolower($extKey);
+			$list[$extKey]['_ICON'] = '<img alt="" src="' . $filepath . $extPath{0} . '/' . $extPath{1} . '/' . $extPath . '_' . end($version) . '.gif" />';
+			$list[$extKey]['downloadcounter'] = $data['downloadcounter'];
+
+			foreach(array_keys($data['versions']) as $version) {
+				$list[$extKey]['versions'][$version]['downloadcounter'] = $data['versions'][$version]['downloadcounter'];
+
+				$list[$extKey]['versions'][$version]['EM_CONF'] = array(
+				'version' => $version,
+				'title' => $data['versions'][$version]['title'],
+				'description' => $data['versions'][$version]['description'],
+				'category' => $data['versions'][$version]['category'],
+				'constraints' => $data['versions'][$version]['dependencies'],
+				'state' => $data['versions'][$version]['state'],
+				'reviewstate' => $data['versions'][$version]['reviewstate'],
+				'lastuploaddate' => $data['versions'][$version]['lastuploaddate'],
+				'author' => $data['versions'][$version]['authorname'],
+				'author_email' => $data['versions'][$version]['authoremail'],
+				'author_company' => $data['versions'][$version]['authorcompany'],
+				);
+			}
+			tx_em_Tools::setCat($cat, $list[$extKey]['versions'][$version], $extKey);
+			if ($unsetProc) {
+				unset($this->parentObject->xmlhandler->extensionsXML[$extKey]);
+			}
+		}
+
+		return array($list,$cat);
+	}
+
+
+	/**
+	 * Adds extension to extension list and returns new list. If -1 is returned, an error happend.
+	 * Checks dependencies etc.
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array - information about installed extensions
+	 * @return	string		New list of installed extensions or -1 if error
+	 * @see showExtDetails()
+	 */
+	function addExtToList($extKey,$instExtInfo)	{
+		global $TYPO3_LOADED_EXT;
+
+			// ext_emconf.php information:
+		$conf = $instExtInfo[$extKey]['EM_CONF'];
+
+			// Get list of installed extensions and add this one.
+		$listArr = array_keys($TYPO3_LOADED_EXT);
+		if ($conf['priority']=='top')	{
+			array_unshift($listArr,$extKey);
+		} else {
+			$listArr[]=$extKey;
+		}
+
+			// Manage other circumstances:
+		$listArr = tx_em_Tools::managesPriorities($listArr,$instExtInfo);
+		$listArr = $this->removeRequiredExtFromListArr($listArr);
+
+			// Implode unique list of extensions to load and return:
+		$list = implode(',',array_unique($listArr));
+		return $list;
+	}
+
+	/**
+	 * Remove extension key from the list of currently installed extensions and return list. If -1 is returned, an error happend.
+	 * Checks dependencies etc.
+	 *
+	 * @param	string		Extension key
+	 * @param	array		Extension information array - information about installed extensions
+	 * @return	string		New list of installed extensions or -1 if error
+	 * @see showExtDetails()
+	 */
+	function removeExtFromList($extKey, $instExtInfo)	{
+		global $TYPO3_LOADED_EXT;
+
+			// Initialize:
+		$depList = array();
+		$listArr = array_keys($TYPO3_LOADED_EXT);
+
+			// Traverse all installed extensions to check if any of them have this extension as dependency since if that is the case it will not work out!
+		foreach($listArr as $k => $ext)	{
+			if ($instExtInfo[$ext]['EM_CONF']['dependencies'])	{
+				$dep = t3lib_div::trimExplode(',',$instExtInfo[$ext]['EM_CONF']['dependencies'],1);
+				if (in_array($extKey,$dep))	{
+					$depList[] = $ext;
+				}
+			}
+			if (!strcmp($ext,$extKey))	unset($listArr[$k]);
+		}
+
+			// Returns either error or the new list
+		if (count($depList))	{
+			$msg = sprintf($GLOBALS['LANG']->getLL('removeExtFromList_dependency'),
+				implode(', ', $depList)
+			);
+			$this->content .= $this->doc->section($GLOBALS['LANG']->getLL('removeExtFromList_dependency_error'), $msg, 0, 1, 2);
+			return -1;
+		} else {
+			$listArr = $this->removeRequiredExtFromListArr($listArr);
+			$list = implode(',',array_unique($listArr));
+			return $list;
+		}
+	}
+
+	/**
+	 * This removes any required extensions from the $listArr - they should NOT be added to the common extension list, because they are found already in "requiredExt" list
+	 *
+	 * @param	array		Array of extension keys as values
+	 * @return	array		Modified array
+	 * @see removeExtFromList(), addExtToList()
+	 */
+	function removeRequiredExtFromListArr($listArr) {
+		foreach($listArr as $k => $ext) {
+			if (in_array($ext, $this->parentObject->requiredExt) || !strcmp($ext,'_CACHEFILE')) {
+				unset($listArr[$k]);
+			}
+		}
+		return $listArr;
+	}
+
+
+}
+
+?>
\ No newline at end of file
