Index: tests/t3lib/cache/frontend/t3lib_cache_frontend_phpfrontendtestcase.php
===================================================================
--- tests/t3lib/cache/frontend/t3lib_cache_frontend_phpfrontendtestcase.php	(revision 0)
+++ tests/t3lib/cache/frontend/t3lib_cache_frontend_phpfrontendtestcase.php	(revision 0)
@@ -0,0 +1,88 @@
+<?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!
+***************************************************************/
+
+
+/**
+ * Testcase for the PHP source code cache frontend
+ *
+ * This file is a backport from FLOW3
+ *
+ * @author Christian Kuhn <lolli@schwarzbu.ch>
+ * @package TYPO3
+ * @subpackage tests
+ * @version $Id$
+ */
+class t3lib_cache_frontend_PhpFrontendTestCase extends tx_phpunit_testcase {
+
+	/**
+	 * @test
+	 * @author Robert Lemke <robert@typo3.org>
+	 * @expectedException InvalidArgumentException
+	 */
+	public function setChecksIfTheIdentifierIsValid() {
+		$cache = $this->getMock('t3lib_cache_frontend_StringFrontend', array('isValidEntryIdentifier'), array(), '', FALSE);
+		$cache->expects($this->once())->method('isValidEntryIdentifier')->with('foo')->will($this->returnValue(FALSE));
+		$cache->set('foo', 'bar');
+	}
+
+	/**
+	 * @test
+	 * @author Robert Lemke <robert@typo3.org>
+	 */
+	public function setPassesPhpSourceCodeTagsAndLifetimeToBackend() {
+		$originalSourceCode = 'return "hello world!";';
+		$modifiedSourceCode = '<?php' . chr(10) . $originalSourceCode . chr(10) . '__halt_compiler();';
+
+		$mockBackend = $this->getMock('t3lib_cache_backend_PhpCapableBackend', array(), array(), '', FALSE);
+		$mockBackend->expects($this->once())->method('set')->with('Foo-Bar', $modifiedSourceCode, array('tags'), 1234);
+
+		$cache = t3lib_div::makeInstance('t3lib_cache_frontend_PhpFrontend', 'PhpFrontend', $mockBackend);
+		$cache->set('Foo-Bar', $originalSourceCode, array('tags'), 1234);
+	}
+
+	/**
+	 * @test
+	 * @author Robert Lemke <robert@typo3.org>
+	 * @expectedException t3lib_cache_exception_InvalidData
+	 */
+	public function setThrowsInvalidDataExceptionOnNonStringValues() {
+		$cache = $this->getMock('t3lib_cache_frontend_PhpFrontend', array('dummy'), array(), '', FALSE);
+		$cache->set('Foo-Bar', array());
+	}
+
+	/**
+	 * @test
+	 * @author Robert Lemke <robert@typo3.org>
+	 */
+	public function requireOnceCallsTheBackendsRequireOnceMethod() {
+		$mockBackend = $this->getMock('t3lib_cache_backend_PhpCapableBackend', array(), array(), '', FALSE);
+		$mockBackend->expects($this->once())->method('requireOnce')->with('Foo-Bar')->will($this->returnValue('hello world!'));
+
+		$cache = t3lib_div::makeInstance('t3lib_cache_frontend_PhpFrontend', 'PhpFrontend', $mockBackend);
+
+		$result = $cache->requireOnce('Foo-Bar');
+		$this->assertSame('hello world!', $result);
+	}
+}
+?>
Index: tests/t3lib/cache/backend/t3lib_cache_backend_filebackendtestcase.php
===================================================================
--- tests/t3lib/cache/backend/t3lib_cache_backend_filebackendtestcase.php	(revision 7841)
+++ tests/t3lib/cache/backend/t3lib_cache_backend_filebackendtestcase.php	(working copy)
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 2009 Ingo Renner <ingo@typo3.org>
+*  (c) 2009-2010 Ingo Renner <ingo@typo3.org>
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
@@ -50,12 +50,19 @@
  *
  * This file is a backport from FLOW3
  *
