diff --git a/t3lib/class.t3lib_befunc.php b/t3lib/class.t3lib_befunc.php
index 135211a08ac4c61713c786385fea1f5d64600b5a..09ba414c8686fcec9cffd2d70727ac91e1a1d676 100644
--- a/t3lib/class.t3lib_befunc.php
+++ b/t3lib/class.t3lib_befunc.php
@@ -3159,7 +3159,7 @@ final class t3lib_BEfunc {
 	 */
 	public static function getUrlToken($formName = 'securityToken', $tokenName = 'formToken') {
 		$formprotection = t3lib_formprotection_Factory::get();
-		return '&' . $tokenName . '=' . $formprotection->generateToken($formName) . '-' . $formName;
+		return '&' . $tokenName . '=' . $formprotection->generateToken($formName);
 	}
 
 	/*******************************************
diff --git a/t3lib/class.t3lib_pagerenderer.php b/t3lib/class.t3lib_pagerenderer.php
index 19188397dbc0bd14e1b7837ca1cec0966d03ba85..fc287a9aa63ca5ffed89a1b70763f1606c937ba7 100644
--- a/t3lib/class.t3lib_pagerenderer.php
+++ b/t3lib/class.t3lib_pagerenderer.php
@@ -985,7 +985,7 @@ class t3lib_PageRenderer implements t3lib_Singleton {
 			// does this only with multiple arguments
 		$this->addExtOnReadyCode('
 			(function() {
-				TYPO3.ExtDirectToken = "' . $token . '-extDirect";
+				TYPO3.ExtDirectToken = "' . $token . '";
 				for (var api in Ext.app.ExtDirectAPI) {
 					var provider = Ext.Direct.addProvider(Ext.app.ExtDirectAPI[api]);
 					provider.on("beforecall", function(provider, transaction, meta) {
diff --git a/t3lib/class.t3lib_tceforms.php b/t3lib/class.t3lib_tceforms.php
index 86aee82a31b1e9ecda6745b484b30a8f8a044469..ba7ae5c0abb38ffc369612d80c8dc3dcb069d8b5 100644
--- a/t3lib/class.t3lib_tceforms.php
+++ b/t3lib/class.t3lib_tceforms.php
@@ -4984,7 +4984,7 @@ class t3lib_TCEforms {
 	 */
 	public static function getHiddenTokenField($formName = 'securityToken', $tokenName = 'formToken') {
 		$formprotection = t3lib_formprotection_Factory::get();
-		return '<input type="hidden" name="' .$tokenName . '" value="' . $formprotection->generateToken($formName) . '-' . $formName . '" />';
+		return '<input type="hidden" name="' .$tokenName . '" value="' . $formprotection->generateToken($formName) . '" />';
 	}
 
 	/**
diff --git a/t3lib/formprotection/class.t3lib_formprotection_abstract.php b/t3lib/formprotection/class.t3lib_formprotection_abstract.php
index ba2dddb1e969f73aa9cbe9737a8e4df4b40c044e..313bc1cc452dc64a3cc512af04d76fd686ef67ba 100644
--- a/t3lib/formprotection/class.t3lib_formprotection_abstract.php
+++ b/t3lib/formprotection/class.t3lib_formprotection_abstract.php
@@ -35,75 +35,49 @@
  * @subpackage t3lib
  *
  * @author Oliver Klee <typo3-coding@oliverklee.de>
+ * @author Helmut Hummel <helmut.hummel@typo3.org>
  */
 abstract class t3lib_formprotection_Abstract {
 	/**
-	 * the maximum number of tokens that can exist at the same time
+	 * The session token which is used to be hashed during token generation.
 	 *
-	 * @var integer
+	 * @var string
 	 */
-	protected $maximumNumberOfTokens = 0;
+	protected $sessionToken;
 
 	/**
-	 * Valid tokens sorted from oldest to newest.
-	 *
-	 * [tokenId] => array(formName, formInstanceName)
-	 *
-	 * @var array<array>
-	 */
-	protected $tokens = array();
-
-	/**
-	 * Tokens that have been added during this request.
-	 *
-	 * @var array<array>
-	 */
-	protected $addedTokens = array();
-
-	/**
-	 * Token ids of tokens that have been dropped during this request.
-	 *
-	 * @var array
-	 */
-	protected $droppedTokenIds = array();
-
-	/**
-	 * Constructor. Makes sure existing tokens are read and available for
-	 * checking.
+	 * Constructor. Makes sure the session token is read and
+	 * available for checking.
 	 */
 	public function __construct() {
-		$this->tokens = $this->retrieveTokens();
+		$this->retrieveSessionToken();
 	}
 
 	/**
 	 * Frees as much memory as possible.
 	 */
 	public function __destruct() {
-		$this->tokens = array();
+		unset($this->sessionToken);
 	}
 
 	/**
-	 * Deletes all existing tokens and persists the (empty) token table.
+	 * Deletes the session token and persists the (empty) token.
 	 *
 	 * This function is intended to be called when a user logs on or off.
 	 *
 	 * @return void
 	 */
 	public function clean() {
-		$this->tokens = array();
-		$this->persistTokens();
+		unset($this->sessionToken);
+		$this->persistSessionToken();
 	}
 
 	/**
-	 * Generates and stores a token for a form.
+	 * Generates a token for a form by hashing the given parameters
+	 * with the secret session token.
 	 *
 	 * Calling this function two times with the same parameters will create
-	 * two valid, different tokens.
-	 *
-	 * Generating more tokens than $maximumNumberOfEntries will cause the oldest
-	 * tokens to get dropped.
-	 *
-	 * Note: This function does not persist the tokens.
+	 * the same valid token during one user session.
 	 *
 	 * @param string $formName
 	 *		the name of the form, for example a table name like "tt_content",
@@ -126,17 +100,12 @@ abstract class t3lib_formprotection_Abstract {
 			throw new InvalidArgumentException('$formName must not be empty.', 1294586643);
 		}
 
-		do {
-			$tokenId = bin2hex(t3lib_div::generateRandomBytes(16));
-		} while (isset($this->tokens[$tokenId]));
-
-		$this->tokens[$tokenId] = array(
-			'formName' => $formName,
-			'action' => $action,
-			'formInstanceName' => $formInstanceName,
+		$tokenId = t3lib_div::hmac(
+			$formName .
+			$action .
+			$formInstanceName .
+			$this->sessionToken
 		);
-		$this->addedTokens[$tokenId] = $this->tokens[$tokenId];
-		$this->preventOverflow();
 
 		return $tokenId;
 	}
@@ -145,40 +114,33 @@ abstract class t3lib_formprotection_Abstract {
 	 * Checks whether the token $tokenId is valid in the form $formName with
 	 * $formInstanceName.
 	 *
-	 * A token is valid if $tokenId, $formName and $formInstanceName match and
-	 * the token has not been used yet.
-	 *
-	 * Calling this function will mark the token $tokenId as invalud (if it
-	 * exists).
-	 *
-	 * So calling this function with the same parameters two times will return
-	 * FALSE the second time.
-	 *
 	 * @param string $tokenId
-	 *		a form token to check, may also be empty or utterly misformed
+	 *		a form token to check, may also be empty or utterly malformed
 	 * @param string $formName
 	 *		the name of the form to check, for example "tt_content",
-	 *		may also be empty or utterly misformed
+	 *		may also be empty or utterly malformed
 	 * @param string $action
 	 *		the action of the form to check, for example "edit",
-	 *		may also be empty or utterly misformed
+	 *		may also be empty or utterly malformed
 	 * @param string $formInstanceName
 	 *		the instance name of the form to check, for example "42" or "foo"
-	 *		or "31,42", may also be empty or utterly misformed
+	 *		or "31,42", may also be empty or utterly malformed
 	 *
 	 * @return boolean
 	 *		 TRUE if $tokenId, $formName, $action and $formInstanceName match
-	 *		 and the token has not been used yet, FALSE otherwise
 	 */
 	public function validateToken(
 		$tokenId, $formName, $action = '', $formInstanceName = ''
 	) {
-		if (isset($this->tokens[$tokenId])) {
-			$token = $this->tokens[$tokenId];
-			$isValid = ($token['formName'] == $formName)
-					   && ($token['action'] == $action)
-					   && ($token['formInstanceName'] == $formInstanceName);
-			$this->dropToken($tokenId);
+		$validTokenId = t3lib_div::hmac(
+			(string)$formName .
+			(string)$action .
+			(string)$formInstanceName .
+			$this->sessionToken
+		);
+
+		if ((string)$tokenId === $validTokenId) {
+			$isValid = TRUE;
 		} else {
 			$isValid = FALSE;
 		}
@@ -191,92 +153,41 @@ abstract class t3lib_formprotection_Abstract {
 	}
 
 	/**
-	 * Creates or displayes an error message telling the user that the submitted
-	 * form token is invalid.
-	 *
-	 * This function may also be empty if the validation error should be handled
-	 * silently.
-	 *
-	 * @return void
-	 */
-	abstract protected function createValidationErrorMessage();
-
-	/**
-	 * Retrieves all saved tokens.
-	 *
-	 * @return array<arrray>
-	 *		 the saved tokens, will be empty if no tokens have been saved
-	 */
-	abstract protected function retrieveTokens();
-
-	/**
-	 * Saves the tokens so that they can be used by a later incarnation of this
-	 * class.
+	 * Generates the random token which is used in the hash for the form tokens.
 	 *
-	 * @return void
+	 * @return string
 	 */
-	abstract public function persistTokens();
+	protected function generateSessionToken() {
+		return bin2hex(t3lib_div::generateRandomBytes(32));
+	}
 
 	/**
-	 * Drops the token with the ID $tokenId.
-	 *
-	 * If there is no token with that ID, this function is a no-op.
-	 *
-	 * Note: This function does not persist the tokens.
+	 * Creates or displays an error message telling the user that the submitted
+	 * form token is invalid.
 	 *
-	 * @param string $tokenId
-	 *		the 32-character ID of an existing token, must not be empty
+	 * This function may also be empty if the validation error should be handled
+	 * silently.
 	 *
 	 * @return void
 	 */
-	protected function dropToken($tokenId) {
-		if (isset($this->tokens[$tokenId])) {
-			unset($this->tokens[$tokenId]);
-			$this->droppedTokenIds[] = $tokenId;
-		}
-	}
-
-	/**
-	 * Persisting of tokens is only required, if tokens are
-	 * deleted or added during this request.
-	 *
-	 * @return boolean
-	 */
-	protected function isPersistingRequired() {
-		return !empty($this->droppedTokenIds) || !empty($this->addedTokens);
-	}
+	abstract protected function createValidationErrorMessage();
 
 	/**
-	 * Reset the arrays of added or deleted tokens.
+	 * Retrieves the session token.
 	 *
-	 * @return void
+	 * @return string
+	 *		 the saved session token, will be empty if no token has been saved
 	 */
-	protected function resetPersistingRequiredStatus() {
-		$this->droppedTokenIds = array();
-		$this->addedTokens = array();
-	}
+	abstract protected function retrieveSessionToken();
 
 	/**
-	 * Checks whether the number of current tokens still is at most
-	 * $this->maximumNumberOfTokens.
-	 *
-	 * If there are more tokens, the oldest tokens are removed until the number
-	 * of tokens is low enough.
-	 *
-	 * Note: This function does not persist the tokens.
+	 * Saves the session token so that it can be used by a later incarnation
+	 * of this class.
 	 *
+	 * @access private
 	 * @return void
 	 */
-	protected function preventOverflow() {
-		if (empty($this->tokens)) {
-			return;
-		}
-
-		while (count($this->tokens) > $this->maximumNumberOfTokens) {
-			reset($this->tokens);
-			$this->dropToken(key($this->tokens));
-		}
-	}
+	abstract public function persistSessionToken();
 }
 
 ?>
\ No newline at end of file
diff --git a/t3lib/formprotection/class.t3lib_formprotection_backendformprotection.php b/t3lib/formprotection/class.t3lib_formprotection_backendformprotection.php
index 06ad1147b0a01de410994ca62b430d88d0e258d5..045a043356253a714acf50fa64bfa143449dcdc9 100644
--- a/t3lib/formprotection/class.t3lib_formprotection_backendformprotection.php
+++ b/t3lib/formprotection/class.t3lib_formprotection_backendformprotection.php
@@ -3,6 +3,7 @@
  * Copyright notice
  *
  * (c) 2010-2011 Oliver Klee <typo3-coding@oliverklee.de>
+ * (c) 2010-2011 Helmut Hummel <helmut.hummel@typo3.org>
  * All rights reserved
  *
  * This script is part of the TYPO3 project. The TYPO3 project is
@@ -35,9 +36,8 @@
  * matter; you only need it to get the form token for verifying it.
  *
  * <pre>
- * $formToken = t3lib_formprotection_Factory::get(
- *	 t3lib_formprotection_Factory::TYPE_BACK_END
- * )->generateToken(
+ * $formToken = t3lib_formprotection_Factory::get()
+ * 	->generateToken(
  *	 'BE user setup', 'edit'
  * );
  * $this->content .= '<input type="hidden" name="formToken" value="' .
@@ -53,35 +53,20 @@
  * For editing a tt_content record, the call could look like this:
  *
  * <pre>
- * $formToken = t3lib_formprotection_Factory::get(
- *	 t3lib_formprotection_Factory::TYPE_BACK_END
- * )->getFormProtection()->generateToken(
+ * $formToken = t3lib_formprotection_Factory::get()
+ * 	->getFormProtection()->generateToken(
  *	'tt_content', 'edit', $uid
  * );
  * </pre>
  *
- * At the end of the form, you need to persist the tokens. This makes sure that
- * generated tokens get saved, and also that removed tokens stay removed:
- *
- * <pre>
- * t3lib_formprotection_Factory::get(
- *	 t3lib_formprotection_Factory::TYPE_BACK_END
- * )->persistTokens();
- * </pre>
- *
- * In BE lists, it might be necessary to generate hundreds of tokens. So the
- * tokens do not get automatically persisted after creation for performance
- * reasons.
- *
  *
  * When processing the data that has been submitted by the form, you can check
  * that the form token is valid like this:
  *
  * <pre>
- * if ($dataHasBeenSubmitted && t3lib_formprotection_Factory::get(
- *		 t3lib_formprotection_Factory::TYPE_BACK_END
- *	 )->validateToken(
- *		 (string) t3lib_div::_POST('formToken'),
+ * if ($dataHasBeenSubmitted && t3lib_formprotection_Factory::get()
+ * 	->validateToken(
+ *		 t3lib_div::_POST('formToken'),
  *		 'BE user setup', 'edit
  *	 )
  * ) {
@@ -92,27 +77,14 @@
  * }
  * </pre>
  *
- * Note that validateToken invalidates the token with the token ID. So calling
- * validate with the same parameters two times in a row will always return FALSE
- * for the second call.
- *
- * It is important that the tokens get validated <em>before</em> the tokens are
- * persisted. This makes sure that the tokens that get invalidated by
- * validateToken cannot be used again.
  *
  * @package TYPO3
  * @subpackage t3lib
  *
  * @author Oliver Klee <typo3-coding@oliverklee.de>
+ * @author Helmut Hummel <helmut.hummel@typo3.org>
  */
 class t3lib_formprotection_BackendFormProtection extends t3lib_formprotection_Abstract {
-	/**
-	 * the maximum number of tokens that can exist at the same time
-	 *
-	 * @var integer
-	 */
-	protected $maximumNumberOfTokens = 20000;
-
 	/**
 	 * Keeps the instance of the user which existed during creation
 	 * of the object.
@@ -121,6 +93,14 @@ class t3lib_formprotection_BackendFormProtection extends t3lib_formprotection_Ab
 	 */
 	protected $backendUser;
 
+	/**
+	 * Instance of the registry, which is used to permanently persist
+	 * the session token so that it can be restored during re-login.
+	 *
+	 * @var t3lib_Registry
+	 */
+	protected $registry;
+
 	/**
 	 * Only allow construction if we have a backend session
 	 */
@@ -137,34 +117,7 @@ class t3lib_formprotection_BackendFormProtection extends t3lib_formprotection_Ab
 	}
 
 	/**
-	 * Overrule the method in the absract class, because we can drop the
-	 * whole locking procedure, which is done in persistTokens, if we
-	 * simply want to delete all tokens.
-	 *
-	 * @see t3lib/formprotection/t3lib_formprotection_Abstract::clean()
-	 */
-	public function clean() {
-		$this->tokens = array();
-		$this->backendUser->setAndSaveSessionData('formTokens', $this->tokens);
-		$this->resetPersistingRequiredStatus();
-	}
-
-	/**
-	 * Override the abstract class to be able to strip out
-	 * the token id from the POST variable.
-	 *
-	 * @see t3lib/formprotection/t3lib_formprotection_Abstract::validateToken()
-	 */
-	public function validateToken(
-		$token, $formName, $action = '', $formInstanceName = ''
-	) {
-		list($tokenId, $_) = explode('-', (string)$token);
-
-		return parent::validateToken($tokenId, $formName, $action, $formInstanceName);
-	}
-
-	/**
-	 * Creates or displayes an error message telling the user that the submitted
+	 * Creates or displays an error message telling the user that the submitted
 	 * form token is invalid.
 	 *
 	 * @return void
@@ -183,90 +136,89 @@ class t3lib_formprotection_BackendFormProtection extends t3lib_formprotection_Ab
 	}
 
 	/**
-	 * Retrieves all saved tokens.
+	 * Retrieves the saved session token or generates a new one.
 	 *
 	 * @return array<array>
 	 *		 the saved tokens as, will be empty if no tokens have been saved
 	 */
-	protected function retrieveTokens() {
-		$tokens = $this->backendUser->getSessionData('formTokens');
-		if (!is_array($tokens)) {
-			$tokens = array();
+	protected function retrieveSessionToken() {
+		$this->sessionToken = $this->backendUser->getSessionData('formSessionToken');
+		if (empty($this->sessionToken)) {
+			$this->sessionToken = $this->generateSessionToken();
+			$this->persistSessionToken();
 		}
+	}
 
-		return $tokens;
+	/**
+	 * Saves the tokens so that they can be used by a later incarnation of this
+	 * class.
+	 *
+	 * @return void
+	 */
+	public function persistSessionToken() {
+		$this->backendUser->setAndSaveSessionData('formSessionToken', $this->sessionToken);
 	}
 
 	/**
-	 * It might be that two (or more) scripts are executed at the same time,
-	 * which would lead to a race condition, where both (all) scripts retrieve
-	 * the same tokens from the session, so the script that is executed
-	 * last will overwrite the tokens generated in the first scripts.
-	 * So before writing all tokens back to the session we need to get the
-	 * current tokens from the session again.
+	 * Sets the session token for the user from the registry
+	 * and returns it additionally.
 	 *
+	 * @access private
+	 * @return string
 	 */
-	protected function updateTokens() {
-		$this->backendUser->user = $this->backendUser->fetchUserSession(TRUE);
-		$tokens = $this->retrieveTokens();
-		$this->tokens = array_merge($tokens, $this->addedTokens);
-		foreach ($this->droppedTokenIds as $tokenId) {
-			unset($this->tokens[$tokenId]);
+	public function setSessionTokenFromRegistry() {
+		$this->sessionToken = $this->getRegistry()
+				->get('core', 'formSessionToken:' . $this->backendUser->user['uid']);
+		if (empty($this->sessionToken)) {
+			throw new UnexpectedValueException('Failed to restore the session token from the registry.', 1301827270);
 		}
+		return $this->sessionToken;
 	}
 
 	/**
-	 * Saves the tokens so that they can be used by a later incarnation of this
-	 * class.
+	 * Stores the session token in the registry to have it
+	 * available during re-login of the user.
 	 *
+	 * @access private
 	 * @return void
 	 */
-	public function persistTokens() {
-		if ($this->isPersistingRequired()) {
-			$lockObject = $this->acquireLock();
-
-			$this->updateTokens();
-			$this->backendUser->setAndSaveSessionData('formTokens', $this->tokens);
-			$this->resetPersistingRequiredStatus();
-
-			$this->releaseLock($lockObject);
-		}
+	public function storeSessionTokenInRegistry() {
+		$this->getRegistry()
+				->set('core', 'formSessionToken:' . $this->backendUser->user['uid'], $this->sessionToken);
 	}
 
 	/**
-	 * Tries to acquire a lock to not allow a race condition.
+	 * Removes the session token for the user from the registry.
 	 *
-	 * @return t3lib_lock|FALSE The lock object or FALSE
+	 * @access private
+	 * @return string
 	 */
-	protected function acquireLock() {
-		$identifier = 'persistTokens' . $this->backendUser->id;
-		try {
-			/** @var t3lib_lock $lockObject */
-			$lockObject = t3lib_div::makeInstance('t3lib_lock', $identifier, 'simple');
-			$lockObject->setEnableLogging(FALSE);
-			$success = $lockObject->acquire();
-		} catch (Exception $e) {
-			t3lib_div::sysLog('Locking: Failed to acquire lock: '.$e->getMessage(), 't3lib_formprotection_BackendFormProtection', t3lib_div::SYSLOG_SEVERITY_ERROR);
-			$success = FALSE;	// If locking fails, return with false and continue without locking
-		}
-
-		return $success ? $lockObject : FALSE;
+	public function removeSessionTokenFromRegistry() {
+		return $this->getRegistry()
+				->remove('core', 'formSessionToken:' . $this->backendUser->user['uid']);
 	}
 
 	/**
-	 * Releases the lock if it was acquired before.
+	 * Returns the instance of the registry.
 	 *
-	 * @return boolean
+	 * @return t3lib_Registry
 	 */
-	protected function releaseLock(&$lockObject) {
-		$success = FALSE;
-			// If lock object is set and was acquired, release it:
-		if (is_object($lockObject) && $lockObject instanceof t3lib_lock && $lockObject->getLockStatus()) {
-			$success = $lockObject->release();
-			$lockObject = NULL;
+	protected function getRegistry() {
+		if (!$this->registry instanceof t3lib_Registry) {
+			$this->registry = t3lib_div::makeInstance('t3lib_Registry');
 		}
+		return $this->registry;
+	}
 
-		return $success;
+	/**
+	 * Inject the registry. Currently only used in unit tests.
+	 *
+	 * @access private
+	 * @param  t3lib_Registry $registry
+	 * @return void
+	 */
+	public function injectRegistry(t3lib_Registry $registry) {
+		$this->registry = $registry;
 	}
 
 	/**
diff --git a/t3lib/formprotection/class.t3lib_formprotection_disabledformprotection.php b/t3lib/formprotection/class.t3lib_formprotection_disabledformprotection.php
index 18c878dc173b8056974e5401e97c430dc74a12ec..dff5a89c5cb195d26ed1a3e450cefc025c32cb60 100644
--- a/t3lib/formprotection/class.t3lib_formprotection_disabledformprotection.php
+++ b/t3lib/formprotection/class.t3lib_formprotection_disabledformprotection.php
@@ -73,14 +73,14 @@ class t3lib_formprotection_DisabledFormProtection extends t3lib_formprotection_A
 	/**
 	 * Dummy implementation
 	 */
-	protected function retrieveTokens() {
+	protected function retrieveSessionToken() {
 		// Do nothing.
 	}
 
 	/**
 	 * Dummy implementation
 	 */
-	public function persistTokens() {
+	public function persistSessionToken() {
 		// Do nothing.
 	}
 }
diff --git a/t3lib/formprotection/class.t3lib_formprotection_factory.php b/t3lib/formprotection/class.t3lib_formprotection_factory.php
index c7ad85bdb4db103ce92d9f7ff2eced2e494836d9..062092a05f1c3e46a8bbec3492d433440d1242fa 100644
--- a/t3lib/formprotection/class.t3lib_formprotection_factory.php
+++ b/t3lib/formprotection/class.t3lib_formprotection_factory.php
@@ -33,17 +33,13 @@
  * Usage for the back-end form protection:
  *
  * <pre>
- * $formProtection = t3lib_formprotection_Factory::get(
- *	 't3lib_formProtection_BackEnd'
- * );
+ * $formProtection = t3lib_formprotection_Factory::get();
  * </pre>
  *
  * Usage for the install tool form protection:
  *
  * <pre>
- * $formProtection = t3lib_formprotection_Factory::get(
- *	 'tx_install_formprotection'
- * );
+ * $formProtection = t3lib_formprotection_Factory::get();
  * $formProtection->injectInstallTool($this);
  * </pre>
  *
@@ -52,6 +48,7 @@
  *
  * @author Oliver Klee <typo3-coding@oliverklee.de>
  * @author Ernesto Baschny <ernst@cron-it.de>
+ * @author Helmut Hummel <helmut.hummel@typo3.org>
  */
 final class t3lib_formprotection_Factory {
 	/**
@@ -71,7 +68,8 @@ final class t3lib_formprotection_Factory {
 	 * Gets a form protection instance for the requested class $className.
 	 *
 	 * If there already is an existing instance of the requested $className, the
-	 * existing instance will be returned.
+	 * existing instance will be returned. If no $className is provided, the factory
+	 * detects the scope and returns the appropriate form protection object.
 	 *
 	 * @param string $className
 	 *		the name of the class for which to return an instance, must be
@@ -90,7 +88,7 @@ final class t3lib_formprotection_Factory {
 	}
 
 	/**
-	 * Returns the classname depending on TYPO3_MODE and
+	 * Returns the class name depending on TYPO3_MODE and
 	 * active backend session.
 	 *
 	 * @return string
@@ -128,7 +126,7 @@ final class t3lib_formprotection_Factory {
 		return (isset($GLOBALS['BE_USER']) &&
 			$GLOBALS['BE_USER'] instanceof t3lib_beUserAuth &&
 			isset($GLOBALS['BE_USER']->user['uid']) &&
-			!(TYPO3_MODE == 'FE')
+			!(TYPO3_MODE === 'FE')
 		);
 	}
 
@@ -141,12 +139,12 @@ final class t3lib_formprotection_Factory {
 		return (is_object($GLOBALS['TSFE']) &&
 			$GLOBALS['TSFE']->fe_user instanceof tslib_feUserAuth &&
 			isset($GLOBALS['TSFE']->fe_user->user['uid']) &&
-			(TYPO3_MODE == 'FE')
+			(TYPO3_MODE === 'FE')
 		);
 	}
 
 	/**
-	 * Creates an instace for the requested class $className
+	 * Creates an instance for the requested class $className
 	 * and stores it internally.
 	 *
 	 * @param string $className
@@ -182,6 +180,7 @@ final class t3lib_formprotection_Factory {
 	 *
 	 * Note: This function is intended for testing purposes only.
 	 *
+	 * @access private
 	 * @param string $className
 	 *		the name of the class for which to set an instance, must be
 	 *		"t3lib_formProtection_BackEnd" or "t3lib_formprotection_InstallToolFormProtection"
diff --git a/t3lib/formprotection/class.t3lib_formprotection_installtoolformprotection.php b/t3lib/formprotection/class.t3lib_formprotection_installtoolformprotection.php
index d764b086cf3320014d6aedae9e664077e20ef9e6..09216333a3eb18fb66a5f5eeb4b7fe496aa4e78e 100644
--- a/t3lib/formprotection/class.t3lib_formprotection_installtoolformprotection.php
+++ b/t3lib/formprotection/class.t3lib_formprotection_installtoolformprotection.php
@@ -47,20 +47,12 @@
  * possible. For different forms (e.g. the password change and editing a the
  * configuration), those values should be different.
  *
- * At the end of the form, you need to persist the tokens. This makes sure that
- * generated tokens get saved, and also that removed tokens stay removed:
- *
- * <pre>
- * $this->formProtection()->persistTokens();
- * </pre>
- *
- *
  * When processing the data that has been submitted by the form, you can check
  * that the form token is valid like this:
  *
  * <pre>
  * if ($dataHasBeenSubmitted && $this->formProtection()->validateToken(
- *	 (string) $_POST['formToken'],
+ *	 $_POST['formToken'],
  *	 'installToolPassword',
  *	 'change'
  * ) {
@@ -71,13 +63,6 @@
  * }
  * </pre>
  *
- * Note that validateToken invalidates the token with the token ID. So calling
- * validate with the same parameters two times in a row will always return FALSE
- * for the second call.
- *
- * It is important that the tokens get validated <em>before</em> the tokens are
- * persisted. This makes sure that the tokens that get invalidated by
- * validateToken cannot be used again.
  *
  * @package TYPO3
  * @subpackage t3lib
@@ -85,13 +70,6 @@
  * @author Oliver Klee <typo3-coding@oliverklee.de>
  */
 class t3lib_formprotection_InstallToolFormProtection extends t3lib_formProtection_Abstract {
-	/**
-	 * the maximum number of tokens that can exist at the same time
-	 *
-	 * @var integer
-	 */
-	protected $maximumNumberOfTokens = 100;
-
 	/**
 	 * an instance of the install tool used for displaying messages
 	 *
@@ -134,20 +112,19 @@ class t3lib_formprotection_InstallToolFormProtection extends t3lib_formProtectio
 	}
 
 	/**
-	 * Retrieves all saved tokens.
+	 * Retrieves or generates the session token.
 	 *
-	 * @return array<array>
-	 *		 the saved tokens, will be empty if no tokens have been saved
+	 * @return void
 	 */
-	protected function retrieveTokens() {
-		if (isset($_SESSION['installToolFormTokens'])
-			&& is_array($_SESSION['installToolFormTokens'])
+	protected function retrieveSessionToken() {
+		if (isset($_SESSION['installToolFormToken'])
+			&& !empty($_SESSION['installToolFormToken'])
 		) {
-			$tokens = $_SESSION['installToolFormTokens'];
+			$this->sessionToken = $_SESSION['installToolFormToken'];
 		} else {
-			$tokens = array();
+			$this->sessionToken = $this->generateSessionToken();
+			$this->persistSessionToken();
 		}
-		return $tokens;
 	}
 
 	/**
@@ -156,8 +133,8 @@ class t3lib_formprotection_InstallToolFormProtection extends t3lib_formProtectio
 	 *
 	 * @return void
 	 */
-	public function persistTokens() {
-		$_SESSION['installToolFormTokens'] = $this->tokens;
+	public function persistSessionToken() {
+		$_SESSION['installToolFormToken'] = $this->sessionToken;
 	}
 }
 
diff --git a/tests/t3lib/formprotection/class.t3lib_formprotection_AbstractTest.php b/tests/t3lib/formprotection/class.t3lib_formprotection_AbstractTest.php
index fc276110bcebbc3560033fc158a5350fbee18c3e..2b3e3581ce3e42743ee5a2688b6820ed3099153d 100644
--- a/tests/t3lib/formprotection/class.t3lib_formprotection_AbstractTest.php
+++ b/tests/t3lib/formprotection/class.t3lib_formprotection_AbstractTest.php
@@ -55,13 +55,13 @@ class t3lib_formprotection_AbstractTest extends tx_phpunit_testcase {
 	/**
 	 * @test
 	 */
-	public function constructionRetrievesTokens() {
+	public function constructionRetrievesToken() {
 		$className = uniqid('t3lib_formProtection');
 		eval(
 			'class ' . $className . ' extends t3lib_formProtection_Testing {' .
-				'public $tokensHaveBeenRetrieved = FALSE; ' .
-				'protected function retrieveTokens() {' .
-				'$this->tokensHaveBeenRetrieved = TRUE;' .
+				'public $tokenHasBeenRetrieved = FALSE; ' .
+				'protected function retrieveSessionToken() {' .
+				'$this->tokenHasBeenRetrieved = TRUE;' .
 				'}' .
 			'}'
 		);
@@ -69,7 +69,7 @@ class t3lib_formprotection_AbstractTest extends tx_phpunit_testcase {
 		$fixture = new $className();
 
 		$this->assertTrue(
-			$fixture->tokensHaveBeenRetrieved
+			$fixture->tokenHasBeenRetrieved
 		);
 	}
 
@@ -90,11 +90,11 @@ class t3lib_formprotection_AbstractTest extends tx_phpunit_testcase {
 	/**
 	 * @test
 	 */
-	public function cleanPersistsTokens() {
+	public function cleanPersistsToken() {
 		$fixture = $this->getMock(
-			't3lib_formProtection_Testing', array('persistTokens')
+			't3lib_formProtection_Testing', array('persistSessionToken')
 		);
-		$fixture->expects($this->once())->method('persistTokens');
+		$fixture->expects($this->once())->method('persistSessionToken');
 
 		$fixture->clean();
 	}
@@ -141,7 +141,7 @@ class t3lib_formprotection_AbstractTest extends tx_phpunit_testcase {
 	 */
 	public function generateTokenReturns32CharacterHexToken() {
 		$this->assertRegexp(
-			'/^[0-9a-f]{32}$/',
+			'/^[0-9a-f]{40}$/',
 			$this->fixture->generateToken('foo')
 		);
 	}
@@ -149,66 +149,13 @@ class t3lib_formprotection_AbstractTest extends tx_phpunit_testcase {
 	/**
 	 * @test
 	 */
-	public function generateTokenCalledTwoTimesWithSameParametersReturnsDifferentTokens() {
-		$this->assertNotEquals(
+	public function generateTokenCalledTwoTimesWithSameParametersReturnsSameTokens() {
+		$this->assertEquals(
 			$this->fixture->generateToken('foo', 'edit', 'bar'),
 			$this->fixture->generateToken('foo', 'edit', 'bar')
 		);
 	}
 
-	/**
-	 * @test
-	 */
-	public function generatingTooManyTokensInvalidatesOldestToken() {
-		$this->fixture->setMaximumNumberOfTokens(2);
-
-		$formName = 'foo';
-
-		$token1 = $this->fixture->generateToken($formName);
-		$token2 = $this->fixture->generateToken($formName);
-		$token3 = $this->fixture->generateToken($formName);
-
-		$this->assertFalse(
-			$this->fixture->validateToken($token1, $formName)
-		);
-	}
-
-	/**
-	 * @test
-	 */
-	public function generatingTooManyTokensNotInvalidatesNewestToken() {
-		$this->fixture->setMaximumNumberOfTokens(2);
-
-		$formName = 'foo';
-		$formInstanceName = 'bar';
-
-		$token1 = $this->fixture->generateToken($formName);
-		$token2 = $this->fixture->generateToken($formName);
-		$token3 = $this->fixture->generateToken($formName);
-
-		$this->assertTrue(
-			$this->fixture->validateToken($token3, $formName)
-		);
-	}
-
-	/**
-	 * @test
-	 */
-	public function generatingTooManyTokensNotInvalidatesTokenInTheMiddle() {
-		$this->fixture->setMaximumNumberOfTokens(2);
-
-		$formName = 'foo';
-		$formInstanceName = 'bar';
-
-		$token1 = $this->fixture->generateToken($formName);
-		$token2 = $this->fixture->generateToken($formName);
-		$token3 = $this->fixture->generateToken($formName);
-
-		$this->assertTrue(
-			$this->fixture->validateToken($token2, $formName)
-		);
-	}
-
 
 	///////////////////////////////////
 	// Tests concerning validateToken
@@ -262,24 +209,7 @@ class t3lib_formprotection_AbstractTest extends tx_phpunit_testcase {
 	/**
 	 * @test
 	 */
-	public function validateTokenWithValidDataDropsToken() {
-		$formName = 'foo';
-
-		$fixture = $this->getMock(
-			't3lib_formProtection_Testing', array('dropToken')
-		);
-
-		$tokenId = $fixture->generateToken($formName);
-		$fixture->expects($this->once())->method('dropToken')
-			->with($tokenId);
-
-		$fixture->validateToken($tokenId, $formName);
-	}
-
-	/**
-	 * @test
-	 */
-	public function validateTokenWithValidDataCalledTwoTimesReturnsFalseOnSecondCall() {
+	public function validateTokenWithValidDataCalledTwoTimesReturnsTrueOnSecondCall() {
 		$formName = 'foo';
 		$action = 'edit';
 		$formInstanceName = 'bar';
@@ -288,7 +218,7 @@ class t3lib_formprotection_AbstractTest extends tx_phpunit_testcase {
 
 		$this->fixture->validateToken($tokenId, $formName, $action, $formInstanceName);
 
-		$this->assertFalse(
+		$this->assertTrue(
 			$this->fixture->validateToken($tokenId, $formName, $action, $formInstanceName)
 		);
 	}
@@ -361,52 +291,6 @@ class t3lib_formprotection_AbstractTest extends tx_phpunit_testcase {
 		);
 	}
 
-	/**
-	 * @test
-	 */
-	public function validateTokenWithTwoTokensForSameFormNameAndActionAndFormInstanceNameReturnsTrueForBoth() {
-		$formName = 'foo';
-		$action = 'edit';
-		$formInstanceName = 'bar';
-
-		$tokenId1 = $this->fixture->generateToken($formName, $action, $formInstanceName);
-		$tokenId2 = $this->fixture->generateToken($formName, $action, $formInstanceName);
-
-		$this->assertTrue(
-			$this->fixture->validateToken(
-				$tokenId1, $formName, $action, $formInstanceName
-			)
-		);
-		$this->assertTrue(
-			$this->fixture->validateToken(
-				$tokenId2, $formName, $action, $formInstanceName
-			)
-		);
-	}
-
-	/**
-	 * @test
-	 */
-	public function validateTokenWithTwoTokensForSameFormNameAndActionAndFormInstanceNameCalledInReverseOrderReturnsTrueForBoth() {
-		$formName = 'foo';
-		$action = 'edit';
-		$formInstanceName = 'bar';
-
-		$tokenId1 = $this->fixture->generateToken($formName, $action, $formInstanceName);
-		$tokenId2 = $this->fixture->generateToken($formName, $action, $formInstanceName);
-
-		$this->assertTrue(
-			$this->fixture->validateToken(
-				$tokenId2, $formName, $action, $formInstanceName
-			)
-		);
-		$this->assertTrue(
-			$this->fixture->validateToken(
-				$tokenId1, $formName, $action, $formInstanceName
-			)
-		);
-	}
-
 	/**
 	 * @test
 	 */
diff --git a/tests/t3lib/formprotection/class.t3lib_formprotection_BackendFormProtectionTest.php b/tests/t3lib/formprotection/class.t3lib_formprotection_BackendFormProtectionTest.php
index 38374f464403f5f8ea266b19d960939fe18fed85..7c158be6b07d9207f679c6e0743ceebfb02d63f1 100644
--- a/tests/t3lib/formprotection/class.t3lib_formprotection_BackendFormProtectionTest.php
+++ b/tests/t3lib/formprotection/class.t3lib_formprotection_BackendFormProtectionTest.php
@@ -83,11 +83,11 @@ class t3lib_formprotection_BackendFormProtectionTest extends tx_phpunit_testcase
 				'  public function createValidationErrorMessage() {' .
 				'    parent::createValidationErrorMessage();' .
 				'  }' .
-				'  public function updateTokens() {' .
-				'    return parent::updateTokens();' .
+				'  public function retrieveSessionToken() {' .
+				'    return parent::retrieveSessionToken();' .
 				'  }' .
-				'  public function retrieveTokens() {' .
-				'    return parent::retrieveTokens();' .
+				'  public function setSessionToken($sessionToken) {' .
+				'    $this->sessionToken = $sessionToken;' .
 				'  }' .
 				'}'
 			);
@@ -162,93 +162,57 @@ class t3lib_formprotection_BackendFormProtectionTest extends tx_phpunit_testcase
 	/**
 	 * @test
 	 */
-	public function retrieveTokensReadsTokensFromSessionData() {
+	public function retrieveTokenReadsTokenFromSessionData() {
 		$GLOBALS['BE_USER']->expects($this->once())->method('getSessionData')
-			->with('formTokens')->will($this->returnValue(array()));
+			->with('formSessionToken')->will($this->returnValue(array()));
 
-		$this->fixture->retrieveTokens();
+		$this->fixture->retrieveSessionToken();
 	}
 
 	/**
 	 * @test
 	 */
-	public function tokensFromSessionDataAreAvailableForValidateToken() {
-		$tokenId = '51a655b55c54d54e5454c5f521f6552a';
+	public function tokenFromSessionDataIsAvailableForValidateToken() {
+		$sessionToken = '881ffea2159ac72182557b79dc0c723f5a8d20136f9fab56cdd4f8b3a1dbcfcd';
 		$formName = 'foo';
 		$action = 'edit';
 		$formInstanceName = '42';
 
+		$tokenId = t3lib_div::hmac($formName . $action . $formInstanceName . $sessionToken);
+
 		$GLOBALS['BE_USER']->expects($this->atLeastOnce())->method('getSessionData')
-			->with('formTokens')
-			->will($this->returnValue(array(
-				$tokenId => array(
-					'formName' => $formName,
-					'action' => $action,
-					'formInstanceName' => $formInstanceName,
-				),
-			)));
+			->with('formSessionToken')
+			->will($this->returnValue($sessionToken));
 
-		$this->fixture->updateTokens();
+		$this->fixture->retrieveSessionToken();
 
 		$this->assertTrue(
-			$this->fixture->validateToken($tokenId, $formName, $action,  $formInstanceName)
+			$this->fixture->validateToken($tokenId, $formName, $action, $formInstanceName)
 		);
 	}
 
 	/**
+	 * @expectedException UnexpectedValueException
 	 * @test
 	 */
-	public function tokensStayDroppedAfterPersistingTokens() {
-		$tokenId = '51a655b55c54d54e5454c5f521f6552a';
-		$formName = 'foo';
-		$action = 'edit';
-		$formInstanceName = '42';
-
-		$GLOBALS['BE_USER']->expects($this->atLeastOnce())->method('getSessionData')
-			->will($this->returnValue(array(
-				$tokenId => array(
-					'formName' => $formName,
-					'action' => $action,
-					'formInstanceName' => $formInstanceName,
-				),
-			)));
-
-		$className = $this->createAccessibleProxyClass();
-
-		$this->fixture->updateTokens();
-
-		$this->fixture->validateToken($tokenId, $formName, $action,  $formInstanceName);
-
-		$this->fixture->persistTokens();
-
-		$this->assertFalse(
-			$this->fixture->validateToken($tokenId, $formName, $action,  $formInstanceName)
+	public function restoreSessionTokenFromRegistryThrowsExceptionIfSessionTokenIsEmpty() {
+		$this->fixture->injectRegistry(
+			$this->getMock('t3lib_Registry')
 		);
+		$this->fixture->setSessionTokenFromRegistry();
 	}
 
 	/**
 	 * @test
 	 */
-	public function persistTokensWritesTokensToSession() {
-		$formName = 'foo';
-		$action = 'edit';
-		$formInstanceName = '42';
-
-		$tokenId = $this->fixture->generateToken(
-			$formName, $action, $formInstanceName
-		);
-		$allTokens = array(
-			$tokenId => array(
-					'formName' => $formName,
-					'action' => $action,
-					'formInstanceName' => $formInstanceName,
-				),
-		);
+	public function persistSessionTokenWritesTokenToSession() {
+		$sessionToken = '881ffea2159ac72182557b79dc0c723f5a8d20136f9fab56cdd4f8b3a1dbcfcd';
+		$this->fixture->setSessionToken($sessionToken);
 
 		$GLOBALS['BE_USER']->expects($this->once())
-			->method('setAndSaveSessionData')->with('formTokens', $allTokens);
+			->method('setAndSaveSessionData')->with('formSessionToken', $sessionToken);
 
-		$this->fixture->persistTokens();
+		$this->fixture->persistSessionToken();
 	}
 
 
diff --git a/tests/t3lib/formprotection/class.t3lib_formprotection_InstallToolFormProtectionTest.php b/tests/t3lib/formprotection/class.t3lib_formprotection_InstallToolFormProtectionTest.php
index f3966790d71e38e1b4275e4cc4f752ea0d017b9a..8dc593d9854473e845fd95b14a5ba1c941daceeb 100644
--- a/tests/t3lib/formprotection/class.t3lib_formprotection_InstallToolFormProtectionTest.php
+++ b/tests/t3lib/formprotection/class.t3lib_formprotection_InstallToolFormProtectionTest.php
@@ -77,11 +77,12 @@ class t3lib_formprotection_InstallToolFormProtectionTest extends tx_phpunit_test
 		if (!class_exists($className)) {
 			eval(
 				'class ' . $className . ' extends t3lib_formprotection_InstallToolFormProtection {' .
+				'  public $sessionToken;' .
 				'  public function createValidationErrorMessage() {' .
 				'    parent::createValidationErrorMessage();' .
 				'  }' .
-				'  public function retrieveTokens() {' .
-				'    return $this->tokens = parent::retrieveTokens();' .
+				'  public function retrieveSessionToken() {' .
+				'    parent::retrieveSessionToken();' .
 				'  }' .
 				'}'
 			);
@@ -114,52 +115,36 @@ class t3lib_formprotection_InstallToolFormProtectionTest extends tx_phpunit_test
 	/**
 	 * @test
 	 */
-	public function tokensFromSessionDataAreAvailableForValidateToken() {
-		$tokenId = '51a655b55c54d54e5454c5f521f6552a';
+	public function tokenFromSessionDataIsAvailableForValidateToken() {
+		$sessionToken = '881ffea2159ac72182557b79dc0c723f5a8d20136f9fab56cdd4f8b3a1dbcfcd';
 		$formName = 'foo';
 		$action = 'edit';
 		$formInstanceName = '42';
 
-		$_SESSION['installToolFormTokens'] = array(
-			$tokenId => array(
-				'formName' => $formName,
-				'action' => $action,
-				'formInstanceName' => $formInstanceName,
-			),
-		);
+		$tokenId = t3lib_div::hmac($formName . $action . $formInstanceName . $sessionToken);
+
+		$_SESSION['installToolFormToken'] = $sessionToken;
 
-		$this->fixture->retrieveTokens();
+		$this->fixture->retrieveSessionToken();
 
 		$this->assertTrue(
-			$this->fixture->validateToken(
-				$tokenId, $formName, $action,  $formInstanceName
-			)
+			$this->fixture->validateToken($tokenId, $formName, $action, $formInstanceName)
 		);
 	}
 
 	/**
 	 * @test
 	 */
-	public function persistTokensWritesTokensToSession() {
-		$formName = 'foo';
-		$action = 'edit';
-		$formInstanceName = '42';
+	public function persistSessionTokenWritesTokensToSession() {
+		$_SESSION['installToolFormToken'] = 'foo';
 
-		$tokenId = $this->fixture->generateToken(
-			$formName, $action, $formInstanceName
-		);
+		$this->fixture->sessionToken = '881ffea2159ac72182557b79dc0c723f5a8d20136f9fab56cdd4f8b3a1dbcfcd';
 
-		$this->fixture->persistTokens();
+		$this->fixture->persistSessionToken();
 
 		$this->assertEquals(
-			array(
-				$tokenId => array(
-						'formName' => $formName,
-						'action' => $action,
-						'formInstanceName' => $formInstanceName,
-					),
-			),
-			$_SESSION['installToolFormTokens']
+			'881ffea2159ac72182557b79dc0c723f5a8d20136f9fab56cdd4f8b3a1dbcfcd',
+			$_SESSION['installToolFormToken']
 		);
 	}
 
diff --git a/tests/t3lib/formprotection/fixtures/class.t3lib_formprotection_testing.php b/tests/t3lib/formprotection/fixtures/class.t3lib_formprotection_testing.php
index 0c472c9f8eac7c8ea8642b0e4a6f688a863da1fc..2ce5c85ae2a71c5f5148cbad04a643733f2f3614 100644
--- a/tests/t3lib/formprotection/fixtures/class.t3lib_formprotection_testing.php
+++ b/tests/t3lib/formprotection/fixtures/class.t3lib_formprotection_testing.php
@@ -34,24 +34,6 @@
  * @author Oliver Klee <typo3-coding@oliverklee.de>
  */
 class t3lib_formProtection_Testing extends t3lib_formprotection_Abstract {
-	/**
-	 * the maximum number of tokens that can exist at the same time
-	 *
-	 * @var integer
-	 */
-	protected $maximumNumberOfTokens = 100;
-
-	/**
-	 * Sets the maximum number of tokens that can exist at the same time.
-	 *
-	 * @param integer $number maximum number of tokens, must be > 0
-	 *
-	 * @return void
-	 */
-	public function setMaximumNumberOfTokens($number) {
-		$this->maximumNumberOfTokens = $number;
-	}
-
 	/**
 	 * Creates or displayes an error message telling the user that the submitted
 	 * form token is invalid.
@@ -66,7 +48,9 @@ class t3lib_formProtection_Testing extends t3lib_formprotection_Abstract {
 	 * @return array the saved tokens as a two-dimensional array, will be empty
 	 *               if no tokens have been saved
 	 */
-	protected function retrieveTokens() {}
+	protected function retrieveSessionToken() {
+		$this->sessionToken = $this->generateSessionToken();
+	}
 
 	/**
 	 * Saves the tokens so that they can be used by a later incarnation of this
@@ -74,21 +58,7 @@ class t3lib_formProtection_Testing extends t3lib_formprotection_Abstract {
 	 *
 	 * @return void
 	 */
-	public function persistTokens() {}
-
-	/**
-	 * Drops the token with the ID $tokenId and persists all tokens.
-	 *
-	 * If there is no token with that ID, this function is a no-op.
-	 *
-	 * @param string $tokenId
-	 *        the 32-character ID of an existing token, must not be empty
-	 *
-	 * @return void
-	 */
-	public function dropToken($tokenId) {
-		parent::dropToken($tokenId);
-	}
+	public function persistSessionToken() {}
 }
 
 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/formprotection/class.t3lib_formprotection_testing.php'])) {
diff --git a/typo3/alt_clickmenu.php b/typo3/alt_clickmenu.php
index de22429ea222cb004abf6bcd7a27e798a34dcb7f..66556604317bcd7a4837dd9756a1cb3098c9b2fd 100644
--- a/typo3/alt_clickmenu.php
+++ b/typo3/alt_clickmenu.php
@@ -1763,7 +1763,6 @@ class SC_alt_clickmenu {
 			$this->content = $this->doc->insertStylesAndJS($this->content);
 			echo $this->content;
 		} else {
-			t3lib_formprotection_Factory::get()->persistTokens();
 			$this->content = $GLOBALS['LANG']->csConvObj->utf8_encode($this->content,$GLOBALS['LANG']->charSet);
 			t3lib_ajax::outputXMLreply($this->content);
 		}
diff --git a/typo3/classes/class.ajaxlogin.php b/typo3/classes/class.ajaxlogin.php
index 001fe6b8fd25edcfad5956649936c71ec16c72c7..ec86bdcf38deb861832fdae60f8b2c91455e8c6a 100644
--- a/typo3/classes/class.ajaxlogin.php
+++ b/typo3/classes/class.ajaxlogin.php
@@ -45,11 +45,10 @@ class AjaxLogin {
 	public function login(array $parameters, TYPO3AJAX $ajaxObj) {
 		if ($this->isAuthorizedBackendSession()) {
 			$json = array('success' => TRUE);
-			$token = '';
 			if ($this->hasLoginBeenProcessed()) {
-				$formprotection = t3lib_formprotection_Factory::get();
-				$json['accessToken'] = $formprotection->generateToken('refreshTokens');
-				$formprotection->persistTokens();
+				$formProtection = t3lib_formprotection_Factory::get();
+				$formProtection->setSessionTokenFromRegistry();
+				$formProtection->persistSessionToken();
 			}
 		} else {
 			$json = array('success' => FALSE);
@@ -68,7 +67,7 @@ class AjaxLogin {
 	}
 
 	/**
-	 * Check whether the user was not already authorized
+	 * Check whether the user was already authorized or not
 	 *
 	 * @return boolean
 	 */
@@ -164,43 +163,6 @@ class AjaxLogin {
 		$parent->addContent('challenge', $_SESSION['login_challenge']);
 		$parent->setContentFormat('json');
 	}
-
-	/**
-	 * Generates new tokens for the ones found in the DOM.
-	 *
-	 * @param	array		$parameters: Parameters (not used)
-	 * @param	TYPO3AJAX	$parent: The calling parent AJAX object
-	 */
-	public function refreshTokens(array $parameters, TYPO3AJAX $parent) {
-		$accessToken = (string)t3lib_div::_GP('accessToken');
-		$formprotection = t3lib_formprotection_Factory::get();
-
-		if ($formprotection->validateToken($accessToken, 'refreshTokens')) {
-			$oldTokens = json_decode((string)t3lib_div::_GP('tokens'));
-			$regeneratedTokens = new stdClass();
-
-			foreach ($oldTokens as $oldToken) {
-				$newToken = $this->generateNewToken($oldToken);
-				$regeneratedTokens->$oldToken = $newToken;
-			}
-		}
-		$parent->addContent('newTokens', $regeneratedTokens);
-		$parent->setContentFormat('json');
-
-		$formprotection->persistTokens();
-	}
-
-	/**
-	 * Generate new token.
-	 *
-	 * @param string $oldToken
-	 * @return string regenerated Token
-	 */
-	protected function generateNewToken($oldToken) {
-		list ($tokenId, $formName) = explode('-', $oldToken);
-		return t3lib_formprotection_Factory::get()->generateToken($formName) . '-' . $formName;
-	}
-
 }
 
 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/classes/class.ajaxlogin.php'])) {
diff --git a/typo3/classes/class.clearcachemenu.php b/typo3/classes/class.clearcachemenu.php
index 96b135a650b9c20d2c8e26a117750719ccd44063..3abdb741de3c15949a3d8fbd72baa02ec352f556 100644
--- a/typo3/classes/class.clearcachemenu.php
+++ b/typo3/classes/class.clearcachemenu.php
@@ -112,8 +112,6 @@ class ClearCacheMenu implements backend_toolbarItem {
 				$hookObject->manipulateCacheActions($this->cacheActions, $this->optionValues);
 			}
 		}
-
-		t3lib_formprotection_Factory::get()->persistTokens();
 	}
 
 	/**
diff --git a/typo3/index.php b/typo3/index.php
index e9891cfffc89138e0910f0ce27c490a9ea291441..2b7fb7bea126f9581261215e539f1b4b5a3fd8ae 100644
--- a/typo3/index.php
+++ b/typo3/index.php
@@ -392,13 +392,14 @@ class SC_index {
 				break;
 			}
 
+			$formProtection = t3lib_formprotection_Factory::get();
 				// If there is a redirect URL AND if loginRefresh is not set...
 			if (!$this->loginRefresh)	{
+				$formProtection->storeSessionTokenInRegistry();
 				t3lib_utility_Http::redirect($this->redirectToURL);
 			} else {
-				$formprotection = t3lib_formprotection_Factory::get();
-				$accessToken = $formprotection->generateToken('refreshTokens');
-				$formprotection->persistTokens();
+				$formProtection->setSessionTokenFromRegistry();
+				$formProtection->persistSessionToken();
 				$TBE_TEMPLATE->JScode.=$TBE_TEMPLATE->wrapScriptTags('
 					if (parent.opener && (parent.opener.busy || parent.opener.TYPO3.loginRefresh)) {
 						if (parent.opener.TYPO3.loginRefresh) {
@@ -406,7 +407,6 @@ class SC_index {
 						} else {
 							parent.opener.busy.loginRefreshed();
 						}
-						parent.opener.TYPO3.loginRefresh.refreshTokens("' . $accessToken . '");
 						parent.close();
 					}
 				');
diff --git a/typo3/js/clearcachemenu.js b/typo3/js/clearcachemenu.js
index 0a7c6534b59d078e04235e0f66de236723e042ac..25b30f9d96068dfe3595b5a5579889da4bfcf737 100644
--- a/typo3/js/clearcachemenu.js
+++ b/typo3/js/clearcachemenu.js
@@ -96,10 +96,6 @@ var ClearCacheMenu = Class.create({
 				'method': 'get',
 				'onComplete': function(result) {
 					spinner.replace(oldIcon);
-						// replace used token with new one
-					if (result.responseText.length > 0) {
-						link.href = link.href.substr(0, link.href.length - result.responseText.length) + result.responseText
-					}
 				}.bind(this)
 			});
 		}
diff --git a/typo3/js/loginrefresh.js b/typo3/js/loginrefresh.js
index de0871bfdf41241ae1b6e2405e62e6b2e5676020..33ca93ba7f00cac5ba0d2c627e7822d8eab267a2 100644
--- a/typo3/js/loginrefresh.js
+++ b/typo3/js/loginrefresh.js
@@ -306,7 +306,6 @@ Ext.ux.TYPO3.loginRefresh = Ext.extend(Ext.util.Observable, {
 						// User is logged in
 						Ext.getCmp("loginformWindow").hide();
 						TYPO3.loginRefresh.startTimer();
-						TYPO3.loginRefresh.refreshTokens(result.accessToken);
 					} else {
 						// TODO: add failure to notification system instead of alert
 						Ext.Msg.alert(TYPO3.LLL.core.refresh_login_failed, TYPO3.LLL.core.refresh_login_failed_message);
@@ -337,97 +336,6 @@ Ext.ux.TYPO3.loginRefresh = Ext.extend(Ext.util.Observable, {
 		} else {
 			this.submitForm();
 		}
-	},
-
-	getOutdatedTokens: function() {
-		var tokens = [];
-		var searchTokenPlaces = [top, top.content.document];
-
-		if (top.nav instanceof TYPO3.iframePanel) {
-			searchTokenPlaces.push(top.nav.getIframe());
-		}
-
-		Ext.each(searchTokenPlaces, function(searchPlace) {
-			var links = searchPlace.Ext.query('a[href*=formToken]');
-			Ext.each(links, function(linkTag) {
-				tokens.push(Ext.urlDecode(linkTag.href).formToken);
-			});
-
-			var formFields = searchPlace.Ext.query("form input[name=formToken]");
-			Ext.each(formFields, function(inputField) {
-				tokens.push(inputField.value);
-			});
-
-			var linksOnclick = searchPlace.Ext.query('a[onclick*=formToken]');
-			Ext.each(linksOnclick, function(linkTag) {
-				tokens.push(linkTag.attributes.onclick.value.match(/&formToken=([^&]*)&/).pop());
-			});
-
-			if (Ext.isString(searchPlace.TYPO3.ExtDirectToken)) {
-				tokens.push(searchPlace.TYPO3.ExtDirectToken);
-			}
-
-		});
-
-		return tokens;
-	},
-
-	replaceOutdatedTokens: function(newTokens) {
-		var searchTokenPlaces = [top, top.content.document];
-
-		if (top.nav instanceof TYPO3.iframePanel) {
-			searchTokenPlaces.push(top.nav.getIframe());
-		}
-
-		Ext.each(searchTokenPlaces, function(searchPlace) {
-			var links = searchPlace.Ext.query('a[href*=formToken]');
-			Ext.each(links, function(linkTag) {
-				var url = Ext.urlDecode(linkTag.href);
-				url.formToken = newTokens[url.formToken];
-				linkTag.href = unescape(Ext.urlEncode(url));
-			});
-
-			var formFields = searchPlace.Ext.query("form input[name=formToken]");
-			Ext.each(formFields, function(inputField) {
-				inputField.value = newTokens[inputField.value];
-			});
-
-			var linksOnclick = searchPlace.Ext.query('a[onclick*=formToken]');
-			Ext.each(linksOnclick, function(linkTag) {
-				var token = linkTag.attributes.onclick.value.match(/&formToken=([^&]*)&/).pop();
-				linkTag.attributes.onclick.value = linkTag.attributes.onclick.value.replace(new RegExp(token), newTokens[token]);
-			});
-
-			if (Ext.isString(searchPlace.TYPO3.ExtDirectToken)) {
-				searchPlace.TYPO3.ExtDirectToken = newTokens[searchPlace.TYPO3.ExtDirectToken];
-			}
-		});
-	},
-
-	refreshTokens: function(accessToken) {
-		Ext.Ajax.request({
-			url: "ajax.php",
-			params: {
-				"ajaxID": "BackendLogin::refreshTokens",
-				"accessToken": accessToken,
-				"tokens": Ext.encode(this.getOutdatedTokens())
-			},
-			method: "POST",
-			scope: this,
-			success: function(response, opts) {
-				var result = Ext.util.JSON.decode(response.responseText);
-				TYPO3.loginRefresh.replaceOutdatedTokens(result.newTokens);
-			},
-			failure: function(response, opts) {
-				TYPO3.Flashmessage.display(
-						TYPO3.Severity.error,
-						'Refresh tokens',
-						'Refreshing tokens after relogin failed. Please reload the backend.',
-						30
-					);
-			}
-
-		});
 	}
 });
 
diff --git a/typo3/logout.php b/typo3/logout.php
index 759b6784759a02b70d361291493c5c781d924fb9..c11ada394aeac3b83900fee80c0cb4c889010d22 100644
--- a/typo3/logout.php
+++ b/typo3/logout.php
@@ -66,7 +66,8 @@ class SC_logout {
 	 */
 	function logout()	{
 			// Logout written to log
-		$GLOBALS['BE_USER']->writelog(255 ,2, 0, 1, 'User %s logged out from TYPO3 Backend', array($GLOBALS['BE_USER']->user['username']));
+		$GLOBALS['BE_USER']->writelog(255, 2, 0, 1, 'User %s logged out from TYPO3 Backend', array($GLOBALS['BE_USER']->user['username']));
+		t3lib_formProtection_Factory::get()->removeSessionTokenFromRegistry();
 		$GLOBALS['BE_USER']->logoff();
 		$redirect = t3lib_div::sanitizeLocalUrl(t3lib_div::_GP('redirect'));
 		$redirectUrl = $redirect ? $redirect : 'index.php';
diff --git a/typo3/sysext/install/mod/class.tx_install.php b/typo3/sysext/install/mod/class.tx_install.php
index 8d239e2653096d4389607db2aabe9486313848ab..0abb71eca85fe011b21b7cbebb751998048d083d 100755
--- a/typo3/sysext/install/mod/class.tx_install.php
+++ b/typo3/sysext/install/mod/class.tx_install.php
@@ -925,8 +925,6 @@ REMOTE_ADDR was '".t3lib_div::getIndpEnv('REMOTE_ADDR')."' (".t3lib_div::getIndp
 				break;
 			}
 		}
-
-		$this->formProtection->persistTokens();
 	}
 
 	/**
diff --git a/typo3/sysext/setup/mod/index.php b/typo3/sysext/setup/mod/index.php
index f92ee092a2265d3086901ce5456a39175863ffe4..76795fc9d2f1f416b028b96d45eccfd6bb0ca2d3 100755
--- a/typo3/sysext/setup/mod/index.php
+++ b/typo3/sysext/setup/mod/index.php
@@ -145,6 +145,8 @@ class SC_mod_user_setup_index {
 
 	/**
 	 * Getter for the form protection instance.
+	 *
+	 * @return t3lib_formprotection_BackendFormProtection
 	 */
 	public function getFormProtection() {
 		return $this->formProtection;
@@ -1033,6 +1035,4 @@ $LANG->includeLLFile('EXT:setup/mod/locallang.xml');
 $SOBE->init();
 $SOBE->main();
 $SOBE->printContent();
-
-$SOBE->getFormProtection()->persistTokens();
 ?>
\ No newline at end of file
diff --git a/typo3/tce_db.php b/typo3/tce_db.php
index 309dd90ccf73a12faa8d4af04e82e6530233d2c3..51a3616efb53e7755d1a850df12088502d751ca0 100644
--- a/typo3/tce_db.php
+++ b/typo3/tce_db.php
@@ -249,18 +249,7 @@ $formprotection = t3lib_formprotection_Factory::get();
 if ($formprotection->validateToken(t3lib_div::_GP('formToken'), 'tceAction')) {
 	$SOBE->initClipboard();
 	$SOBE->main();
-
-		// This is done for the clear cache menu, so that it gets a new token
-		// making it possible to clear cache several times.
-	if (t3lib_div::_GP('ajaxCall')) {
-		$token = array();
-		$token['value'] = $formprotection->generateToken('tceAction');
-		$token['name'] = 'formToken';
-			// This will be used by clearcachemenu.js to replace the token for the next call
-		echo t3lib_BEfunc::getUrlToken('tceAction');
-	}
 }
-$formprotection->persistTokens();
 $SOBE->finish();
 
 ?>
\ No newline at end of file
diff --git a/typo3/template.php b/typo3/template.php
index bd98584c252740a4f168f75baf19daa5fa5424d8..996aada91643316bc38ce1d69e9b8c51ec1f7457 100644
--- a/typo3/template.php
+++ b/typo3/template.php
@@ -906,7 +906,6 @@ $str.=$this->docBodyTagBegin().
 
 <!-- Wrapping DIV-section for whole page END -->
 </div>':'') . $this->endOfPageJsBlock ;
-			t3lib_formprotection_Factory::get()->persistTokens();
 		}