- * @author	Ingo Renner <ingo@typo3.org>
+ * @author Ingo Renner <ingo@typo3.org>
+ * @author Christian Kuhn <lolli@schwarzbu.ch>
  * @package TYPO3
  * @subpackage tests
  * @version $Id: t3lib_cache_backend_filebackendtestcase.php 7825 2010-06-06 14:52:10Z lolli $
  */
 class t3lib_cache_backend_FileBackendTestCase extends tx_phpunit_testcase {
+	/**
+	 * Backup of global variable EXEC_TIME
+	 *
+	 * @var array
+	 */
+	protected $backupGlobalVariables;
 
 	/**
 	 * If set, the tearDown() method will clean up the cache subdirectory used by this unit test.
@@ -64,6 +71,9 @@
 	 */
 	protected $backend;
 
+	/**
+	 * @var string Directory for testing data, relative to PATH_site
+	 */
 	protected $testingCacheDirectory;
 
 	/**
@@ -72,6 +82,10 @@
 	 * @return void
 	 */
 	public function setUp() {
+		$this->backupGlobalVariables = array(
+			'EXEC_TIME' => $GLOBALS['EXEC_TIME'],
+		);
+
 		$this->testingCacheDirectory = 'typo3temp/cache/testing/';
 
 		$this->backend = t3lib_div::makeInstance(
@@ -110,7 +124,7 @@
 	 * @author Robert Lemke <robert@typo3.org>
 	 * @author Ingo Renner <ingo@typo3.org>
 	 */
-	public function getCacheDirectoryReturnsThePreviouslySetDirectory() {
+	public function getCacheDirectoryReturnsTheCurrentCacheDirectory() {
 		$directory = $this->testingCacheDirectory;
 		$fullPathToDirectory = t3lib_div::getIndpEnv('TYPO3_DOCUMENT_ROOT') . '/' . $directory;
 
@@ -125,18 +139,13 @@
 	 * @expectedException t3lib_cache_exception_InvalidData
 	 */
 	public function setThrowsExceptionIfDataIsNotAString() {
-		$cache = $this->getMock('t3lib_cache_frontend_AbstractFrontend',
-			array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove'),
-			array(),
-			'',
-			FALSE
-		);
+		$mockCache = $this->getMock('t3lib_cache_frontend_AbstractFrontend', array(), array(), '', FALSE);
+		$mockCache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('UnitTestCache'));
 
+		$this->backend->setCache($mockCache);
 		$data = array('Some data');
 		$entryIdentifier = 'BackendFileTest';
 
-		$this->backend->setCache($cache);
-
 		$this->backend->set($entryIdentifier, $data);
 	}
 
@@ -146,39 +155,19 @@
 	 * @author Ingo Renner <ingo@typo3.org>
 	 */
 	public function setReallySavesToTheSpecifiedDirectory() {
-		$cacheIdentifier = 'UnitTestCache';
-		$cache = $this->getMock('t3lib_cache_frontend_AbstractFrontend',
-			array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove'),
-			array(),
-			'',
-			FALSE
-		);
+		$mockCache = $this->getMock('t3lib_cache_frontend_AbstractFrontend', array(), array(), '', FALSE);
+		$mockCache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('UnitTestCache'));
 
-		$cache->expects($this->atLeastOnce())
-			->method('getIdentifier')
-			->will($this->returnValue($cacheIdentifier));
-
 		$data = 'some data' . microtime();
 		$entryIdentifier = 'BackendFileTest';
-		$entryIdentifierHash = sha1($entryIdentifier);
+		$this->backend->setCache($mockCache);
+		$pathAndFilename = $this->backend->getCacheDirectory() . $entryIdentifier;
 
-		$this->backend->setCache($cache);
-		$this->backend->set($entryIdentifier, $data);
+		$this->backend->set($entryIdentifier, $data, array(), 10);
 
-		$cacheDirectory = $this->backend->getCacheDirectory();
-		$pathAndFilename = $cacheDirectory
-			. 'data/'
-			. $cacheIdentifier . '/'
-			. $entryIdentifierHash[0] . '/'
-			. $entryIdentifierHash[1] . '/'
-			. $entryIdentifier;
-		$this->assertTrue(file_exists($pathAndFilename), 'File does not exist.');
-		$retrievedData = file_get_contents($pathAndFilename, NULL, NULL, t3lib_cache_backend_FileBackend::EXPIRYTIME_LENGTH);
-		$this->assertEquals(
-			$data,
-			$retrievedData,
-			'The original and the retrieved data don\'t match.'
-		);
+		$this->assertFileExists($pathAndFilename);
+		$retrievedData = file_get_contents($pathAndFilename, NULL, NULL, 0, strlen($data));
+		$this->assertEquals($data, $retrievedData);
 	}
 
 	/**
@@ -187,37 +176,23 @@
 	 * @author Ingo Renner <ingo@typo3.org>
 	 */
 	public function setOverwritesAnAlreadyExistingCacheEntryForTheSameIdentifier() {
-		$cacheIdentifier = 'UnitTestCache';
-		$cache = $this->getMock('t3lib_cache_frontend_AbstractFrontend',
-			array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove'),
-			array(),
-			'',
-			FALSE
-		);
-		$cache->expects($this->atLeastOnce())
-			->method('getIdentifier')
-			->will($this->returnValue($cacheIdentifier));
+		$mockCache = $this->getMock('t3lib_cache_frontend_AbstractFrontend', array(), array(), '', FALSE);
+		$mockCache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('UnitTestCache'));
 
 		$data1 = 'some data' . microtime();
 		$data2 = 'some data' . microtime();
 		$entryIdentifier = 'BackendFileRemoveBeforeSetTest';
-		$entryIdentifierHash = sha1($entryIdentifier);
 
-		$this->backend->setCache($cache);
+		$this->backend->setCache($mockCache);
 		$this->backend->set($entryIdentifier, $data1, array(), 500);
-			// setting a second entry with the same identifier, but different
+			// Setting a second entry with the same identifier, but different
 			// data, this should _replace_ the existing one we set before
 		$this->backend->set($entryIdentifier, $data2, array(), 200);
 
-		$cacheDirectory = $this->backend->getCacheDirectory();
-		$pathAndFilename = $cacheDirectory
-			. 'data/'
-			. $cacheIdentifier . '/'
-			. $entryIdentifierHash[0] . '/'
-			. $entryIdentifierHash[1] . '/'
-			. $entryIdentifier;
-		$this->assertTrue(file_exists($pathAndFilename), 'File does not exist.');
-		$retrievedData = file_get_contents($pathAndFilename, NULL, NULL, t3lib_cache_backend_FileBackend::EXPIRYTIME_LENGTH);
+		$pathAndFilename = $this->backend->getCacheDirectory() . $entryIdentifier;
+
+		$this->assertFileExists($pathAndFilename);
+		$retrievedData = file_get_contents($pathAndFilename, NULL, NULL, 0, strlen($data2));
 		$this->assertEquals($data2, $retrievedData);
 	}
 
@@ -226,90 +201,76 @@
 	 * @author Robert Lemke <robert@typo3.org>
 	 * @author Ingo Renner <ingo@typo3.org>
 	 */
-	public function setReallySavesSpecifiedTags() {
-		$cacheIdentifier = 'UnitTestCache';
-		$cache = $this->getMock('t3lib_cache_frontend_AbstractFrontend',
-			array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove'),
-			array(),
-			'',
-			FALSE
-		);
-		$cache->expects($this->atLeastOnce())
-			->method('getIdentifier')
-			->will($this->returnValue($cacheIdentifier));
+	public function setAlsoSavesSpecifiedTags() {
+		$mockCache = $this->getMock('t3lib_cache_frontend_AbstractFrontend', array(), array(), '', FALSE);
+		$mockCache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('UnitTestCache'));
 
 		$data = 'some data' . microtime();
 		$entryIdentifier = 'BackendFileTest';
-		$entryIdentifierHash = sha1($entryIdentifier);
 
-		$this->backend->setCache($cache);
-		$tagsDirectory = $this->backend->getCacheDirectory() . 'tags/';
+		$this->backend->setCache($mockCache);
+		$this->backend->set($entryIdentifier, $data, array('Tag1', 'Tag2'));
 
-		$this->backend->set($entryIdentifier, $data, array('UnitTestTag%tag1', 'UnitTestTag%tag2'));
-
-		$this->assertTrue(is_dir($tagsDirectory . 'UnitTestTag%tag1'), 'Tag directory UnitTestTag%tag1 does not exist.');
-		$this->assertTrue(is_dir($tagsDirectory . 'UnitTestTag%tag2'), 'Tag directory UnitTestTag%tag2 does not exist.');
-
-		$filename = $tagsDirectory . 'UnitTestTag%tag1/' . $cacheIdentifier . t3lib_cache_backend_FileBackend::SEPARATOR . $entryIdentifier;
-		$this->assertTrue(file_exists($filename), 'File "' . $filename . '" does not exist.');
-
-		$filename = $tagsDirectory . 'UnitTestTag%tag2/' . $cacheIdentifier . t3lib_cache_backend_FileBackend::SEPARATOR . $entryIdentifier;
-		$this->assertTrue(file_exists($filename), 'File "' . $filename . '" does not exist.');
+		$pathAndFilename = $this->backend->getCacheDirectory() . $entryIdentifier;
+		$this->assertFileExists($pathAndFilename);
+		$retrievedData = file_get_contents($pathAndFilename, NULL, NULL, (strlen($data) + t3lib_cache_backend_FileBackend::EXPIRYTIME_LENGTH), 9);
+		$this->assertEquals('Tag1 Tag2', $retrievedData);
 	}
 
 	/**
 	 * @test
 	 * @author Robert Lemke <robert@typo3.org>
+	 * @author Karsten Dambekalns <karsten@typo3.org>
 	 * @author Ingo Renner <ingo@typo3.org>
 	 */
-	public function getReturnsContentOfTheCorrectCacheFile() {
-		$cacheIdentifier = 'UnitTestCache';
-		$cache = $this->getMock('t3lib_cache_frontend_AbstractFrontend',
-			array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove'),
-			array(),
-			'',
-			FALSE
-		);
-		$cache->expects($this->atLeastOnce())
-			->method('getIdentifier')
-			->will($this->returnValue($cacheIdentifier));
+	public function setWithUnlimitedLifetimeWritesCorrectEntry() {
+		$mockCache = $this->getMock('t3lib_cache_frontend_AbstractFrontend', array(), array(), '', FALSE);
+		$mockCache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('UnitTestCache'));
 
-		$this->backend->setCache($cache);
-
+		$data = 'some data' . microtime();
 		$entryIdentifier = 'BackendFileTest';
 
-		$data = 'some data' . microtime();
-		$this->backend->set($entryIdentifier, $data, array(), 500);
+		$this->backend->setCache($mockCache);
+		$pathAndFilename = $this->backend->getCacheDirectory() . $entryIdentifier;
 
-		$data = 'some other data' . microtime();
-		$this->backend->set($entryIdentifier, $data, array(), 100);
+		$this->backend->set($entryIdentifier, $data, array(), 0);
 
-		$loadedData = $this->backend->get($entryIdentifier);
+		$this->assertFileExists($pathAndFilename);
 
-		$this->assertEquals($data, $loadedData, 'The original and the retrieved data don\'t match.');
+		$dataSize = (integer)file_get_contents($pathAndFilename, NULL, NULL, filesize($pathAndFilename) - t3lib_cache_backend_FileBackend::DATASIZE_DIGITS, t3lib_cache_backend_FileBackend::DATASIZE_DIGITS);
+		$retrievedData = file_get_contents($pathAndFilename, NULL, NULL, 0, $dataSize);
+
+		$this->assertEquals($data, $retrievedData, 'The original and the retrieved data don\'t match.');
 	}
 
 	/**
 	 * @test
 	 * @author Robert Lemke <robert@typo3.org>
+	 */
+	public function getReturnsFalseForExpiredEntries() {
+		$mockCache = $this->getMock('t3lib_cache_frontend_AbstractFrontend', array(), array(), '', FALSE);
+		$mockCache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('UnitTestCache'));
+
+		$backend = $this->getMock('t3lib_cache_backend_FileBackend', array('isCacheFileExpired'), array(), '', FALSE);
+		$fullPathToCacheFile = t3lib_div::getIndpEnv('TYPO3_DOCUMENT_ROOT') . '/typo3temp/cache/UnitTestCache/ExpiredEntry';
+		$backend->expects($this->once())->method('isCacheFileExpired')->with($fullPathToCacheFile)->will($this->returnValue(TRUE));
+		$backend->setCache($mockCache);
+
+		$this->assertFalse($backend->get('ExpiredEntry'));
+	}
+
+	/**
+	 * @test
+	 * @author Robert Lemke <robert@typo3.org>
 	 * @author Ingo Renner <ingo@typo3.org>
 	 */
-	public function hasReturnsTheCorrectResult() {
-		$cacheIdentifier = 'UnitTestCache';
-		$cache = $this->getMock('t3lib_cache_frontend_AbstractFrontend',
-			array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove'),
-			array(),
-			'',
-			FALSE
-		);
-		$cache->expects($this->atLeastOnce())
-			->method('getIdentifier')
-			->will($this->returnValue($cacheIdentifier));
+	public function hasReturnsTrueIfAnEntryExists() {
+		$mockCache = $this->getMock('t3lib_cache_frontend_AbstractFrontend', array(), array(), '', FALSE);
+		$mockCache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('UnitTestCache'));
 
-		$this->backend->setCache($cache);
+		$this->backend->setCache($mockCache);
 
 		$entryIdentifier = 'BackendFileTest';
-
 		$data = 'some data' . microtime();
 		$this->backend->set($entryIdentifier, $data);
 
@@ -320,39 +281,34 @@
 	/**
 	 * @test
 	 * @author Robert Lemke <robert@typo3.org>
+	 */
+	public function hasReturnsFalseForExpiredEntries() {
+		$backend = $this->getMock('t3lib_cache_backend_FileBackend', array('isCacheFileExpired'), array(), '', FALSE);
+		$backend->expects($this->exactly(2))->method('isCacheFileExpired')->will($this->onConsecutiveCalls(TRUE, FALSE));
+
+		$this->assertFalse($backend->has('foo'));
+		$this->assertTrue($backend->has('bar'));
+	}
+
+	/**
+	 * @test
+	 * @author Robert Lemke <robert@typo3.org>
 	 * @author Ingo Renner <ingo@typo3.org>
 	 */
 	public function removeReallyRemovesACacheEntry() {
-		$cacheIdentifier = 'UnitTestCache';
-		$cache = $this->getMock('t3lib_cache_frontend_AbstractFrontend',
-			array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove'),
-			array(),
-			'',
-			FALSE
-		);
-		$cache->expects($this->atLeastOnce())
-			->method('getIdentifier')
-			->will($this->returnValue($cacheIdentifier));
+		$mockCache = $this->getMock('t3lib_cache_frontend_AbstractFrontend', array(), array(), '', FALSE);
+		$mockCache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('UnitTestCache'));
 
 		$data = 'some data' . microtime();
-		$entryIdentifier = 'BackendFileRemovalTest';
-		$entryIdentifierHash = sha1($entryIdentifier);
+		$entryIdentifier = 'BackendFileTest';
 
-		$cacheDirectory = $this->backend->getCacheDirectory();
-		$this->backend->setCache($cache);
-
-		$pathAndFilename = $cacheDirectory
-			. 'data/'
-			. $cacheIdentifier . '/'
-			. $entryIdentifierHash[0] . '/'
-			. $entryIdentifierHash[1] . '/'
-			. $entryIdentifier;
-
+		$this->backend->setCache($mockCache);
+		$pathAndFilename = $this->backend->getCacheDirectory() . $entryIdentifier;
 		$this->backend->set($entryIdentifier, $data);
-		$this->assertTrue(file_exists($pathAndFilename), 'The cache entry does not exist.');
 
+		$this->assertFileExists($pathAndFilename);
 		$this->backend->remove($entryIdentifier);
-		$this->assertFalse(file_exists($pathAndFilename), 'The cache entry still exists.');
+		$this->assertFileNotExists($pathAndFilename);
 	}
 
 	/**
@@ -362,38 +318,22 @@
 	 * @author Ingo Renner <ingo@typo3.org>
 	 */
 	public function collectGarbageReallyRemovesAnExpiredCacheEntry() {
-		$cacheIdentifier = 'UnitTestCache';
-		$cache = $this->getMock('t3lib_cache_frontend_AbstractFrontend',
-			array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove'),
-			array(),
-			'',
-			FALSE
-		);
-		$cache->expects($this->atLeastOnce())
-			->method('getIdentifier')
-			->will($this->returnValue($cacheIdentifier));
+		$mockCache = $this->getMock('t3lib_cache_frontend_AbstractFrontend', array(), array(), '', FALSE);
+		$mockCache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('UnitTestCache'));
 
 		$data = 'some data' . microtime();
 		$entryIdentifier = 'BackendFileRemovalTest';
-		$entryIdentifierHash = sha1($entryIdentifier);
 
-		$cacheDirectory = $this->backend->getCacheDirectory();
-		$this->backend->setCache($cache);
-
-		$pathAndFilename = $cacheDirectory
-			. 'data/'
-			. $cacheIdentifier . '/'
-			. $entryIdentifierHash[0] . '/'
-			. $entryIdentifierHash[1] . '/'
-			. $entryIdentifier;
-
+		$this->backend->setCache($mockCache);
+		$pathAndFilename = $this->backend->getCacheDirectory() . $entryIdentifier;
 		$this->backend->set($entryIdentifier, $data, array(), 1);
-		$this->assertTrue(file_exists($pathAndFilename), 'The cache entry does not exist.');
 
-		sleep(2);
+		$this->assertFileExists($pathAndFilename);
 
+		$GLOBALS['EXEC_TIME'] += 2;
 		$this->backend->collectGarbage();
-		$this->assertFalse(file_exists($pathAndFilename), 'The cache entry still exists.');
+
+		$this->assertFileNotExists($pathAndFilename);
 	}
 
 	/**
@@ -403,40 +343,32 @@
 	 * @author Ingo Renner <ingo@typo3.org>
 	 */
 	public function collectGarbageReallyRemovesAllExpiredCacheEntries() {
-		$cacheIdentifier = 'UnitTestCache';
-		$cache = $this->getMock('t3lib_cache_frontend_AbstractFrontend',
-			array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove'),
-			array(),
-			'',
-			FALSE
-		);
-		$cache->expects($this->atLeastOnce())
-			->method('getIdentifier')
-			->will($this->returnValue($cacheIdentifier));
+		$mockCache = $this->getMock('t3lib_cache_frontend_AbstractFrontend', array(), array(), '', FALSE);
+		$mockCache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('UnitTestCache'));
 
 		$data = 'some data' . microtime();
 		$entryIdentifier = 'BackendFileRemovalTest';
 
-		$cacheDirectory = $this->backend->getCacheDirectory();
-		$this->backend->setCache($cache);
+		$this->backend->setCache($mockCache);
+		$pathAndFilename = $this->backend->getCacheDirectory() . $entryIdentifier;
 
-		$pattern = $cacheDirectory
-			. 'data/'
-			. $cacheIdentifier . '/*/*/'
-			. $entryIdentifier
-			. '?';
-
-		$this->backend->set($entryIdentifier . 'A', $data, array(), 1);
-		$this->backend->set($entryIdentifier . 'B', $data, array(), 1);
+		$this->backend->set($entryIdentifier . 'A', $data, array(), NULL);
+		$this->backend->set($entryIdentifier . 'B', $data, array(), 10);
 		$this->backend->set($entryIdentifier . 'C', $data, array(), 1);
-		$filesFound = glob($pattern);
-		$this->assertTrue(is_array($filesFound) && count($filesFound) > 0, 'The cache entries do not exist.');
+		$this->backend->set($entryIdentifier . 'D', $data, array(), 1);
 
-		sleep(2);
+		$this->assertFileExists($pathAndFilename . 'A');
+		$this->assertFileExists($pathAndFilename . 'B');
+		$this->assertFileExists($pathAndFilename . 'C');
+		$this->assertFileExists($pathAndFilename . 'D');
 
+		$GLOBALS['EXEC_TIME'] += 2;
 		$this->backend->collectGarbage();
-		$filesFound = is_array(glob($pattern)) ? glob($pattern) : array();
-		$this->assertTrue(count($filesFound) === 0, 'The cache entries still exist.');
+
+		$this->assertFileExists($pathAndFilename . 'A');
+		$this->assertFileExists($pathAndFilename . 'B');
+		$this->assertFileNotExists($pathAndFilename . 'C');
+		$this->assertFileNotExists($pathAndFilename . 'D');
 	}
 
 	/**
@@ -444,62 +376,44 @@
 	 * @author Robert Lemke <robert@typo3.org>
 	 * @author Ingo Renner <ingo@typo3.org>
 	 */
-	public function removeReallyRemovesTagsOfRemovedEntry() {
-		$cacheIdentifier = 'UnitTestCache';
-		$cache = $this->getMock('t3lib_cache_frontend_AbstractFrontend',
-			array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove'),
-			array(),
-			'',
-			FALSE
-		);
-		$cache->expects($this->atLeastOnce())
-			->method('getIdentifier')
-			->will($this->returnValue($cacheIdentifier));
+	public function findIdentifiersByTagFindsCacheEntriesWithSpecifiedTag() {
+		$mockCache = $this->getMock('t3lib_cache_frontend_AbstractFrontend', array(), array(), '', FALSE);
+		$mockCache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('UnitTestCache'));
 
+		$this->backend->setCache($mockCache);
+
 		$data = 'some data' . microtime();
-		$entryIdentifier = 'BackendFileTest';
+		$this->backend->set('BackendFileTest1', $data, array('UnitTestTag%test', 'UnitTestTag%boring'));
+		$this->backend->set('BackendFileTest2', $data, array('UnitTestTag%test', 'UnitTestTag%special'));
+		$this->backend->set('BackendFileTest3', $data, array('UnitTestTag%test'));
 
-		$this->backend->setCache($cache);
+		$expectedEntry = 'BackendFileTest2';
 
-		$tagsDirectory = $this->backend->getCacheDirectory() . 'tags/';
+		$actualEntries = $this->backend->findIdentifiersByTag('UnitTestTag%special');
 
-		$this->backend->set($entryIdentifier, $data, array('UnitTestTag%tag1', 'UnitTestTag%tag2'));
-		$this->backend->remove($entryIdentifier);
-
-		$this->assertTrue(!file_exists($tagsDirectory . 'UnitTestTag%tag1/' . $entryIdentifier), 'File "' . $tagsDirectory . 'UnitTestTag%tag1/' . $entryIdentifier . '" still exists.');
-		$this->assertTrue(!file_exists($tagsDirectory . 'UnitTestTag%tag2/' . $entryIdentifier), 'File "' . $tagsDirectory . 'UnitTestTag%tag2/' . $entryIdentifier . '" still exists.');
+		$this->assertTrue(is_array($actualEntries), 'actualEntries is not an array.');
+		$this->assertEquals($expectedEntry, array_pop($actualEntries));
 	}
 
 	/**
 	 * @test
-	 * @author Robert Lemke <robert@typo3.org>
 	 * @author Ingo Renner <ingo@typo3.org>
 	 */
-	public function findIdentifiersByTagFindsCacheEntriesWithSpecifiedTag() {
-		$cacheIdentifier = 'UnitTestCache';
-		$cache = $this->getMock('t3lib_cache_frontend_AbstractFrontend',
-			array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove'),
-			array(),
-			'',
-			FALSE
-		);
-		$cache->expects($this->atLeastOnce())
-			->method('getIdentifier')
-			->will($this->returnValue($cacheIdentifier));
+	public function findIdentifiersByTagDoesNotReturnExpiredEntries() {
+		$mockCache = $this->getMock('t3lib_cache_frontend_AbstractFrontend', array(), array(), '', FALSE);
+		$mockCache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('UnitTestCache'));
 
-		$this->backend->setCache($cache);
+		$this->backend->setCache($mockCache);
 
-		$data = 'some data' . microtime();
+		$data = 'some data';
 		$this->backend->set('BackendFileTest1', $data, array('UnitTestTag%test', 'UnitTestTag%boring'));
-		$this->backend->set('BackendFileTest2', $data, array('UnitTestTag%test', 'UnitTestTag%special'));
+		$this->backend->set('BackendFileTest2', $data, array('UnitTestTag%test', 'UnitTestTag%special'), -100);
 		$this->backend->set('BackendFileTest3', $data, array('UnitTestTag%test'));
 
-		$expectedEntry = 'BackendFileTest2';
-
-		$actualEntries = $this->backend->findIdentifiersByTag('UnitTestTag%special');
-		$this->assertTrue(is_array($actualEntries), 'actualEntries is not an array.');
-
-		$this->assertEquals($expectedEntry, array_pop($actualEntries));
+		$this->assertSame(array(), $this->backend->findIdentifiersByTag('UnitTestTag%special'));
+		$foundIdentifiers = $this->backend->findIdentifiersByTag('UnitTestTag%test');
+		sort($foundIdentifiers);
+		$this->assertSame(array('BackendFileTest1', 'BackendFileTest3'), $foundIdentifiers);
 	}
 
 	/**
@@ -507,23 +421,12 @@
 	 * @author Robert Lemke <robert@typo3.org>
 	 * @author Ingo Renner <ingo@typo3.org>
 	 */
-	public function flushRemovesAllCacheEntriesAndRelatedTags() {
-		$cacheIdentifier = 'UnitTestCache';
-		$cache = $this->getMock('t3lib_cache_frontend_AbstractFrontend',
-			array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove'),
-			array(),
-			'',
-			FALSE
-		);
-		$cache->expects($this->atLeastOnce())
-			->method('getIdentifier')
-			->will($this->returnValue($cacheIdentifier));
+	public function flushRemovesAllCacheEntries() {
+		$mockCache = $this->getMock('t3lib_cache_frontend_AbstractFrontend', array(), array(), '', FALSE);
+		$mockCache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('UnitTestCache'));
 
-		$this->backend->setCache($cache);
+		$this->backend->setCache($mockCache);
 
-		$tagsDirectory = $this->backend->getCacheDirectory() . 'tags/';
-		$cacheDirectory = $this->backend->getCacheDirectory() . 'data/' . $cacheIdentifier . '/';
-
 		$data = 'some data' . microtime();
 		$this->backend->set('BackendFileTest1', $data, array('UnitTestTag%test'));
 		$this->backend->set('BackendFileTest2', $data, array('UnitTestTag%test', 'UnitTestTag%special'));
@@ -531,19 +434,9 @@
 
 		$this->backend->flush();
 
-		$pattern = $cacheDirectory . '*/*/*';
+		$pattern = $this->backend->getCacheDirectory() . '*';
 		$filesFound = is_array(glob($pattern)) ? glob($pattern) : array();
 		$this->assertTrue(count($filesFound) === 0, 'Still files in the cache directory');
-
-		$tagPrefixTest = $tagsDirectory . 'UnitTestTag%test/' . $cacheIdentifier . '^';
-		$tagPrefixSpecial = $tagsDirectory . 'UnitTestTag%special/' . $cacheIdentifier . '^';
-		$entryIdentifier = 'BackendFileTest1';
-		$this->assertTrue(!file_exists($tagPrefixTest . $entryIdentifier), 'File "' . $tagPrefixTest . $entryIdentifier . '" still exists.');
-		$entryIdentifier = 'BackendFileTest2';
-		$this->assertTrue(!file_exists($tagPrefixTest . $entryIdentifier), 'File "' . $tagPrefixTest . $entryIdentifier . '" still exists.');
-		$this->assertTrue(!file_exists($tagPrefixSpecial . $entryIdentifier), 'File "' . $tagPrefixSpecial . $entryIdentifier . '" still exists.');
-		$entryIdentifier = 'BackendFileTest3';
-		$this->assertTrue(!file_exists($tagPrefixTest . $entryIdentifier), 'File "' . $tagPrefixTest . $entryIdentifier . '" still exists.');
 	}
 
 	/**
@@ -552,18 +445,10 @@
 	 * @author Ingo Renner <ingo@typo3.org>
 	 */
 	public function flushByTagRemovesCacheEntriesWithSpecifiedTag() {
-		$cacheIdentifier = 'UnitTestCache';
-		$cache = $this->getMock('t3lib_cache_frontend_AbstractFrontend',
-			array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove'),
-			array(),
-			'',
-			FALSE
-		);
-		$cache->expects($this->atLeastOnce())
-			->method('getIdentifier')
-			->will($this->returnValue($cacheIdentifier));
+		$mockCache = $this->getMock('t3lib_cache_frontend_AbstractFrontend', array(), array(), '', FALSE);
+		$mockCache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('UnitTestCache'));
 
-		$this->backend->setCache($cache);
+		$this->backend->setCache($mockCache);
 
 		$data = 'some data' . microtime();
 		$this->backend->set('BackendFileTest1', $data, array('UnitTestTag%test', 'UnitTestTag%boring'));
@@ -577,150 +462,21 @@
 		$this->assertTrue($this->backend->has('BackendFileTest3'), 'BackendFileTest3');
 	}
 
-
 	/**
-	 * @test
 	 * @author Robert Lemke <robert@typo3.org>
-	 * @author Karsten Dambekalns <karsten@typo3.org>
 	 * @author Ingo Renner <ingo@typo3.org>
 	 */
-	public function hasReturnsTheCorrectResultForEntryWithExceededLifetime() {
-		$cacheIdentifier = 'UnitTestCache';
-		$cache = $this->getMock('t3lib_cache_frontend_AbstractFrontend',
-			array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove'),
-			array(),
-			'',
-			FALSE
-		);
-		$cache->expects($this->atLeastOnce())
-			->method('getIdentifier')
-			->will($this->returnValue($cacheIdentifier));
-
-		$this->backend->setCache($cache);
-
-		$entryIdentifier = 'BackendFileTest';
-		$data = 'some data' . microtime();
-		$this->backend->set($entryIdentifier, $data);
-
-		$expiredEntryIdentifier = 'ExpiredBackendFileTest';
-		$expiredData = 'some old data' . microtime();
-		$this->backend->set($expiredEntryIdentifier, $expiredData, array(), 1);
-
-		sleep(2);
-
-		$this->assertFalse($this->backend->has($expiredEntryIdentifier), 'has() did not return FALSE.');
-	}
-
-	/**
-	 * @test
-	 * @author Karsten Dambekalns <karsten@typo3.org>
-	 * @author Ingo Renner <ingo@typo3.org>
-	 */
-	public function getReturnsFalseForEntryWithExceededLifetime() {
-		$cacheIdentifier = 'UnitTestCache';
-		$cache = $this->getMock('t3lib_cache_frontend_AbstractFrontend',
-			array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove'),
-			array(),
-			'',
-			FALSE
-		);
-		$cache->expects($this->atLeastOnce())
-			->method('getIdentifier')
-			->will($this->returnValue($cacheIdentifier));
-
-		$this->backend->setCache($cache);
-
-		$entryIdentifier = 'BackendFileTest';
-		$data = 'some data' . microtime();
-		$this->backend->set($entryIdentifier, $data);
-
-		$expiredEntryIdentifier = 'ExpiredBackendFileTest';
-		$expiredData = 'some old data' . microtime();
-		$this->backend->set($expiredEntryIdentifier, $expiredData, array(), 1);
-
-		sleep(2);
-
-		$this->assertEquals($data, $this->backend->get($entryIdentifier), 'The original and the retrieved data don\'t match.');
-		$this->assertFalse($this->backend->get($expiredEntryIdentifier), 'The expired entry could be loaded.');
-	}
-
-	/**
-	 * @test
-	 * @author Karsten Dambekalns <karsten@typo3.org>
-	 * @author Ingo Renner <ingo@typo3.org>
-	 */
-	public function findIdentifiersByTagReturnsEmptyArrayForEntryWithExceededLifetime() {
-		$cacheIdentifier = 'UnitTestCache';
-		$cache = $this->getMock('t3lib_cache_frontend_AbstractFrontend',
-			array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove'),
-			array(),
-			'',
-			FALSE
-		);
-		$cache->expects($this->atLeastOnce())
-			->method('getIdentifier')
-			->will($this->returnValue($cacheIdentifier));
-
-		$this->backend->setCache($cache);
-
-		$this->backend->set('BackendFileTest', 'some data', array('UnitTestTag%special'), 1);
-
-		sleep(2);
-
-		$this->assertEquals(array(), $this->backend->findIdentifiersByTag('UnitTestTag%special'));
-	}
-
-	/**
-	 * @test
-	 * @author Robert Lemke <robert@typo3.org>
-	 * @author Karsten Dambekalns <karsten@typo3.org>
-	 * @author Ingo Renner <ingo@typo3.org>
-	 */
-	public function setWithUnlimitedLifetimeWritesCorrectEntry() {
-		$cacheIdentifier = 'UnitTestCache';
-		$cache = $this->getMock('t3lib_cache_frontend_AbstractFrontend',
-			array('getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove'),
-			array(),
-			'',
-			FALSE
-		);
-		$cache->expects($this->atLeastOnce())
-			->method('getIdentifier')
-			->will($this->returnValue($cacheIdentifier));
-
-		$data = 'some data' . microtime();
-		$entryIdentifier = 'BackendFileTest';
-		$entryIdentifierHash = sha1($entryIdentifier);
-
-		$this->backend->setCache($cache);
-		$this->backend->set($entryIdentifier, $data, array(), 0);
-
-		$cacheDirectory = $this->backend->getCacheDirectory();
-
-		$pathAndFilename = $cacheDirectory
-			. 'data/'
-			. $cacheIdentifier . '/'
-			. $entryIdentifierHash[0] . '/'
-			. $entryIdentifierHash[1] . '/'
-			. $entryIdentifier;
-		$this->assertTrue(file_exists($pathAndFilename), 'File not found.');
-
-		$retrievedData = file_get_contents($pathAndFilename, NULL, NULL, t3lib_cache_backend_FileBackend::EXPIRYTIME_LENGTH);
-		$this->assertEquals($data, $retrievedData, 'The original and the retrieved data don\'t match.');
-	}
-
-	/**
-	 * @author Robert Lemke <robert@typo3.org>
-	 * @author Ingo Renner <ingo@typo3.org>
-	 */
 	public function tearDown() {
 		if (is_object($this->backend)) {
 			$directory = $this->backend->getCacheDirectory();
 			if (is_dir($directory)) {
-				t3lib_div::rmdir($directory, true);
+				t3lib_div::rmdir($directory, TRUE);
 			}
 		}
+		foreach ($this->backupGlobalVariables as $key => $data) {
+			$GLOBALS[$key] = $data;
+		}
 	}
 }
 
-?>
\ No newline at end of file
+?>
Index: t3lib/cache/frontend/class.t3lib_cache_frontend_phpfrontend.php
===================================================================
--- t3lib/cache/frontend/class.t3lib_cache_frontend_phpfrontend.php	(revision 0)
+++ t3lib/cache/frontend/class.t3lib_cache_frontend_phpfrontend.php	(revision 0)
@@ -0,0 +1,102 @@
+<?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!
+***************************************************************/
+
+
+/**
+ * A cache frontend tailored to PHP code.
+ *
+ * This file is a backport from FLOW3
+ *
+ * @package TYPO3
+ * @subpackage t3lib_cache
+ * @api
+ * @scope prototype
+ * @version $Id$
+ */
+class t3lib_cache_frontend_PhpFrontend extends t3lib_cache_frontend_StringFrontend {
+	/**
+	 * Constructs the cache
+	 *
+	 * @param string $identifier A identifier which describes this cache
+	 * @param t3lib_cache_backend_PhpCapableBackend $backend Backend to be used for this cache
+	 * @author Robert Lemke <robert@typo3.org>
+	 */
+	public function __construct($identifier, t3lib_cache_backend_PhpCapableBackend $backend) {
+		parent::__construct($identifier, $backend);
+	}
+
+	/**
+	 * Saves the PHP source code in the cache.
+	 *
+	 * @param string $entryIdentifier An identifier used for this cache entry, for example the class name
+	 * @param string $sourceCode PHP source code
+	 * @param array $tags Tags to associate with this cache entry
+	 * @param integer $lifetime Lifetime of this cache entry in seconds. If NULL is specified, the default lifetime is used. "0" means unlimited liftime.
+	 * @return void
+	 * @author Robert Lemke <robert@typo3.org>
+	 * @api
+	 */
+	public function set($entryIdentifier, $sourceCode, $tags = array(), $lifetime = NULL) {
+		if (!$this->isValidEntryIdentifier($entryIdentifier)) {
+			throw new InvalidArgumentException(
+				'"' . $entryIdentifier . '" is not a valid cache entry identifier.',
+				1264023823
+			);
+		}
+		if (!is_string($sourceCode)) {
+			throw new t3lib_cache_exception_InvalidData(
+				'The given source code is not a valid string.',
+				1264023824
+			);
+		}
+		foreach ($tags as $tag) {
+			if (!$this->isValidTag($tag)) {
+				throw new InvalidArgumentException(
+					'"' . $tag . '" is not a valid tag for a cache entry.',
+					1264023825
+				);
+			}
+		}
+		$sourceCode = '<?php' . chr(10) . $sourceCode . chr(10) . '__halt_compiler();';
+		$this->backend->set($entryIdentifier, $sourceCode, $tags, $lifetime);
+	}
+
+	/**
+	 * Loads PHP code from the cache and require_onces it right away.
+	 *
+	 * @param string $entryIdentifier An identifier which describes the cache entry to load
+	 * @return mixed Potential return value from the include operation
+	 * @author Robert Lemke <robert@typo3.org>
+	 * @api
+	 */
+	public function requireOnce($entryIdentifier) {
+		return $this->backend->requireOnce($entryIdentifier);
+	}
+}
+
+if (defined('TYPO3_MODE') && $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/cache/class.t3lib_cache_frontend_phpfrontend.php']) {
+	include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/cache/class.t3lib_cache_frontend_phpfrontend.php']);
+}
+
+?>
Index: t3lib/cache/backend/interfaces/interface.t3lib_cache_backend_phpcapablebackend.php
===================================================================
--- t3lib/cache/backend/interfaces/interface.t3lib_cache_backend_phpcapablebackend.php	(revision 0)
+++ t3lib/cache/backend/interfaces/interface.t3lib_cache_backend_phpcapablebackend.php	(revision 0)
@@ -0,0 +1,50 @@
+<?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.
+*  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!
+***************************************************************/
+
+
+/**
+ * A contract for a cache backend which is capable of storing, retrieving and
+ * including PHP source code.
+ *
+ * @version $Id$
+ * @api
+ * @author Robert Lemke <robert@typo3.org>
+ */
+interface t3lib_cache_backend_PhpCapableBackend extends t3lib_cache_backend_Backend {
+
+	/**
+	 * Loads PHP code from the cache and require_onces it right away.
+	 *
+	 * @param string $entryIdentifier An identifier which describes the cache entry to load
+	 * @return mixed Potential return value from the include operation
+	 * @api
+	 */
+	public function requireOnce($entryIdentifier);
+
+}
+
+?>
Index: t3lib/cache/backend/class.t3lib_cache_backend_filebackend.php
===================================================================
--- t3lib/cache/backend/class.t3lib_cache_backend_filebackend.php	(revision 7841)
+++ t3lib/cache/backend/class.t3lib_cache_backend_filebackend.php	(working copy)
@@ -33,23 +33,27 @@
  * @api
  * @version $Id$
  */
-class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBackend {
+class t3lib_cache_backend_FileBackend extends t3lib_cache_backend_AbstractBackend implements t3lib_cache_backend_PhpCapableBackend {
 
 	const SEPARATOR = '^';
 
 	const EXPIRYTIME_FORMAT = 'YmdHis';
 	const EXPIRYTIME_LENGTH = 14;
 
+	const DATASIZE_DIGITS = 10;
+
 	/**
 	 * @var string Directory where the files are stored
 	 */
 	protected $cacheDirectory = '';
 
+	/**
+	 * @var string Absolute path to root, usually document root of website
+	 */
 	protected $root = '/';
 
 	/**
 	 * Maximum allowed file path length in the current environment.
-	 * Will be set in initializeObject()
 	 *
 	 * @var integer
 	 */
@@ -63,18 +67,28 @@
 	public function __construct(array $options = array()) {
 		parent::__construct($options);
 
+		if (is_null($this->maximumPathLength)) {
+			$this->maximumPathLength = t3lib_div::getMaximumPathLength();
+		}
+	}
+
+	/**
+	 * Sets a reference to the cache frontend which uses this backend and
+	 * initializes the default cache directory
+	 *
+	 * @void
+	 * @author Robert Lemke <robert@typo3.org>
+	 */
+	public function setCache(t3lib_cache_frontend_frontend $cache) {
+		parent::setCache($cache);
+
 		if (empty($this->cacheDirectory)) {
 			$cacheDirectory = 'typo3temp/cache/';
 			try {
 				$this->setCacheDirectory($cacheDirectory);
 			} catch(t3lib_cache_Exception $exception) {
-
 			}
 		}
-
-		if (is_null($this->maximumPathLength)) {
-			$this->maximumPathLength = t3lib_div::getMaximumPathLength();
-		}
 	}
 
 	/**
@@ -92,8 +106,6 @@
 		$documentRoot = PATH_site;
 
 		if (($open_basedir = ini_get('open_basedir'))) {
-
-
 			if (TYPO3_OS === 'WIN') {
 				$delimiter = ';';
 				$cacheDirectory = str_replace('\\', '/', $cacheDirectory);
@@ -107,10 +119,9 @@
 					$cacheDirectory = PATH_site . $cacheDirectory;
 				}
 			}
-			$basedirs = explode($delimiter, $open_basedir);
 
+			$basedirs = explode($delimiter, $open_basedir);
 			$cacheDirectoryInBaseDir = FALSE;
-
 			foreach ($basedirs as $basedir) {
 				if (TYPO3_OS === 'WIN') {
 					$basedir = str_replace('\\', '/', $basedir);
@@ -125,7 +136,6 @@
 					break;
 				}
 			}
-
 			if (!$cacheDirectoryInBaseDir) {
 				throw new t3lib_cache_Exception(
 					'Open_basedir restriction in effect. The directory "' . $cacheDirectory . '" is not in an allowed path.'
@@ -133,20 +143,22 @@
 			}
 		} else {
 			if ($cacheDirectory[0] == '/') {
-					// absolute path to cache directory.
+					// Absolute path to cache directory.
 				$documentRoot = '/';
 			}
-
 			if (TYPO3_OS === 'WIN') {
 				$documentRoot = '';
 			}
 		}
 
-		// after this point all paths have '/' as directory seperator
-
+			// After this point all paths have '/' as directory seperator
 		if ($cacheDirectory[strlen($cacheDirectory) - 1] !== '/') {
 			$cacheDirectory .= '/';
 		}
+		$cacheDirectory .= $this->cacheIdentifier;
+		if ($cacheDirectory[strlen($cacheDirectory) - 1] !== '/') {
+			$cacheDirectory .= '/';
+		}
 
 		if (!is_writable($documentRoot . $cacheDirectory)) {
 			t3lib_div::mkdir_deep(
@@ -154,14 +166,12 @@
 				$cacheDirectory
 			);
 		}
-
 		if (!is_dir($documentRoot . $cacheDirectory)) {
 			throw new t3lib_cache_Exception(
 				'The directory "' . $documentRoot . $cacheDirectory . '" does not exist.',
 				1203965199
 			);
 		}
-
 		if (!is_writable($documentRoot . $cacheDirectory)) {
 			throw new t3lib_cache_Exception(
 				'The directory "' . $documentRoot . $cacheDirectory . '" is not writable.',
@@ -169,16 +179,6 @@
 			);
 		}
 
-		$tagsDirectory = $cacheDirectory . 'tags/';
-
-
-
-		if (!is_writable($documentRoot . $tagsDirectory)) {
-			t3lib_div::mkdir_deep(
-				$documentRoot,
-				$tagsDirectory
-			);
-		}
 		$this->root = $documentRoot;
 		$this->cacheDirectory =  $cacheDirectory;
 	}
@@ -188,6 +188,7 @@
 	 *
 	 * @return string Full path of the cache directory
 	 * @author Robert Lemke <robert@typo3.org>
+	 * @api
 	 */
 	public function getCacheDirectory() {
 		return $this->root . $this->cacheDirectory;
@@ -196,14 +197,15 @@
 	/**
 	 * Saves data in a cache file.
 	 *
-	 * @param string An identifier for this specific cache entry
-	 * @param string The data to be stored
-	 * @param array Tags to associate with this cache entry
-	 * @param integer Lifetime of this cache entry in seconds. If NULL is specified, the default lifetime is used. "0" means unlimited lifetime.
+	 * @param string $entryIdentifier An identifier for this specific cache entry
+	 * @param string $data The data to be stored
+	 * @param array $tags Tags to associate with this cache entry
+	 * @param integer $lifetime Lifetime of this cache entry in seconds. If NULL is specified, the default lifetime is used. "0" means unlimited lifetime.
 	 * @return void
 	 * @throws t3lib_cache_Exception if the directory does not exist or is not writable or exceeds the maximum allowed path length, or if no cache frontend has been set.
 	 * @throws t3lib_cache_exception_InvalidData if the data to bes stored is not a string.
 	 * @author Robert Lemke <robert@typo3.org>
+	 * @api
 	 */
 	public function set($entryIdentifier, $data, array $tags = array(), $lifetime = NULL) {
 		if (!$this->cache instanceof t3lib_cache_frontend_Frontend) {
@@ -220,157 +222,92 @@
 			);
 		}
 
-		$expirytime = $this->calculateExpiryTime($lifetime);
-		$cacheEntryPath = $this->renderCacheEntryPath($entryIdentifier);
-		$absCacheEntryPath = $this->root . $cacheEntryPath;
-
-
-		if (!is_writable($absCacheEntryPath)) {
-			try {
-				t3lib_div::mkdir_deep(
-					$this->root,
-					$cacheEntryPath
-				);
-			} catch(Exception $exception) {
-
-			}
-
-			if (!is_writable($absCacheEntryPath)) {
-				throw new t3lib_cache_Exception(
-					'The cache directory "' . $absCacheEntryPath . '" could not be created.',
-					1204026250
-				);
-			}
-		}
-
 		$this->remove($entryIdentifier);
 
-		$data = $expirytime->format(self::EXPIRYTIME_FORMAT) . $data;
-		$cacheEntryPathAndFilename = $absCacheEntryPath . uniqid() . '.temp';
-		if (strlen($cacheEntryPathAndFilename) > $this->maximumPathLength) {
+		$temporaryCacheEntryPathAndFilename = $this->root . $this->cacheDirectory . uniqid() . '.temp';
+		if (strlen($temporaryCacheEntryPathAndFilename) > $this->maximumPathLength) {
 			throw new t3lib_cache_Exception(
-				'The length of the temporary cache file path "' . $cacheEntryPathAndFilename .
-					'" is ' . strlen($cacheEntryPathAndFilename) . ' characters long and exceeds the maximum path length of ' .
+				'The length of the temporary cache file path "' . $temporaryCacheEntryPathAndFilename .
+					'" is ' . strlen($temporaryCacheEntryPathAndFilename) . ' characters long and exceeds the maximum path length of ' .
 					$this->maximumPathLength . '. Please consider setting the temporaryDirectoryBase option to a shorter path. ',
 				1248710426
 			);
 		}
-		$result = file_put_contents($cacheEntryPathAndFilename, $data);
+
+		$expiryTime = ($lifetime === NULL) ? 0 : ($GLOBALS['EXEC_TIME'] + $lifetime);
+		$metaData = str_pad($expiryTime, self::EXPIRYTIME_LENGTH) . implode(' ', $tags) . str_pad(strlen($data), self::DATASIZE_DIGITS);
+		$result = file_put_contents($temporaryCacheEntryPathAndFilename, $data . $metaData);
+
 		if ($result === FALSE) {
-			throw new t3lib_cache_Exception(
-				'The temporary cache file "' . $cacheEntryPathAndFilename . '" could not be written.',
+			throw new t3lib_cache_exception(
+				'The temporary cache file "' . $temporaryCacheEntryPathAndFilename . '" could not be written.',
 				1204026251
 			);
 		}
 
-		for ($i = 0; $i < 5; $i++) {
-			$result = rename($cacheEntryPathAndFilename, $absCacheEntryPath . $entryIdentifier);
-			if ($result === TRUE) {
-				break;
-			}
+		$i = 0;
+		$cacheEntryPathAndFilename = $this->root . $this->cacheDirectory . $entryIdentifier;
+			// @TODO: Figure out why the heck this is done and maybe find a smarter solution, report to FLOW3
+		while (!rename($temporaryCacheEntryPathAndFilename, $cacheEntryPathAndFilename) && $i < 5) {
+			$i++;
 		}
 
+			// @FIXME: At least the result of rename() should be handled here, report to FLOW3
 		if ($result === FALSE) {
-			throw new t3lib_cache_Exception(
-				'The cache file "' . $entryIdentifier . '" could not be written.',
+			throw new t3lib_cache_exception(
+				'The cache file "' . $cacheEntryPathAndFilename . '" could not be written.',
 				1222361632
 			);
 		}
-
-		foreach ($tags as $tag) {
-			$this->setTag($entryIdentifier, $tag);
-		}
 	}
 
 	/**
-	 * Creates a tag that is associated with the given cache identifier
-	 *
-	 * @param string $entryIdentifier An identifier for this specific cache entry
-	 * @param string $tag Tag to associate with this cache entry
-	 * @return void
-	 * @throws t3lib_cache_Exception if the tag path is not writable or exceeds the maximum allowed path length
-	 * @author Bastian Waidelich <bastian@typo3.org>
-	 * @author Ingo Renner <ingo@typo3.org>
-	 */
-	protected function setTag($entryIdentifier, $tag) {
-		$tagPath = $this->cacheDirectory . 'tags/' . $tag . '/';
-		$absTagPath = $this->root . $tagPath;
-		if (!is_writable($absTagPath)) {
-			t3lib_div::mkdir_deep($this->root, $tagPath);
-			if (!is_writable($absTagPath)) {
-				throw new t3lib_cache_Exception(
-					'The tag directory "' . $absTagPath . '" could not be created.',
-					1238242144
-				);
-			}
-		}
-
-		$tagPathAndFilename = $absTagPath . $this->cacheIdentifier
-			. self::SEPARATOR . $entryIdentifier;
-		if (strlen($tagPathAndFilename) > $this->maximumPathLength) {
-			throw new t3lib_cache_Exception(
-				'The length of the tag path "' . $tagPathAndFilename . '" is ' . strlen($tagPathAndFilename) .
-					' characters long and exceeds the maximum path length of ' . $this->maximumPathLength .
-					'. Please consider setting the temporaryDirectoryBase option to a shorter path. ',
-				1248710426
-			);
-		}
-		touch($tagPathAndFilename);
-	}
-
-	/**
 	 * Loads data from a cache file.
 	 *
-	 * @param string An identifier which describes the cache entry to load
+	 * @param string $entryIdentifier An identifier which describes the cache entry to load
 	 * @return mixed The cache entry's content as a string or FALSE if the cache entry could not be loaded
 	 * @author Robert Lemke <robert@typo3.org>
 	 * @author Karsten Dambekalns <karsten@typo3.org>
+	 * @api
 	 */
 	public function get($entryIdentifier) {
-		$pathAndFilename = $this->root . $this->renderCacheEntryPath($entryIdentifier) . $entryIdentifier;
-		return ($this->isCacheFileExpired($pathAndFilename)) ? FALSE : file_get_contents($pathAndFilename, NULL, NULL, self::EXPIRYTIME_LENGTH);
+		$pathAndFilename = $this->root . $this->cacheDirectory . $entryIdentifier;
+		if ($this->isCacheFileExpired($pathAndFilename)) {
+			return FALSE;
+		}
+		$dataSize = (integer)file_get_contents($pathAndFilename, NULL, NULL, filesize($pathAndFilename) - self::DATASIZE_DIGITS, self::DATASIZE_DIGITS);
+		return file_get_contents($pathAndFilename, NULL, NULL, 0, $dataSize);
 	}
 
 	/**
 	 * Checks if a cache entry with the specified identifier exists.
 	 *
-	 * @param	string $entryIdentifier
-	 * @return	boolean TRUE if such an entry exists, FALSE if not
+	 * @param string $entryIdentifier Specifies the cache entry to remove
+	 * @return boolean TRUE if (at least) an entry could be removed or FALSE if no entry was found
 	 * @author Robert Lemke <robert@typo3.org>
+	 * @api
 	 */
 	public function has($entryIdentifier) {
-		return !$this->isCacheFileExpired($this->root . $this->renderCacheEntryPath($entryIdentifier) . $entryIdentifier);
+		return !$this->isCacheFileExpired($this->root . $this->cacheDirectory . $entryIdentifier);
 	}
 
 	/**
 	 * Removes all cache entries matching the specified identifier.
 	 * Usually this only affects one entry.
 	 *
-	 * @param string Specifies the cache entry to remove
+	 * @param string $entryIdentifier Specifies the cache entry to remove
 	 * @return boolean TRUE if (at least) an entry could be removed or FALSE if no entry was found
 	 * @author Robert Lemke <robert@typo3.org>
+	 * @api
 	 */
 	public function remove($entryIdentifier) {
-		$pathAndFilename = $this->root . $this->renderCacheEntryPath($entryIdentifier) . $entryIdentifier;
-
+		$pathAndFilename = $this->root . $this->cacheDirectory . $entryIdentifier;
 		if (!file_exists($pathAndFilename)) {
 			return FALSE;
 		}
-
 		if (unlink($pathAndFilename) === FALSE) {
 			return FALSE;
 		}
-
-		foreach($this->findTagFilesByEntry($entryIdentifier) as $pathAndFilename) {
-			if (!file_exists($pathAndFilename)) {
-				return FALSE;
-			}
-
-			if (unlink($pathAndFilename) === FALSE) {
-				return FALSE;
-			}
-		}
-
 		return TRUE;
 	}
 
@@ -378,63 +315,63 @@
 	 * Finds and returns all cache entry identifiers which are tagged by the
 	 * specified tag.
 	 *
-	 * @param string The tag to search for
+	 * @param string $searchedTag The tag to search for
 	 * @return array An array with identifiers of all matching entries. An empty array if no entries matched
 	 * @author Robert Lemke <robert@typo3.org>
 	 * @author Karsten Dambekalns <karsten@typo3.org>
+	 * @api
 	 */
-	public function findIdentifiersByTag($tag) {
-		if (!$this->cache instanceof t3lib_cache_frontend_Frontend) {
-			throw new t3lib_cache_Exception(
-				'Yet no cache frontend has been set via setCache().',
-				1204111376
-			);
-		}
+	public function findIdentifiersByTag($searchedTag) {
+		$entryIdentifiers = array();
+		$now = $GLOBALS['EXEC_TIME'];
+		for ($directoryIterator = t3lib_div::makeInstance('DirectoryIterator', $this->root . $this->cacheDirectory); $directoryIterator->valid(); $directoryIterator->next()) {
+			if ($directoryIterator->isDot()) {
+				continue;
+			}
+			$cacheEntryPathAndFilename = $directoryIterator->getPathname();
+			$index = (integer)file_get_contents($cacheEntryPathAndFilename, NULL, NULL, filesize($cacheEntryPathAndFilename) - self::DATASIZE_DIGITS, self::DATASIZE_DIGITS);
+			$metaData = file_get_contents($cacheEntryPathAndFilename, NULL, NULL, $index);
 
-		$path = $this->root . $this->cacheDirectory . 'tags/';
-		$pattern = $path . $tag . '/' . $this->cacheIdentifier . self::SEPARATOR . '*';
-		$filesFound = glob($pattern);
-
-		if ($filesFound === FALSE || count($filesFound) === 0) {
-			return array();
-		}
-
-		$cacheEntries = array();
-		foreach ($filesFound as $filename) {
-			list(,$entryIdentifier) = explode(self::SEPARATOR, basename($filename));
-			if ($this->has($entryIdentifier)) {
-				$cacheEntries[$entryIdentifier] = $entryIdentifier;
+			$expiryTime = (integer)substr($metaData, 0, self::EXPIRYTIME_LENGTH);
+			if ($expiryTime !== 0 && $expiryTime < $now) {
+				continue;
 			}
+			if (in_array($searchedTag, explode(' ', substr($metaData, self::EXPIRYTIME_LENGTH, -self::DATASIZE_DIGITS)))) {
+				$entryIdentifiers[] = $directoryIterator->getFilename();
+			}
 		}
-
-		return array_values($cacheEntries);
+		return $entryIdentifiers;
 	}
 
 	/**
 	 * Finds and returns all cache entry identifiers which are tagged by the
 	 * specified tags.
 	 *
-	 * @param array Array of tags to search for
+	 * @param array $searchedTags Array of tags to search for
 	 * @return array An array with identifiers of all matching entries. An empty array if no entries matched
 	 * @author Ingo Renner <ingo@typo3.org>
+	 * @author Christian Kuhn <lolli@schwarzbu.ch>
+	 * @api
 	 */
-	public function findIdentifiersByTags(array $tags) {
-		$taggedEntries = array();
-		$foundEntries  = array();
+	public function findIdentifiersByTags(array $searchedTags) {
+		$entryIdentifiers = array();
+		for ($directoryIterator = t3lib_div::makeInstance('DirectoryIterator', $this->root . $this->cacheDirectory); $directoryIterator->valid(); $directoryIterator->next()) {
+			if ($directoryIterator->isDot()) {
+				continue;
+			}
+			$cacheEntryPathAndFilename = $directoryIterator->getPathname();
+			$index = (integer)file_get_contents($cacheEntryPathAndFilename, NULL, NULL, filesize($cacheEntryPathAndFilename) - self::DATASIZE_DIGITS, self::DATASIZE_DIGITS);
+			$metaData = file_get_contents($cacheEntryPathAndFilename, NULL, NULL, $index);
 
-		foreach ($tags as $tag) {
-			$taggedEntries[$tag] = $this->findIdentifiersByTag($tag);
-		}
-
-		$intersectedTaggedEntries = call_user_func_array('array_intersect', $taggedEntries);
-
-		foreach ($intersectedTaggedEntries as $entryIdentifier) {
-			if ($this->has($entryIdentifier)) {
-				$foundEntries[$entryIdentifier] = $entryIdentifier;
+			$expiryTime = (integer)substr($metaData, 0, self::EXPIRYTIME_LENGTH);
+			if ($expiryTime !== 0 && $expiryTime < $GLOBALS['EXEC_TIME']) {
+				continue;
 			}
+			if (in_array($searchedTags, explode(' ', substr($metaData, self::EXPIRYTIME_LENGTH, -self::DATASIZE_DIGITS)))) {
+				$entryIdentifiers[] = $directoryIterator->getFilename();
+			}
 		}
-
-		return $foundEntries;
+		return $entryIdentifiers;
 	}
 
 	/**
@@ -442,28 +379,20 @@
 	 *
 	 * @return void
 	 * @author Robert Lemke <robert@typo3.org>
+	 * @author Christian Kuhn <lolli@schwarzbu.ch>
+	 * @api
 	 */
 	public function flush() {
-		if (!$this->cache instanceof t3lib_cache_frontend_Frontend) {
-			throw new t3lib_cache_Exception(
-				'Yet no cache frontend has been set via setCache().',
-				1204111376
-			);
-		}
-
-		$dataPath = $this->root . $this->cacheDirectory . 'data/' . $this->cacheIdentifier . '/';
-		$tagsPath = $this->root . $this->cacheDirectory . 'tags/';
-
-		t3lib_div::rmdir($dataPath, true);
-		t3lib_div::rmdir($tagsPath, true);
+		t3lib_div::rmdir($this->root . $this->cacheDirectory, TRUE);
 	}
 
 	/**
 	 * Removes all cache entries of this cache which are tagged by the specified tag.
 	 *
-	 * @param string The tag the entries must have
+	 * @param string $tag The tag the entries must have
 	 * @return void
 	 * @author Ingo Renner <ingo@typo3.org>
+	 * @api
 	 */
 	public function flushByTag($tag) {
 		$identifiers = $this->findIdentifiersByTag($tag);
@@ -479,9 +408,10 @@
 	/**
 	 * Removes all cache entries of this cache which are tagged by the specified tag.
 	 *
-	 * @param array	The tags the entries must have
+	 * @param array $tags The tags the entries must have
 	 * @return void
 	 * @author Ingo Renner <ingo@typo3.org>
+	 * @api
 	 */
 	public function flushByTags(array $tags) {
 		foreach ($tags as $tag) {
@@ -493,13 +423,17 @@
 	 * Checks if the given cache entry files are still valid or if their
 	 * lifetime has exceeded.
 	 *
-	 * @param	string	$cacheFilename
-	 * @return	boolean
+	 * @param string $cacheEntryPathAndFilename
+	 * @return boolean
 	 * @author Robert Lemke <robert@typo3.org>
 	 */
-	protected function isCacheFileExpired($cacheFilename) {
-		$timestamp = (file_exists($cacheFilename)) ? file_get_contents($cacheFilename, NULL, NULL, 0, self::EXPIRYTIME_LENGTH) : 1;
-		return $timestamp < gmdate(self::EXPIRYTIME_FORMAT);
+	protected function isCacheFileExpired($cacheEntryPathAndFilename) {
+		if (!file_exists($cacheEntryPathAndFilename)) {
+			return TRUE;
+		}
+		$index = (integer)file_get_contents($cacheEntryPathAndFilename, NULL, NULL, filesize($cacheEntryPathAndFilename) - self::DATASIZE_DIGITS, self::DATASIZE_DIGITS);
+		$expiryTime = file_get_contents($cacheEntryPathAndFilename, NULL, NULL, $index, self::EXPIRYTIME_LENGTH);
+		return ($expiryTime != 0 && $expiryTime < $GLOBALS['EXEC_TIME']);
 	}
 
 	/**
@@ -507,6 +441,7 @@
 	 *
 	 * @return void
 	 * @author Karsten Dambekalns <karsten@typo3.org>
+	 * @api
 	 */
 	public function collectGarbage() {
 		if (!$this->cache instanceof t3lib_cache_frontend_Frontend) {
@@ -516,31 +451,19 @@
 			);
 		}
 
-		$pattern = $this->root . $this->cacheDirectory . 'data/' . $this->cacheIdentifier . '/*/*/*';
+		$pattern = $this->root . $this->cacheDirectory . '*';
 		$filesFound = glob($pattern);
 
-		foreach ($filesFound as $cacheFilename) {
-			if ($this->isCacheFileExpired($cacheFilename)) {
-				$this->remove(basename($cacheFilename));
+		if (is_array($filesFound)) {
+			foreach ($filesFound as $cacheFilename) {
+				if ($this->isCacheFileExpired($cacheFilename)) {
+					$this->remove(basename($cacheFilename));
+ 				}
  			}
- 		}
+		}
 	}
 
 	/**
-	 * Renders the full path (excluding file name) leading to the given cache entry.
-	 * Doesn't check if such a cache entry really exists.
-	 *
-	 * @param string $identifier Identifier for the cache entry
-	 * @return string Absolute path leading to the directory containing the cache entry
-	 * @author Robert Lemke <robert@typo3.org>
-	 * @internal
-	 */
-	protected function renderCacheEntryPath($identifier) {
-		$identifierHash = sha1($identifier);
-		return $this->cacheDirectory . 'data/' . $this->cacheIdentifier . '/' . $identifierHash[0] . '/' . $identifierHash[1] . '/';
-	}
-
-	/**
 	 * Tries to find the cache entry for the specified identifier.
 	 * Usually only one cache entry should be found - if more than one exist, this
 	 * is due to some error or crash.
@@ -559,7 +482,7 @@
 			);
 		}
 
-		$pattern = $this->root . $this->renderCacheEntryPath($entryIdentifier) . $entryIdentifier;
+		$pattern = $this->root . $this->cacheDirectory . $entryIdentifier;
 		$filesFound = glob($pattern);
 		if ($filesFound === FALSE || count($filesFound) === 0) {
 			return FALSE;
@@ -568,28 +491,16 @@
 		return $filesFound;
 	}
 
-
 	/**
-	 * Tries to find the tag entries for the specified cache entry.
+	 * Loads PHP code from the cache and require_onces it right away.
 	 *
-	 * @param string $entryIdentifier The cache entry identifier to find tag files for
-	 * @return array The file names (including path)
-	 * @author Robert Lemke <robert@typo3.org>
-	 * @throws t3lib_cache_Exception if no frontend has been set
-	 * @internal
+	 * @param string $entryIdentifier An identifier which describes the cache entry to load
+	 * @return mixed Potential return value from the include operation
+	 * @api
 	 */
-	protected function findTagFilesByEntry($entryIdentifier) {
-		if (!$this->cache instanceof t3lib_cache_frontend_Frontend) {
-			throw new t3lib_cache_Exception(
-				'Yet no cache frontend has been set via setCache().',
-				1204111376
-			);
-		}
-
-		$path = $this->root . $this->cacheDirectory . 'tags/';
-		$pattern = $path . '*/' . $this->cacheIdentifier . self::SEPARATOR . $entryIdentifier;
-		$tagFilesFound = glob($pattern);
-		return ($tagFilesFound ? $tagFilesFound : array());
+	public function requireOnce($entryIdentifier) {
+		$pathAndFilename = $this->root . $this->cacheDirectory . $entryIdentifier;
+		return ($this->isCacheFileExpired($pathAndFilename)) ? FALSE : require_once($pathAndFilename);
 	}
 }
 
Index: t3lib/core_autoload.php
===================================================================
--- t3lib/core_autoload.php	(revision 7841)
+++ t3lib/core_autoload.php	(working copy)
@@ -94,6 +94,7 @@
 	't3lib_cache_backend_pdobackend' => PATH_t3lib . 'cache/backend/class.t3lib_cache_backend_pdobackend.php',
 	't3lib_cache_backend_transientmemorybackend' => PATH_t3lib . 'cache/backend/class.t3lib_cache_backend_transientmemorybackend.php',
 	't3lib_cache_backend_backend' => PATH_t3lib . 'cache/backend/interfaces/interface.t3lib_cache_backend_backend.php',
+	't3lib_cache_backend_phpcapablebackend' => PATH_t3lib . 'cache/backend/interfaces/interface.t3lib_cache_backend_phpcapablebackend.php',
 	't3lib_cache_exception_classalreadyloaded' => PATH_t3lib . 'cache/exception/class.t3lib_cache_exception_classalreadyloaded.php',
 	't3lib_cache_exception_duplicateidentifier' => PATH_t3lib . 'cache/exception/class.t3lib_cache_exception_duplicateidentifier.php',
 	't3lib_cache_exception_invalidbackend' => PATH_t3lib . 'cache/exception/class.t3lib_cache_exception_invalidbackend.php',
@@ -101,6 +102,7 @@
 	't3lib_cache_exception_invaliddata' => PATH_t3lib . 'cache/exception/class.t3lib_cache_exception_invaliddata.php',
 	't3lib_cache_exception_nosuchcache' => PATH_t3lib . 'cache/exception/class.t3lib_cache_exception_nosuchcache.php',
 	't3lib_cache_frontend_abstractfrontend' => PATH_t3lib . 'cache/frontend/class.t3lib_cache_frontend_abstractfrontend.php',
+	't3lib_cache_frontend_phpfrontend' => PATH_t3lib . 'cache/frontend/class.t3lib_cache_frontend_phpfrontend.php',
 	't3lib_cache_frontend_stringfrontend' => PATH_t3lib . 'cache/frontend/class.t3lib_cache_frontend_stringfrontend.php',
 	't3lib_cache_frontend_variablefrontend' => PATH_t3lib . 'cache/frontend/class.t3lib_cache_frontend_variablefrontend.php',
 	't3lib_cache_frontend_frontend' => PATH_t3lib . 'cache/frontend/interfaces/interface.t3lib_cache_frontend_frontend.php',
