[TASK] Order the methods of stdWrap unit tests alphabetically 42/48842/4
authorElmar Hinz <t3elmar@gmail.com>
Thu, 7 Jul 2016 11:42:29 +0000 (13:42 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Thu, 7 Jul 2016 14:56:08 +0000 (16:56 +0200)
- Put the unit test methods of stdWrap into an alphabetical order.
- Don't touch any method comments.
- Dont't touch any method bodys.

Releases: master
Resolves: #76981
Change-Id: I2702942cc22cb5fa956017339580914bc3894508
Reviewed-on: https://review.typo3.org/48842
Tested-by: Bamboo TYPO3com <info@typo3.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/frontend/Tests/Unit/ContentObject/ContentObjectRendererTest.php

index 6c6a9ab..16f5249 100644 (file)
@@ -160,6 +160,14 @@ class ContentObjectRendererTest extends UnitTestCase
     //////////////////////
 
     /**
+     * @return TypoScriptFrontendController
+     */
+    protected function getFrontendController()
+    {
+        return $GLOBALS['TSFE'];
+    }
+
+    /**
      * Avoid logging to the file system (file writer is currently the only configured writer)
      */
     protected function createMockedLoggerAndLogManager()
@@ -508,42 +516,12 @@ class ContentObjectRendererTest extends UnitTestCase
     }
 
     //////////////////////////////
+
+    //////////////////////////////
     // Tests concerning cropHTML
     //////////////////////////////
 
     /**
-     * Check if stdWrap_cropHTML works properly.
-     *
-     * Show:
-     *
-     * - Delegates to method cropHTML.
-     * - Parameter 1 is $content.
-     * - Parameter 2 is $conf['cropHTML'].
-     * - Returns the return value.
-     *
-     * @test
-     * @return void
-     */
-    public function stdWrap_cropHTML()
-    {
-        $content = $this->getUniqueId('content');
-        $conf = [
-            'cropHTML' => $this->getUniqueId('cropHTML'),
-            'cropHTML.' => $this->getUniqueId('not used'),
-        ];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['cropHTML'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('cropHTML')
-            ->with($content, $conf['cropHTML'])
-            ->willReturn($return);
-        $this->assertSame($return,
-            $subject->stdWrap_cropHTML($content, $conf));
-    }
-
-    /**
      * Data provider for cropHTML.
      *
      * Provides combinations of text type and configuration.
@@ -796,6770 +774,6802 @@ class ContentObjectRendererTest extends UnitTestCase
     }
 
     /**
-     * Data provider for stdWrap_cacheRead
+     * Data provider for round
      *
-     * @return array Order: expect, input, conf, times, with, will
+     * @return array [$expect, $contet, $conf]
      */
-    public function stdWrap_cacheReadDataProvider()
+    public function roundDataProvider()
     {
-        $cacheConf = [$this->getUniqueId('cache.')];
-        $conf = ['cache.' => $cacheConf];
         return [
-            'no conf' => [
-                'content', 'content', [],
-                0, null, null,
-            ],
-            'no cache. conf' => [
-                'content', 'content', ['otherConf' => 1],
-                0, null, null,
+            // floats
+            'down' => [1.0, 1.11, []],
+            'up' => [2.0, 1.51, []],
+            'rounds up from x.50' => [2.0, 1.50, []],
+            'down with decimals' => [0.12, 0.1231, ['decimals' => 2]],
+            'up with decimals' => [0.13, 0.1251, ['decimals' => 2]],
+            'ceil' => [1.0, 0.11, ['roundType' => 'ceil']],
+            'ceil does not accept decimals' => [
+                1.0, 0.111, [
+                    'roundType' => 'ceil',
+                    'decimals' => 2,
+                ],
             ],
-            'non-cached simulation' => [
-                'content', 'content', $conf,
-                1, $cacheConf, false,
+            'floor' => [2.0, 2.99, ['roundType' => 'floor']],
+            'floor does not accept decimals' => [
+                2.0, 2.999, [
+                    'roundType' => 'floor',
+                    'decimals' => 2,
+                ],
             ],
-            'cached simulation' => [
-                'cachedContent', 'content', $conf,
-                1, $cacheConf, 'cachedContent',
+            'round, down' => [1.0, 1.11, ['roundType' => 'round']],
+            'round, up' => [2.0, 1.55, ['roundType' => 'round']],
+            'round does accept decimals' => [
+                5.56, 5.5555, [
+                    'roundType' => 'round',
+                    'decimals' => 2,
+                ],
             ],
+            // strings
+            'emtpy string' => [0.0, '', []],
+            'word string' => [0.0, 'word', []],
+            'float string' => [1.0, '1.123456789', []],
+            // other types
+            'null' => [0.0, null, []],
+            'false' => [0.0, false, []],
+            'true' => [1.0, true, []]
         ];
     }
 
     /**
-     * Check if stdWrap_cacheRead works properly.
+     * Check if round works properly
      *
-     * - the method branches correctly
-     * - getFromCache is called to fetch from cache
-     * - $conf['cache.'] is passed on as parameter
+     * Show:
      *
-     * @test
-     * @dataProvider stdWrap_cacheReadDataProvider
-     * @param string $expect Expected result.
-     * @param string $input Given input string.
-     * @param array $conf Property 'cache.'
-     * @param int $times Times called mocked method.
-     * @param array $with Parameter passed to mocked method.
-     * @param string|false $will Return value of mocked method.
+     *  - Different types of input are casted to float.
+     *  - Configuration ceil rounds like ceil().
+     *  - Configuration floor rounds like floor().
+     *  - Otherwise rounds like round() and decimals can be applied.
+     *  - Always returns float.
+     *
+     * @param float $expected The expected output.
+     * @param mixed $content The given content.
+     * @param array $conf The given configuration of 'round.'.
      * @return void
+     * @dataProvider roundDataProvider
+     * @test
      */
-    public function stdWrap_cacheRead(
-        $expect, $input, $conf, $times, $with, $will)
+    public function round($expect, $content, $conf)
     {
-        $subject = $this->getAccessibleMock(
-            ContentObjectRenderer::class, ['getFromCache']);
-        $subject
-            ->expects($this->exactly($times))
-            ->method('getFromCache')
-            ->with($with)
-            ->willReturn($will);
         $this->assertSame($expect,
-            $subject->stdWrap_cacheRead($input, $conf));
+            $this->subject->_call('round', $content, $conf));
     }
 
     /**
-     * Data provider for fourTypesOfStdWrapHookObjectProcessors
+     * @test
+     */
+    public function recursiveStdWrapProperlyRendersBasicString()
+    {
+        $stdWrapConfiguration = array(
+            'noTrimWrap' => '|| 123|',
+            'stdWrap.' => array(
+                'wrap' => '<b>|</b>'
+            )
+        );
+        $this->assertSame(
+            '<b>Test</b> 123',
+            $this->subject->stdWrap('Test', $stdWrapConfiguration)
+        );
+    }
+
+    /**
+     * @test
+     */
+    public function recursiveStdWrapIsOnlyCalledOnce()
+    {
+        $stdWrapConfiguration = array(
+            'append' => 'TEXT',
+            'append.' => array(
+                'data' => 'register:Counter'
+            ),
+            'stdWrap.' => array(
+                'append' => 'LOAD_REGISTER',
+                'append.' => array(
+                    'Counter.' => array(
+                        'prioriCalc' => 'intval',
+                        'cObject' => 'TEXT',
+                        'cObject.' => array(
+                            'data' => 'register:Counter',
+                            'wrap' => '|+1',
+                        )
+                    )
+                )
+            )
+        );
+        $this->assertSame(
+            'Counter:1',
+            $this->subject->stdWrap('Counter:', $stdWrapConfiguration)
+        );
+    }
+
+    /**
+     * Data provider for numberFormat.
      *
-     * @return array Order: stdWrap, hookObjectCall
+     * @return array [$expect, $content, $conf]
      */
-    public function fourTypesOfStdWrapHookObjectProcessorsDataProvider()
+    public function numberFormatDataProvider()
     {
         return [
-            'preProcess' => [
-                'stdWrap_stdWrapPreProcess', 'stdWrapPreProcess'
+            'testing decimals' => [
+                '0.80', 0.8,
+                ['decimals' => 2]
             ],
-            'override' => [
-                'stdWrap_stdWrapOverride', 'stdWrapOverride'
+            'testing decimals with input as string' => [
+                '0.80', '0.8',
+                ['decimals' => 2]
             ],
-            'process' => [
-                'stdWrap_stdWrapProcess', 'stdWrapProcess'
+            'testing dec_point' => [
+                '0,8', 0.8,
+                ['decimals' => 1, 'dec_point' => ',']
             ],
-            'postProcess' => [
-                'stdWrap_stdWrapPostProcess', 'stdWrapPostProcess'
+            'testing thousands_sep' => [
+                '1.000', 999.99,
+                [
+                    'decimals' => 0,
+                    'thousands_sep.' => ['char' => 46]
+                ]
             ],
+            'testing mixture' => [
+                '1.281.731,5', 1281731.45,
+                [
+                    'decimals' => 1,
+                    'dec_point.' => ['char' => 44],
+                    'thousands_sep.' => ['char' => 46]
+                ]
+            ]
         ];
     }
 
     /**
-     * Check if stdWrapHookObject processors work properly.
-     *
-     * Checks:
-     *
-     * - stdWrap_stdWrapPreProcess
-     * - stdWrap_stdWrapOverride
-     * - stdWrap_stdWrapProcess
-     * - stdWrap_stdWrapPostProcess
+     * Check if numberFormat works properly.
      *
+     * @dataProvider numberFormatDataProvider
      * @test
-     * @dataProvider fourTypesOfStdWrapHookObjectProcessorsDataProvider
-     * @param string $stdWrapMethod: The method to cover.
-     * @param string $hookObjectCall: The expected hook object call.
-     * @return void
      */
-    public function fourTypesOfStdWrapHookObjectProcessors(
-        $stdWrapMethod, $hookObjectCall)
+    public function numberFormat($expects, $content, $conf)
     {
-        $conf = [$this->getUniqueId('conf')];
-        $content = $this->getUniqueId('content');
-        $processed1 = $this->getUniqueId('processed1');
-        $processed2 = $this->getUniqueId('processed2');
-        $hookObject1 = $this->createMock(
-            ContentObjectStdWrapHookInterface::class);
-        $hookObject1->expects($this->once())
-            ->method($hookObjectCall)
-            ->with($content, $conf)
-            ->willReturn($processed1);
-        $hookObject2 = $this->createMock(
-            ContentObjectStdWrapHookInterface::class);
-        $hookObject2->expects($this->once())
-            ->method($hookObjectCall)
-            ->with($processed1, $conf)
-            ->willReturn($processed2);
-        $this->subject->_set('stdWrapHookObjects',
-            [$hookObject1, $hookObject2]);
-        $result = $this->subject->$stdWrapMethod($content, $conf);
-        $this->assertSame($processed2, $result);
+        $this->assertSame($expects,
+            $this->subject->numberFormat($content, $conf));
     }
 
     /**
-     * Check if stdWrap_setContentToCurrent works properly.
-     *
-     * @test
-     * @return void
-     */
-    public function stdWrap_setContentToCurrent()
-    {
-        $content = $this->getUniqueId('content');
-        $this->assertNotSame($content, $this->subject->getData('current'));
-        $this->assertSame($content,
-            $this->subject->stdWrap_setContentToCurrent($content));
-        $this->assertSame($content, $this->subject->getData('current'));
-    }
-
-    /**
-     * Data provider for stdWrap_setCurrent
+     * Data provider replacement
      *
-     * @return array Order input, conf
+     * @return array [$expect, $content, $conf]
      */
-    public function stdWrap_setCurrentDataProvider()
+    public function replacementDataProvider()
     {
         return [
-            'no conf' => [
-                'content',
-                [],
-            ],
-            'empty string' => [
-                'content',
-                ['setCurrent' => ''],
-            ],
-            'non-empty string' => [
-                'content',
-                ['setCurrent' => 'xxx'],
-            ],
-            'integer null' => [
-                'content',
-                ['setCurrent' => 0],
-            ],
-            'integer not null' => [
-                'content',
-                ['setCurrent' => 1],
-            ],
-            'boolean true' => [
-                'content',
-                ['setCurrent' => true],
+            'multiple replacements, including regex' => [
+                'There is an animal, an animal and an animal around the block! Yeah!',
+                'There_is_a_cat,_a_dog_and_a_tiger_in_da_hood!_Yeah!',
+                [
+                    '20.' => [
+                        'search' => '_',
+                        'replace.' => ['char' => '32']
+                    ],
+                    '120.' => [
+                        'search' => 'in da hood',
+                        'replace' => 'around the block'
+                    ],
+                    '130.' => [
+                        'search' => '#a (Cat|Dog|Tiger)#i',
+                        'replace' => 'an animal',
+                        'useRegExp' => '1'
+                    ]
+                ]
             ],
-            'boolean false' => [
-                'content',
-                ['setCurrent' => false],
+            'replacement with optionSplit, normal pattern' => [
+                'There1is2a3cat,3a3dog3and3a3tiger3in3da3hood!3Yeah!',
+                'There_is_a_cat,_a_dog_and_a_tiger_in_da_hood!_Yeah!',
+                [
+                    '10.' => [
+                        'search' => '_',
+                        'replace' => '1 || 2 || 3',
+                        'useOptionSplitReplace' => '1'
+                    ]
+                ]
             ],
+            'replacement with optionSplit, using regex' => [
+                'There is a tiny cat, a midsized dog and a big tiger in da hood! Yeah!',
+                'There is a cat, a dog and a tiger in da hood! Yeah!',
+                [
+                    '10.' => [
+                        'search' => '#(a) (Cat|Dog|Tiger)#i',
+                        'replace' => '${1} tiny ${2} || ${1} midsized ${2} || ${1} big ${2}',
+                        'useOptionSplitReplace' => '1',
+                        'useRegExp' => '1'
+                    ]
+                ]
+            ]
         ];
     }
 
     /**
-     * Check if stdWrap_setCurrent works properly.
+     * Check if stdWrap.replacement and all of its properties work properly
      *
      * @test
-     * @dataProvider stdWrap_setCurrentDataProvider
-     * @param string $input The input value.
-     * @param array $conf Property: setCurrent
+     * @dataProvider replacementDataProvider
+     * @param string $content The given input.
+     * @param string $expects The expected result.
+     * @param array $conf The given configuration.
      * @return void
      */
-    public function stdWrap_setCurrent($input, $conf)
+    public function replacement($expects, $content, $conf)
     {
-        if (isset($conf['setCurrent'])) {
-            $this->assertNotSame($conf['setCurrent'], $this->subject->getData('current'));
-        }
-        $this->assertSame($input, $this->subject->stdWrap_setCurrent($input, $conf));
-        if (isset($conf['setCurrent'])) {
-            $this->assertSame($conf['setCurrent'], $this->subject->getData('current'));
-        }
+        $this->assertSame($expects,
+            $this->subject->_call('replacement', $content, $conf));
     }
 
     /**
-     * Data provider for stdWrap_data.
+     * Data provider for the getQuery test
      *
-     * @return array [$expect, $data, $alt]
+     * @return array multi-dimensional array with the second level like this:
+     * @see getQuery
      */
-    public function stdWrap_dataDataProvider()
+    public function getQueryDataProvider()
     {
-        $data = [$this->getUniqueId('data')];
-        $alt = [$this->getUniqueId('alternativeData')];
-        return [
-            'default' => [$data, $data, ''],
-            'alt is array' => [$alt, $data, $alt],
-            'alt is empty array' => [[], $data, []],
-            'alt null' => [$data, $data, null],
-            'alt string' => [$data, $data, 'xxx'],
-            'alt int' => [$data, $data, 1],
-            'alt bool' => [$data, $data, true],
-        ];
+        $data = array(
+            'testing empty conf' => array(
+                'tt_content',
+                array(),
+                array(
+                    'SELECT' => '*'
+                )
+            ),
+            'testing #17284: adding uid/pid for workspaces' => array(
+                'tt_content',
+                array(
+                    'selectFields' => 'header,bodytext'
+                ),
+                array(
+                    'SELECT' => 'header,bodytext, tt_content.uid as uid, tt_content.pid as pid, tt_content.t3ver_state as t3ver_state'
+                )
+            ),
+            'testing #17284: no need to add' => array(
+                'tt_content',
+                array(
+                    'selectFields' => 'tt_content.*'
+                ),
+                array(
+                    'SELECT' => 'tt_content.*'
+                )
+            ),
+            'testing #17284: no need to add #2' => array(
+                'tt_content',
+                array(
+                    'selectFields' => '*'
+                ),
+                array(
+                    'SELECT' => '*'
+                )
+            ),
+            'testing #29783: joined tables, prefix tablename' => array(
+                'tt_content',
+                array(
+                    'selectFields' => 'tt_content.header,be_users.username',
+                    'join' => 'be_users ON tt_content.cruser_id = be_users.uid'
+                ),
+                array(
+                    'SELECT' => 'tt_content.header,be_users.username, tt_content.uid as uid, tt_content.pid as pid, tt_content.t3ver_state as t3ver_state'
+                )
+            ),
+            'testing #34152: single count(*), add nothing' => array(
+                'tt_content',
+                array(
+                    'selectFields' => 'count(*)'
+                ),
+                array(
+                    'SELECT' => 'count(*)'
+                )
+            ),
+            'testing #34152: single max(crdate), add nothing' => array(
+                'tt_content',
+                array(
+                    'selectFields' => 'max(crdate)'
+                ),
+                array(
+                    'SELECT' => 'max(crdate)'
+                )
+            ),
+            'testing #34152: single min(crdate), add nothing' => array(
+                'tt_content',
+                array(
+                    'selectFields' => 'min(crdate)'
+                ),
+                array(
+                    'SELECT' => 'min(crdate)'
+                )
+            ),
+            'testing #34152: single sum(is_siteroot), add nothing' => array(
+                'tt_content',
+                array(
+                    'selectFields' => 'sum(is_siteroot)'
+                ),
+                array(
+                    'SELECT' => 'sum(is_siteroot)'
+                )
+            ),
+            'testing #34152: single avg(crdate), add nothing' => array(
+                'tt_content',
+                array(
+                    'selectFields' => 'avg(crdate)'
+                ),
+                array(
+                    'SELECT' => 'avg(crdate)'
+                )
+            )
+        );
+        return $data;
     }
 
     /**
-     * Checks that stdWrap_data works properly.
-     *
-     * Show:
-     *
-     * - Delegates to method getData.
-     * - Parameter 1 is $conf['data'].
-     * - Parameter 2 is property data by default.
-     * - Parameter 2 is property alternativeData, if set as array.
-     * - Property alternativeData is always unset to ''.
-     * - Returns the return value.
+     * Check if sanitizeSelectPart works as expected
      *
+     * @dataProvider getQueryDataProvider
      * @test
-     * @dataProvider stdWrap_dataDataProvider
-     * @param mixed $expect Expect either $data or $alternativeData.
-     * @param array $data The data.
-     * @param mixed $alt The alternativeData.
-     * @return void
      */
-    public function stdWrap_data($expect, $data, $alt)
+    public function getQuery($table, $conf, $expected)
     {
-        $conf = ['data' => $this->getUniqueId('conf.data')];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getAccessibleMock(
-            ContentObjectRenderer::class, ['getData']);
-        $subject->_set('data', $data);
-        $subject->_set('alternativeData', $alt);
-        $subject
-            ->expects($this->once())
-            ->method('getData')
-            ->with($conf['data'], $expect)
-            ->willReturn($return);
-        $this->assertSame($return, $subject->stdWrap_data('discard', $conf));
-        $this->assertSame('', $subject->_get('alternativeData'));
-    }
-
-    /**
-     * Check if stdWrap_insertData works properly.
-     *
-     * Show:
-     *
-     *  - Delegates to method insertData.
-     *  - Parameter 1 is $content.
-     *  - Returns the return value.
-     *
-     *  @test
-     *  @return void
-     */
-    public function stdWrap_insertData()
-    {
-        $content = $this->getUniqueId('content');
-        $conf = [$this->getUniqueId('conf not used')];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['insertData'])->getMock();
-        $subject->expects($this->once())->method('insertData')
-            ->with($content)->willReturn($return);
-        $this->assertSame($return,
-            $subject->stdWrap_insertData($content, $conf));
-    }
-
-    /**
-     * Check if stdWrap_preIfEmptyListNum works properly.
-     *
-     * Show:
-     *
-     * - Delegates to method listNum.
-     * - Parameter 1 is $content.
-     * - Parameter 2 is $conf['preIfEmptyListNum'].
-     * - Parameter 3 is $conf['preIfEmptyListNum.']['splitChar'].
-     * - Returns the return value.
-     *
-     * @test
-     * @return void
-     */
-    public function stdWrap_preIfEmptyListNum()
-    {
-        $content = $this->getUniqueId('content');
-        $conf = [
-            'preIfEmptyListNum' => $this->getUniqueId('preIfEmptyListNum'),
-            'preIfEmptyListNum.' => [
-                'splitChar' => $this->getUniqueId('splitChar')
-            ],
-        ];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['listNum'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('listNum')
-            ->with(
-                $content,
-                $conf['preIfEmptyListNum'],
-                $conf['preIfEmptyListNum.']['splitChar']
-            )
-            ->willReturn($return);
-        $this->assertSame($return,
-            $subject->stdWrap_preIfEmptyListNum($content, $conf));
+        $GLOBALS['TCA'] = array(
+            'pages' => array(
+                'ctrl' => array(
+                    'enablecolumns' => array(
+                        'disabled' => 'hidden'
+                    )
+                )
+            ),
+            'tt_content' => array(
+                'ctrl' => array(
+                    'enablecolumns' => array(
+                        'disabled' => 'hidden'
+                    ),
+                    'versioningWS' => true
+                )
+            ),
+        );
+        $result = $this->subject->getQuery($table, $conf, true);
+        foreach ($expected as $field => $value) {
+            $this->assertEquals($value, $result[$field]);
+        }
     }
 
     /**
-     * Check if stdWrap_current works properly.
-     *
-     * Show:
-     *
-     * - current is returned from $this->data
-     * - the key is stored in $this->currentValKey
-     * - the key defaults to 'currentValue_kidjls9dksoje'
-     *
      * @test
-     * @return void
      */
-    public function stdWrap_current()
+    public function getQueryCallsGetTreeListWithNegativeValuesIfRecursiveIsSet()
     {
-        $data = [
-            'currentValue_kidjls9dksoje' => 'default',
-            'currentValue_new' => 'new',
-        ];
-        $this->subject->_set('data', $data);
-        $this->assertSame('currentValue_kidjls9dksoje',
-            $this->subject->_get('currentValKey'));
-        $this->assertSame('default',
-            $this->subject->stdWrap_current('discarded', ['discarded']));
-        $this->subject->_set('currentValKey', 'currentValue_new');
-        $this->assertSame('new',
-            $this->subject->stdWrap_current('discarded', ['discarded']));
+        $GLOBALS['TCA'] = array(
+            'pages' => array(
+                'ctrl' => array(
+                    'enablecolumns' => array(
+                        'disabled' => 'hidden'
+                    )
+                )
+            ),
+            'tt_content' => array(
+                'ctrl' => array(
+                    'enablecolumns' => array(
+                        'disabled' => 'hidden'
+                    )
+                )
+            ),
+        );
+        $this->subject = $this->getAccessibleMock(ContentObjectRenderer::class, array('getTreeList'));
+        $this->subject->start(array(), 'tt_content');
+        $conf = array(
+            'recursive' => '15',
+            'pidInList' => '16, -35'
+        );
+        $this->subject->expects($this->at(0))
+            ->method('getTreeList')
+            ->with(-16, 15)
+            ->will($this->returnValue('15,16'));
+        $this->subject->expects($this->at(1))
+            ->method('getTreeList')
+            ->with(-35, 15)
+            ->will($this->returnValue('15,35'));
+        $this->subject->getQuery('tt_content', $conf, true);
     }
 
     /**
-     * Check if stdWrap_preUserFunc works properly.
-     *
-     * Show:
-     *
-     * - Delegates to method callUserFunction.
-     * - Parameter 1 is $conf['preUserFunc'].
-     * - Parameter 2 is $conf['preUserFunc.'].
-     * - Parameter 3 is $content.
-     * - Returns the return value.
-     *
      * @test
-     * @return void
      */
-    public function stdWrap_preUserFunc()
+    public function getQueryCallsGetTreeListWithCurrentPageIfThisIsSet()
     {
-        $content = $this->getUniqueId('content');
-        $conf = [
-            'preUserFunc' => $this->getUniqueId('preUserFunc'),
-            'preUserFunc.' => [$this->getUniqueId('preUserFunc.')],
-        ];
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['callUserFunction'])->getMock();
-        $subject->expects($this->once())->method('callUserFunction')
-            ->with($conf['preUserFunc'], $conf['preUserFunc.'], $content)
-            ->willReturn('return');
-        $this->assertSame('return',
-            $subject->stdWrap_preUserFunc($content, $conf));
+        $GLOBALS['TCA'] = array(
+            'pages' => array(
+                'ctrl' => array(
+                    'enablecolumns' => array(
+                        'disabled' => 'hidden'
+                    )
+                )
+            ),
+            'tt_content' => array(
+                'ctrl' => array(
+                    'enablecolumns' => array(
+                        'disabled' => 'hidden'
+                    )
+                )
+            ),
+        );
+        $this->subject = $this->getAccessibleMock(ContentObjectRenderer::class, array('getTreeList'));
+        $GLOBALS['TSFE']->id = 27;
+        $this->subject->start(array(), 'tt_content');
+        $conf = array(
+            'pidInList' => 'this',
+            'recursive' => '4'
+        );
+        $this->subject->expects($this->once())
+            ->method('getTreeList')
+            ->with(-27)
+            ->will($this->returnValue('27'));
+        $this->subject->getQuery('tt_content', $conf, true);
     }
 
     /**
-     * Data provider for stdWrap_csConv
+     * Data provider for calcAge.
      *
-     * @return array Order expected, input, conf
+     * @return array [$expect, $timestamp, $labels]
      */
-    public function stdWrap_overrideDataProvider()
+    public function calcAgeDataProvider()
     {
         return [
-            'standard case' => [
-                'override', 'content', ['override' => 'override']
-            ],
-            'empty conf does not override' => [
-                'content', 'content', []
-            ],
-            'empty string does not override' => [
-                'content', 'content', ['override' => '']
-            ],
-            'whitespace does not override' => [
-                'content', 'content', ['override' => ' ' . TAB]
-            ],
-            'zero does not override' => [
-                'content', 'content', ['override' => 0]
+            'minutes' => [
+                '2 min', 120, ' min| hrs| days| yrs',
             ],
-            'false does not override' => [
-                'content', 'content', ['override' => false]
+            'hours' => [
+                '2 hrs', 7200, ' min| hrs| days| yrs',
             ],
-            'null does not override' => [
-                'content', 'content', ['override' => null]
+            'days' => [
+                '7 days', 604800, ' min| hrs| days| yrs',
             ],
-            'one does override' => [
-                1, 'content', ['override' => 1]
+            'day with provided singular labels' => [
+                '1 day', 86400, ' min| hrs| days| yrs| min| hour| day| year',
             ],
-            'minus one does override' => [
-                -1, 'content', ['override' => -1]
+            'years' => [
+                '45 yrs', 1417997800, ' min| hrs| days| yrs',
             ],
-            'float does override' => [
-                -0.1, 'content', ['override' => -0.1]
+            'different labels' => [
+                '2 Minutes', 120, ' Minutes| Hrs| Days| Yrs',
             ],
-            'true does override' => [
-                true, 'content', ['override' => true]
+            'negative values' => [
+                '-7 days', -604800, ' min| hrs| days| yrs',
             ],
-            'the value is not trimmed' => [
-                TAB . 'override', 'content', ['override' => TAB . 'override']
+            'default label values for wrong label input' => [
+                '2 min', 121, 10,
             ],
+            'default singular label values for wrong label input' => [
+                '1 year', 31536000, 10,
+            ]
         ];
     }
 
     /**
-     * Check if stdWrap_override works properly.
+     * Check if calcAge works properly.
      *
      * @test
-     * @dataProvider stdWrap_overrideDataProvider
-     * @param string $input The input value.
-     * @param array $conf Property: setCurrent
+     * @dataProvider calcAgeDataProvider
+     * @param int $expect
+     * @param int $timestamp
+     * @param string $labels
      * @return void
      */
-    public function stdWrap_override($expect, $content, $conf)
+    public function calcAge($expect, $timestamp, $labels)
     {
         $this->assertSame($expect,
-            $this->subject->stdWrap_override($content, $conf));
+            $this->subject->calcAge($timestamp, $labels));
     }
 
     /**
-     * Check if stdWrap_listNum works properly.
-     *
-     * Show:
-     *
-     * - Delegates to method listNum.
-     * - Parameter 1 is $content.
-     * - Parameter 2 is $conf['listNum'].
-     * - Parameter 3 is $conf['listNum.']['splitChar'].
-     * - Returns the return value.
-     *
-     * @test
-     * @return void
+     * @return array
      */
-    public function stdWrap_listNum()
+    public function stdWrapReturnsExpectationDataProvider()
     {
-        $content = $this->getUniqueId('content');
-        $conf = [
-            'listNum' => $this->getUniqueId('listNum'),
-            'listNum.' => [
-                'splitChar' => $this->getUniqueId('splitChar')
+        return [
+            'Prevent silent bool conversion' => [
+                '1+1',
+                [
+                    'prioriCalc.' => [
+                        'wrap' => '|',
+                    ],
+                ],
+                '1+1',
             ],
         ];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['listNum'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('listNum')
-            ->with(
-                $content,
-                $conf['listNum'],
-                $conf['listNum.']['splitChar']
-            )
-            ->willReturn($return);
-        $this->assertSame($return,
-            $subject->stdWrap_listNum($content, $conf));
     }
 
     /**
-     * Check if stdWrap_field works properly.
-     *
-     * Show:
-     *
-     * - calls getFieldVal
-     * - passes conf['field'] as parameter
-     *
+     * @param string $content
+     * @param array $configuration
+     * @param string $expectation
+     * @dataProvider stdWrapReturnsExpectationDataProvider
      * @test
-     * @return void
      */
-    public function stdWrap_field()
+    public function stdWrapReturnsExpectation($content, array $configuration, $expectation)
     {
-        $expect = $this->getUniqueId('expect');
-        $conf = ['field' => $this->getUniqueId('field')];
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['getFieldVal'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('getFieldVal')
-            ->with($conf['field'])
-            ->willReturn($expect);
-        $this->assertSame($expect,
-            $subject->stdWrap_field('discarded', $conf));
+        $this->assertSame($expectation, $this->subject->stdWrap($content, $configuration));
     }
 
     /**
-     * Check if stdWrap_prepend works properly.
-     *
-     * Show:
-     *
-     * - Delegates to the method cObjGetSingle().
-     * - First parameter is $conf['prepend'].
-     * - Second parameter is $conf['prepend.'].
-     * - Third parameter is '/stdWrap/.prepend'.
-     * - Returns the return value prepended to $content.
+     * Data provider for substring
      *
-     * @test
-     * @return void
+     * @return array [$expect, $content, $conf]
      */
-    public function stdWrap_prepend()
+    public function substringDataProvider()
     {
-        $debugKey =  '/stdWrap/.prepend';
-        $content = $this->getUniqueId('content');
-        $conf = [
-            'prepend' => $this->getUniqueId('prepend'),
-            'prepend.' => [$this->getUniqueId('prepend.')],
+        return [
+            'sub -1'    => ['g', 'substring', '-1'],
+            'sub -1,0'  => ['g', 'substring', '-1,0'],
+            'sub -1,-1' => ['', 'substring', '-1,-1'],
+            'sub -1,1'  => ['g', 'substring', '-1,1'],
+            'sub 0'     => ['substring', 'substring', '0'],
+            'sub 0,0'   => ['substring', 'substring', '0,0'],
+            'sub 0,-1'  => ['substrin', 'substring', '0,-1'],
+            'sub 0,1'   => ['s', 'substring', '0,1'],
+            'sub 1'     => ['ubstring', 'substring', '1'],
+            'sub 1,0'   => ['ubstring', 'substring', '1,0'],
+            'sub 1,-1'  => ['ubstrin', 'substring', '1,-1'],
+            'sub 1,1'   => ['u', 'substring', '1,1'],
+            'sub'       => ['substring', 'substring', ''],
         ];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['cObjGetSingle'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('cObjGetSingle')
-            ->with($conf['prepend'], $conf['prepend.'], $debugKey)
-            ->willReturn($return);
-        $this->assertSame($return . $content,
-            $subject->stdWrap_prepend($content, $conf));
     }
 
     /**
-     * Check if stdWrap_cObject works properly.
-     *
-     * Show:
-     *
-     * - Delegates to the method cObjGetSingle().
-     * - First parameter is $conf['cObject'].
-     * - Second parameter is $conf['cObject.'].
-     * - Third parameter is '/stdWrap/.cObject'.
-     * - Returns the return.
+     * Check if substring works properly.
      *
      * @test
+     * @dataProvider substringDataProvider
+     * @param string $expect The expected output.
+     * @param string $content The given input.
+     * @param array $conf The given configutation.
      * @return void
      */
-    public function stdWrap_cObject()
+    public function substring($expect, $content, $conf)
     {
-        $debugKey =  '/stdWrap/.cObject';
-        $conf = [
-            'cObject' => $this->getUniqueId('cObject'),
-            'cObject.' => [$this->getUniqueId('cObject.')],
-        ];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['cObjGetSingle'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('cObjGetSingle')
-            ->with($conf['cObject'], $conf['cObject.'], $debugKey)
-            ->willReturn($return);
-        $this->assertSame($return,
-            $subject->stdWrap_cObject('discard', $conf));
+        $this->assertSame($expect, $this->subject->substring($content, $conf));
     }
 
+    ///////////////////////////////
+    // Tests concerning getData()
+    ///////////////////////////////
+
     /**
-     * Check if stdWrap_append works properly.
-     *
-     * Show:
-     *
-     * - Delegates to the method cObjGetSingle().
-     * - First parameter is $conf['append'].
-     * - Second parameter is $conf['append.'].
-     * - Third parameter is '/stdWrap/.append'.
-     * - Returns the return value appended to $content.
+     * @return array
+     */
+    public function getDataWithTypeGpDataProvider()
+    {
+        return array(
+            'Value in get-data' => array('onlyInGet', 'GetValue'),
+            'Value in post-data' => array('onlyInPost', 'PostValue'),
+            'Value in post-data overriding get-data' => array('inGetAndPost', 'ValueInPost'),
+        );
+    }
+
+    /**
+     * Checks if getData() works with type "gp"
      *
      * @test
-     * @return void
+     * @dataProvider getDataWithTypeGpDataProvider
      */
-    public function stdWrap_append()
+    public function getDataWithTypeGp($key, $expectedValue)
     {
-        $debugKey =  '/stdWrap/.append';
-        $content = $this->getUniqueId('content');
-        $conf = [
-            'append' => $this->getUniqueId('append'),
-            'append.' => [$this->getUniqueId('append.')],
-        ];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['cObjGetSingle'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('cObjGetSingle')
-            ->with($conf['append'], $conf['append.'], $debugKey)
-            ->willReturn($return);
-        $this->assertSame($content . $return,
-            $subject->stdWrap_append($content, $conf));
+        $_GET = array(
+            'onlyInGet' => 'GetValue',
+            'inGetAndPost' => 'ValueInGet',
+        );
+        $_POST = array(
+            'onlyInPost' => 'PostValue',
+            'inGetAndPost' => 'ValueInPost',
+        );
+        $this->assertEquals($expectedValue, $this->subject->getData('gp:' . $key));
     }
 
     /**
-     * Check if stdWrap_numRows works properly.
-     *
-     * Show:
-     *
-     * - Delegates to method numRows.
-     * - Parameter is $conf['numRows.'].
-     * - Returns the return value.
+     * Checks if getData() works with type "tsfe"
      *
      * @test
-     * @return void
      */
-    public function stdWrap_numRows()
+    public function getDataWithTypeTsfe()
     {
-        $conf = [
-            'numRows' => $this->getUniqueId('numRows'),
-            'numRows.' => [$this->getUniqueId('numRows')],
-        ];
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['numRows'])->getMock();
-        $subject->expects($this->once())->method('numRows')
-            ->with($conf['numRows.'])->willReturn('return');
-        $this->assertSame('return',
-            $subject->stdWrap_numRows('discard', $conf));
+        $this->assertEquals($GLOBALS['TSFE']->metaCharset, $this->subject->getData('tsfe:metaCharset'));
     }
 
     /**
-     * Check if stdWrap_filelist works properly.
-     *
-     * Show:
-     *
-     * - Delegates to method filelist.
-     * - Parameter is $conf['filelist'].
-     * - Returns the return value.
+     * Checks if getData() works with type "getenv"
      *
      * @test
-     * @return void
      */
-    public function stdWrap_filelist()
+    public function getDataWithTypeGetenv()
     {
-        $conf = [
-            'filelist' => $this->getUniqueId('filelist'),
-            'filelist.' => [$this->getUniqueId('not used')],
-        ];
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['filelist'])->getMock();
-        $subject->expects($this->once())->method('filelist')
-            ->with($conf['filelist'])->willReturn('return');
-        $this->assertSame('return',
-            $subject->stdWrap_filelist('discard', $conf));
+        $envName = $this->getUniqueId('frontendtest');
+        $value = $this->getUniqueId('someValue');
+        putenv($envName . '=' . $value);
+        $this->assertEquals($value, $this->subject->getData('getenv:' . $envName));
     }
 
     /**
-     * Check if stdWrap_filelink works properly.
-     *
-     * Show:
-     *
-     * - Delegates to method filelink.
-     * - Parameter 1 is $content.
-     * - Parameter 2 is $conf['filelink.'].
-     * - Returns the return value.
+     * Checks if getData() works with type "getindpenv"
      *
      * @test
-     * @return void
      */
-    public function stdWrap_filelink()
+    public function getDataWithTypeGetindpenv()
     {
-        $content = $this->getUniqueId('content');
-        $conf = [
-            'filelink' => $this->getUniqueId('not used'),
-            'filelink.' => [$this->getUniqueId('filelink.')],
-        ];
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['filelink'])->getMock();
-        $subject->expects($this->once())->method('filelink')
-            ->with($content, $conf['filelink.'])->willReturn('return');
-        $this->assertSame('return',
-            $subject->stdWrap_filelink($content, $conf));
+        $this->subject->expects($this->once())->method('getEnvironmentVariable')
+            ->with($this->equalTo('SCRIPT_FILENAME'))->will($this->returnValue('dummyPath'));
+        $this->assertEquals('dummyPath', $this->subject->getData('getindpenv:SCRIPT_FILENAME'));
     }
 
     /**
-     * Data provider for stdWrap_fieldRequired.
+     * Checks if getData() works with type "field"
      *
-     * @return array [$expect, $stop, $content, $conf]
+     * @test
      */
-    public function stdWrap_fieldRequiredDataProvider()
+    public function getDataWithTypeField()
     {
-        $content = $this->getUniqueId('content');
-        return [
-            // resulting in boolean false
-            'false is false' => [
-                '', true, $content, ['fieldRequired' => 'false']
-            ],
-            'null is false' => [
-                '', true, $content, ['fieldRequired' => 'null']
-            ],
-            'empty string is false' => [
-                '', true, $content, ['fieldRequired' => 'empty']
-            ],
-            'whitespace is false' => [
-                '', true, $content, ['fieldRequired' => 'whitespace']
-            ],
-            'string zero is false' => [
-                '', true, $content, ['fieldRequired' => 'stringZero']
-            ],
-            'string zero with whitespace is false' => [
-                '', true, $content,
-                ['fieldRequired' => 'stringZeroWithWhiteSpace']
-            ],
-            'zero is false' => [
-                '', true, $content, ['fieldRequired' => 'zero']
-            ],
-            // resulting in boolean true
-            'true is true' => [
-                $content, false, $content, ['fieldRequired' => 'true']
-            ],
-            'string is true' => [
-                $content, false, $content, ['fieldRequired' => 'string']
-            ],
-            'one is true' => [
-                $content, false, $content, ['fieldRequired' => 'one']
-            ]
-        ];
+        $key = 'someKey';
+        $value = 'someValue';
+        $field = array($key => $value);
+
+        $this->assertEquals($value, $this->subject->getData('field:' . $key, $field));
     }
 
     /**
-     * Check if stdWrap_fieldRequired works properly.
-     *
-     * Show:
-     *
-     *  - The value is taken from property array data.
-     *  - The key is taken from $conf['fieldRequired'].
-     *  - The value is casted to string by trim() and trimmed.
-     *  - It is further casted to boolean by if().
-     *  - False triggers a stop of further rendering.
-     *  - False returns '', true the given content as is.
+     * Checks if getData() works with type "field" of the field content
+     * is multi-dimensional (e.g. an array)
      *
      * @test
-     * @dataProvider stdWrap_fieldRequiredDataProvider
-     * @param mixed $expect The expected output.
-     * @param bool $stop Expect stop further rendering.
-     * @param mixed $content The given input.
-     * @param array $conf The given configuration.
-     * @return void
      */
-    public function stdWrap_fieldRequired($expect, $stop, $content, $conf)
+    public function getDataWithTypeFieldAndFieldIsMultiDimensional()
     {
-        $data = [
-            'null' => null,
-            'false' => false,
-            'empty' => '',
-            'whitespace' => TAB . ' ',
-            'stringZero' => '0',
-            'stringZeroWithWhiteSpace' => TAB . ' 0 ' . TAB,
-            'zero' => 0,
-            'string' => 'string',
-            'true' => true,
-            'one' => 1
-        ];
-        $subject = $this->subject;
-        $subject->_set('data', $data);
-        $subject->_set('stdWrapRecursionLevel', 1);
-        $subject->_set('stopRendering', [1 => false]);
-        $this->assertSame($expect,
-            $subject->stdWrap_fieldRequired($content, $conf));
-        $this->assertSame($stop, $subject->_get('stopRendering')[1]);
+        $key = 'somekey|level1|level2';
+        $value = 'somevalue';
+        $field = array('somekey' => array('level1' => array('level2' => 'somevalue')));
+
+        $this->assertEquals($value, $this->subject->getData('field:' . $key, $field));
     }
 
     /**
-     * Data provider for stdWrap_csConv
+     * Basic check if getData gets the uid of a file object
      *
-     * @return array Order expected, input, conf
+     * @test
      */
-    public function stdWrap_csConvDataProvider()
+    public function getDataWithTypeFileReturnsUidOfFileObject()
     {
-        return [
-            'empty string from ISO-8859-15' => [
-                '',
-                iconv('UTF-8', 'ISO-8859-15', ''),
-                ['csConv' => 'ISO-8859-15']
-            ],
-            'empty string from BIG-5' => [
-                '',
-                mb_convert_encoding('', 'BIG-5'),
-                ['csConv' => 'BIG-5']
-            ],
-            '"0" from ISO-8859-15' => [
-                '0',
-                iconv('UTF-8', 'ISO-8859-15', '0'),
-                ['csConv' => 'ISO-8859-15']
-            ],
-            '"0" from BIG-5' => [
-                '0',
-                mb_convert_encoding('0', 'BIG-5'),
-                ['csConv' => 'BIG-5']
-            ],
-            'euro symbol from ISO-88859-15' => [
-                '€',
-                iconv('UTF-8', 'ISO-8859-15', '€'),
-                ['csConv' => 'ISO-8859-15']
-            ],
-            'good morning from BIG-5' => [
-                '早安',
-                mb_convert_encoding('早安', 'BIG-5'),
-                ['csConv' => 'BIG-5']
-            ],
-        ];
+        $uid = $this->getUniqueId();
+        $file = $this->createMock(File::class);
+        $file->expects($this->once())->method('getUid')->will($this->returnValue($uid));
+        $this->subject->setCurrentFile($file);
+        $this->assertEquals($uid, $this->subject->getData('file:current:uid'));
     }
 
     /**
-     * Check if stdWrap_csConv works properly.
+     * Checks if getData() works with type "parameters"
      *
      * @test
-     * @dataProvider stdWrap_csConvDataProvider
-     * @param string $expected The expected value.
-     * @param string $value The input value.
-     * @param array $conf Property: csConv
-     * @return void
      */
-    public function stdWrap_csConv($expected, $input, $conf)
+    public function getDataWithTypeParameters()
     {
-        $this->assertSame($expected,
-            $this->subject->stdWrap_csConv($input, $conf));
+        $key = $this->getUniqueId('someKey');
+        $value = $this->getUniqueId('someValue');
+        $this->subject->parameters[$key] = $value;
+
+        $this->assertEquals($value, $this->subject->getData('parameters:' . $key));
     }
 
     /**
-     * Check if stdWrap_split works properly.
-     *
-     * Show:
-     *
-     * - Delegates to method splitObj.
-     * - Parameter 1 is $content.
-     * - Prameter 2 is $conf['split.'].
-     * - Returns the return value.
+     * Checks if getData() works with type "register"
      *
      * @test
-     * @return void
      */
-     public function stdWrap_split()
-     {
-         $content = $this->getUniqueId('content');
-         $conf = [
-             'split' => $this->getUniqueId('not used'),
-             'split.' => [$this->getUniqueId('split.')],
-         ];
-         $return = $this->getUniqueId('return');
-         $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-             ->setMethods(['splitObj'])->getMock();
-         $subject
-             ->expects($this->once())
-             ->method('splitObj')
-             ->with($content, $conf['split.'])
-             ->willReturn($return);
-         $this->assertSame($return,
-             $subject->stdWrap_split($content, $conf));
-     }
+    public function getDataWithTypeRegister()
+    {
+        $key = $this->getUniqueId('someKey');
+        $value = $this->getUniqueId('someValue');
+        $GLOBALS['TSFE']->register[$key] = $value;
+
+        $this->assertEquals($value, $this->subject->getData('register:' . $key));
+    }
 
     /**
-     * Data provider for stdWrap_prioriCalc
+     * Checks if getData() works with type "level"
      *
-     * @return array [$expect, $content, $conf]
+     * @test
      */
-    public function stdWrap_prioriCalcDataProvider()
+    public function getDataWithTypeLevel()
     {
-        return [
-            'priority of *' => ['7', '1 + 2 * 3', []],
-            'priority of parentheses' => ['9', '(1 + 2) * 3', []],
-            'float' => ['1.5', '3/2', []],
-            'intval casts to int' => [1, '3/2', ['prioriCalc' => 'intval']],
-            'intval does not round' => [2, '2.7', ['prioriCalc' => 'intval']],
-        ];
+        $rootline = array(
+            0 => array('uid' => 1, 'title' => 'title1'),
+            1 => array('uid' => 2, 'title' => 'title2'),
+            2 => array('uid' => 3, 'title' => 'title3'),
+        );
+
+        $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
+        $this->assertEquals(2, $this->subject->getData('level'));
     }
 
     /**
-     * Data provider for stdWrap_HTMLparser
+     * Checks if getData() works with type "global"
      *
-     * @return array [$expect, $content, $conf, $times, $will].
+     * @test
      */
-    public function stdWrap_HTMLparserDataProvider()
+    public function getDataWithTypeGlobal()
     {
-        $content = $this->getUniqueId('content');
-        $parsed = $this->getUniqueId('parsed');
-        return [
-            'no config' => [
-                $content, $content, [], 0, $parsed
-            ],
-            'no array' => [
-                $content, $content, ['HTMLparser.' => 1], 0, $parsed
-            ],
-            'empty array' => [
-                $parsed, $content, ['HTMLparser.' => []], 1, $parsed
-            ],
-            'non-empty array' => [
-                $parsed, $content, ['HTMLparser.' => [true]], 1, $parsed
-            ],
-        ];
+        $this->assertEquals($GLOBALS['TSFE']->metaCharset, $this->subject->getData('global:TSFE|metaCharset'));
     }
 
     /**
-     * Check if stdWrap_HTMLparser works properly
-     *
-     * Show:
-     *
-     * - Checks if $conf['HTMLparser.'] is an array.
-     * - No:
-     *   - Returns $content as is.
-     * - Yes:
-     *   - Delegates to method HTMLparser_TSbridge.
-     *   - Parameter 1 is $content.
-     *   - Parameter 2 is $conf['HTMLparser'].
-     *   - Returns the return value.
+     * Checks if getData() works with type "leveltitle"
      *
      * @test
-     * @dataProvider stdWrap_HTMLparserDataProvider
-     * @param string $expect The expected output.
-     * @param string $content The given content.
-     * @param array $conf The given configuration.
-     * @param int $times Times HTMLparser_TSbridge is called (0 or 1).
-     * @param string $will Return of HTMLparser_TSbridge.
-     * @return void.
      */
-    public function stdWrap_HTMLparser(
-        $expect, $content, $conf, $times, $will)
+    public function getDataWithTypeLeveltitle()
     {
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['HTMLparser_TSbridge'])->getMock();
-        $subject
-            ->expects($this->exactly($times))
-            ->method('HTMLparser_TSbridge')
-            ->with($content, $conf['HTMLparser.'])
-            ->willReturn($will);
-        $this->assertSame($expect,
-            $subject->stdWrap_HTMLparser($content, $conf));
+        $rootline = array(
+            0 => array('uid' => 1, 'title' => 'title1'),
+            1 => array('uid' => 2, 'title' => 'title2'),
+            2 => array('uid' => 3, 'title' => ''),
+        );
+
+        $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
+        $this->assertEquals('', $this->subject->getData('leveltitle:-1'));
+        // since "title3" is not set, it will slide to "title2"
+        $this->assertEquals('title2', $this->subject->getData('leveltitle:-1,slide'));
     }
 
     /**
-     * Check if stdWrap_prioriCalc works properly.
-     *
-     * Show:
-     *
-     * - If $conf['prioriCalc'] is 'intval' the return is casted to int.
-     * - Delegates to MathUtility::calculateWithParentheses.
-     *
-     * Note: As PHPUnit can't mock static methods, the call to
-     *       MathUtility::calculateWithParentheses can't be easily intercepted.
-     *       The test is done by testing input/output pairs instead. To not
-     *       duplicate the testing of calculateWithParentheses just a few
-     *       smoke tests are done here.
+     * Checks if getData() works with type "levelmedia"
      *
      * @test
-     * @dataProvider stdWrap_prioriCalcDataProvider
-     * @param mixed $expect The expected output.
-     * @param string $content The given content.
-     * @param array $conf The given configuration.
-     * @return void
      */
-    public function stdWrap_prioriCalc($expect, $content, $conf)
+    public function getDataWithTypeLevelmedia()
     {
-        $result = $this->subject->stdWrap_prioriCalc($content, $conf);
-        $this->assertSame($expect, $result);
+        $rootline = array(
+            0 => array('uid' => 1, 'title' => 'title1', 'media' => 'media1'),
+            1 => array('uid' => 2, 'title' => 'title2', 'media' => 'media2'),
+            2 => array('uid' => 3, 'title' => 'title3', 'media' => ''),
+        );
+
+        $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
+        $this->assertEquals('', $this->subject->getData('levelmedia:-1'));
+        // since "title3" is not set, it will slide to "title2"
+        $this->assertEquals('media2', $this->subject->getData('levelmedia:-1,slide'));
     }
 
     /**
-     * Test for the stdWrap_stripHtml
+     * Checks if getData() works with type "leveluid"
      *
      * @test
      */
-    public function stdWrap_stripHtml()
+    public function getDataWithTypeLeveluid()
     {
-        $content = '<html><p>Hello <span class="inline">inline tag<span>!</p><p>Hello!</p></html>';
-        $expected = 'Hello inline tag!Hello!';
-        $this->assertSame($expected, $this->subject->stdWrap_stripHtml($content));
+        $rootline = array(
+            0 => array('uid' => 1, 'title' => 'title1'),
+            1 => array('uid' => 2, 'title' => 'title2'),
+            2 => array('uid' => 3, 'title' => 'title3'),
+        );
+
+        $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
+        $this->assertEquals(3, $this->subject->getData('leveluid:-1'));
+        // every element will have a uid - so adding slide doesn't really make sense, just for completeness
+        $this->assertEquals(3, $this->subject->getData('leveluid:-1,slide'));
     }
 
     /**
-     * Check if stdWrap_crop works properly.
-     *
-     * Show:
-     *
-     * - Delegates to method listNum.
-     * - Parameter 1 is $content.
-     * - Parameter 2 is $conf['crop'].
-     * - Returns the return value.
+     * Checks if getData() works with type "levelfield"
      *
      * @test
-     * @return void
      */
-    public function stdWrap_crop()
+    public function getDataWithTypeLevelfield()
     {
-        $content = $this->getUniqueId('content');
-        $conf = [
-            'crop' => $this->getUniqueId('crop'),
-            'crop.' => $this->getUniqueId('not used'),
-        ];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['crop'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('crop')
-            ->with($content, $conf['crop'])
-            ->willReturn($return);
-        $this->assertSame($return,
-            $subject->stdWrap_crop($content, $conf));
+        $rootline = array(
+            0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
+            1 => array('uid' => 2, 'title' => 'title2', 'testfield' => 'field2'),
+            2 => array('uid' => 3, 'title' => 'title3', 'testfield' => ''),
+        );
+
+        $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
+        $this->assertEquals('', $this->subject->getData('levelfield:-1,testfield'));
+        $this->assertEquals('field2', $this->subject->getData('levelfield:-1,testfield,slide'));
     }
 
     /**
-     * Data provider for round
+     * Checks if getData() works with type "fullrootline"
      *
-     * @return array [$expect, $contet, $conf]
+     * @test
      */
-    public function roundDataProvider()
+    public function getDataWithTypeFullrootline()
     {
-        return [
-            // floats
-            'down' => [1.0, 1.11, []],
-            'up' => [2.0, 1.51, []],
-            'rounds up from x.50' => [2.0, 1.50, []],
-            'down with decimals' => [0.12, 0.1231, ['decimals' => 2]],
-            'up with decimals' => [0.13, 0.1251, ['decimals' => 2]],
-            'ceil' => [1.0, 0.11, ['roundType' => 'ceil']],
-            'ceil does not accept decimals' => [
-                1.0, 0.111, [
-                    'roundType' => 'ceil',
-                    'decimals' => 2,
-                ],
-            ],
-            'floor' => [2.0, 2.99, ['roundType' => 'floor']],
-            'floor does not accept decimals' => [
-                2.0, 2.999, [
-                    'roundType' => 'floor',
-                    'decimals' => 2,
-                ],
-            ],
-            'round, down' => [1.0, 1.11, ['roundType' => 'round']],
-            'round, up' => [2.0, 1.55, ['roundType' => 'round']],
-            'round does accept decimals' => [
-                5.56, 5.5555, [
-                    'roundType' => 'round',
-                    'decimals' => 2,
-                ],
-            ],
-            // strings
-            'emtpy string' => [0.0, '', []],
-            'word string' => [0.0, 'word', []],
-            'float string' => [1.0, '1.123456789', []],
-            // other types
-            'null' => [0.0, null, []],
-            'false' => [0.0, false, []],
-            'true' => [1.0, true, []]
-        ];
+        $rootline1 = array(
+            0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
+        );
+        $rootline2 = array(
+            0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
+            1 => array('uid' => 2, 'title' => 'title2', 'testfield' => 'field2'),
+            2 => array('uid' => 3, 'title' => 'title3', 'testfield' => 'field3'),
+        );
+
+        $GLOBALS['TSFE']->tmpl->rootLine = $rootline1;
+        $GLOBALS['TSFE']->rootLine = $rootline2;
+        $this->assertEquals('field2', $this->subject->getData('fullrootline:-1,testfield'));
     }
 
     /**
-     * Check if round works properly
-     *
-     * Show:
-     *
-     *  - Different types of input are casted to float.
-     *  - Configuration ceil rounds like ceil().
-     *  - Configuration floor rounds like floor().
-     *  - Otherwise rounds like round() and decimals can be applied.
-     *  - Always returns float.
+     * Checks if getData() works with type "date"
      *
-     * @param float $expected The expected output.
-     * @param mixed $content The given content.
-     * @param array $conf The given configuration of 'round.'.
-     * @return void
-     * @dataProvider roundDataProvider
      * @test
      */
-    public function round($expect, $content, $conf)
+    public function getDataWithTypeDate()
     {
-        $this->assertSame($expect,
-            $this->subject->_call('round', $content, $conf));
+        $format = 'Y-M-D';
+        $defaultFormat = 'd/m Y';
+
+        $this->assertEquals(date($format, $GLOBALS['EXEC_TIME']), $this->subject->getData('date:' . $format));
+        $this->assertEquals(date($defaultFormat, $GLOBALS['EXEC_TIME']), $this->subject->getData('date'));
     }
 
     /**
-     * Check if stdWrap_round works properly
-     *
-     * Show:
-     *
-     * - Delegates to method round.
-     * - Parameter 1 is $content.
-     * - Parameter 2 is $conf['round.'].
-     * - Returns the return value.
+     * Checks if getData() works with type "page"
      *
      * @test
-     * @return void
      */
-    public function stdWrap_round()
+    public function getDataWithTypePage()
     {
-        $content = $this->getUniqueId('content');
-        $conf = [
-            'round' => $this->getUniqueId('not used'),
-            'round.' => [$this->getUniqueId('round.')],
-        ];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['round'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('round')
-            ->with($content, $conf['round.'])
-            ->willReturn($return);
-        $this->assertSame($return, $subject->stdWrap_round($content, $conf));
+        $uid = rand();
+        $GLOBALS['TSFE']->page['uid'] = $uid;
+        $this->assertEquals($uid, $this->subject->getData('page:uid'));
     }
 
     /**
-     * Check if stdWrap_numberFormat works properly.
-     *
-     * Show:
-     *
-     * - Delegates to the method numberFormat.
-     * - Parameter 1 is $content.
-     * - Parameter 2 is $conf['numberFormat.'].
-     * - Returns the return value.
+     * Checks if getData() works with type "current"
      *
      * @test
-     * @return void
      */
-    public function stdWrap_numberFormat()
+    public function getDataWithTypeCurrent()
     {
-        $content = $this->getUniqueId('content');
-        $conf = [
-            'numberFormat' => $this->getUniqueId('not used'),
-            'numberFormat.' => [$this->getUniqueId('numberFormat.')],
-        ];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['numberFormat'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('numberFormat')
-            ->with($content, $conf['numberFormat.'])
-            ->willReturn($return);
-        $this->assertSame($return,
-            $subject->stdWrap_numberFormat($content, $conf));
+        $key = $this->getUniqueId('someKey');
+        $value = $this->getUniqueId('someValue');
+        $this->subject->data[$key] = $value;
+        $this->subject->currentValKey = $key;
+        $this->assertEquals($value, $this->subject->getData('current'));
     }
 
     /**
-     * Data provider for expandList
+     * Checks if getData() works with type "db"
      *
-     * @return array [$expect, $content]
+     * @test
      */
-    public function stdWrap_expandListDataProvider()
+    public function getDataWithTypeDb()
     {
-        return [
-            'numbers' => ['1,2,3', '1,2,3'],
-            'range' => ['3,4,5', '3-5'],
-            'numbers and range' => ['1,3,4,5,7', '1,3-5,7']
-        ];
+        $dummyRecord = array('uid' => 5, 'title' => 'someTitle');
+
+        $GLOBALS['TSFE']->sys_page->expects($this->atLeastOnce())->method('getRawRecord')->with('tt_content', '106')->will($this->returnValue($dummyRecord));
+        $this->assertEquals($dummyRecord['title'], $this->subject->getData('db:tt_content:106:title'));
     }
 
     /**
-     * Test for the stdWrap function "expandList"
-     *
-     * The method simply delegates to GeneralUtility::expandList. There is no
-     * need to repeat the full set of tests of this method here. As PHPUnit
-     * can't mock static methods, to prove they are called, all we do here
-     * is to provide a few smoke tests.
+     * Checks if getData() works with type "lll"
      *
      * @test
-     * @dataProvider stdWrap_expandListDataProvider
-     * @param string $expected The expeced output.
-     * @param string $content The given content.
-     * @return void
      */
-    public function stdWrap_expandList($expected, $content)
+    public function getDataWithTypeLll()
     {
-        $this->assertEquals($expected,
-            $this->subject->stdWrap_expandList($content));
+        $key = $this->getUniqueId('someKey');
+        $value = $this->getUniqueId('someValue');
+        $language = $this->getUniqueId('someLanguage');
+        $GLOBALS['TSFE']->LL_labels_cache[$language]['LLL:' . $key] = $value;
+        $GLOBALS['TSFE']->lang = $language;
+
+        $this->assertEquals($value, $this->subject->getData('lll:' . $key));
     }
 
     /**
-     * Data provider for stdWrap_trim.
+     * Checks if getData() works with type "path"
      *
-     * @return array [$expect, $content]
+     * @test
      */
-    public function stdWrap_trimDataProvider()
+    public function getDataWithTypePath()
     {
-        return [
-            // string not trimmed
-            'empty string' => ['', ''],
-            'string without whitespace' => ['xxx', 'xxx'],
-            'string with whitespace inside' => [
-                'xx ' . TAB . ' xx',
-                'xx ' . TAB . ' xx',
-            ],
-            'string with newlines inside' => [
-                'xx ' . PHP_EOL . ' xx',
-                'xx ' . PHP_EOL . ' xx',
-            ],
-            // string trimmed
-            'blanks around' => ['xxx', '  xxx  '],
-            'tabs around' => ['xxx', TAB . 'xxx' . TAB],
-            'newlines around' => ['xxx', PHP_EOL . 'xxx' . PHP_EOL],
-            'mixed case' => ['xxx', TAB . ' xxx ' . PHP_EOL],
-            // non strings
-            'null' => ['', null],
-            'false' => ['', false],
-            'true' => ['1', true],
-            'zero' => ['0', 0],
-            'one' => ['1', 1],
-            '-1' => ['-1', -1],
-            '0.0' => ['0', 0.0],
-            '1.0' => ['1', 1.0],
-            '-1.0' => ['-1', -1.0],
-            '1.1' => ['1.1', 1.1],
-        ];
+        $filenameIn = $this->getUniqueId('someValue');
+        $filenameOut = $this->getUniqueId('someValue');
+        $this->templateServiceMock->expects($this->atLeastOnce())->method('getFileName')->with($filenameIn)->will($this->returnValue($filenameOut));
+        $this->assertEquals($filenameOut, $this->subject->getData('path:' . $filenameIn));
     }
 
     /**
-     * Check that stdWrap_trim works properly.
-     *
-     * Show:
-     *
-     *  - the given string is trimmed like PHP trim
-     *  - non-strings are casted to strings:
-     *    - null => 'null'
-     *    - false => ''
-     *    - true => '1'
-     *    - 0 => '0'
-     *    - -1 => '-1'
-     *    - 1.0 => '1'
-     *    - 1.1 => '1.1'
+     * Checks if getData() works with type "parentRecordNumber"
      *
      * @test
-     * @dataProvider stdWrap_trimDataProvider
-     * @param string $expected The expected output.
-     * @param mixed $content The given content.
-     * @return void
      */
-    public function stdWrap_trim($expect, $content)
+    public function getDataWithTypeParentRecordNumber()
     {
-        $result = $this->subject->stdWrap_trim($content);
-        $this->assertSame($expect, $result);
+        $recordNumber = rand();
+        $this->subject->parentRecordNumber = $recordNumber;
+        $this->assertEquals($recordNumber, $this->subject->getData('cobj:parentRecordNumber'));
     }
 
     /**
-     * Data provider for stdWrap_if.
+     * Checks if getData() works with type "debug:rootLine"
      *
-     * @return array [$expect, $stop, $content, $conf, $times, $will]
+     * @test
      */
-    public function stdWrap_ifDataProvider()
+    public function getDataWithTypeDebugRootline()
     {
-        $content = $this->getUniqueId('content');
-        $conf = ['if.' => [$this->getUniqueId('if.')]];
-        return [
-            // evals to true
-            'empty config' => [
-                $content, false, $content, [], 0, null
-            ],
-            'if. is empty array' => [
-                $content, false, $content, ['if.' => []], 0, null
-            ],
-            'if. is null' => [
-                $content, false, $content, ['if.' => null], 0, null
-            ],
-            'if. is false' => [
-                $content, false, $content, ['if.' => false], 0, null
-            ],
-            'if. is 0' => [
-                $content, false, $content, ['if.' => false], 0, null
-            ],
-            'if. is "0"' => [
-                $content, false, $content, ['if.' => '0'], 0, null
-            ],
-            'checkIf returning true' => [
-                $content, false, $content, $conf, 1, true
-            ],
-            // evals to false
-            'checkIf returning false' => [
-                '', true, $content, $conf, 1, false
-            ],
-        ];
+        $rootline = array(
+            0 => array('uid' => 1, 'title' => 'title1'),
+            1 => array('uid' => 2, 'title' => 'title2'),
+            2 => array('uid' => 3, 'title' => ''),
+        );
+        $expectedResult = 'array(3items)0=>array(2items)uid=>1(integer)title=>"title1"(6chars)1=>array(2items)uid=>2(integer)title=>"title2"(6chars)2=>array(2items)uid=>3(integer)title=>""(0chars)';
+        $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
+
+        DebugUtility::useAnsiColor(false);
+        $result = $this->subject->getData('debug:rootLine');
+        $cleanedResult = str_replace("\r", '', $result);
+        $cleanedResult = str_replace("\n", '', $cleanedResult);
+        $cleanedResult = str_replace("\t", '', $cleanedResult);
+        $cleanedResult = str_replace(' ', '', $cleanedResult);
+
+        $this->assertEquals($expectedResult, $cleanedResult);
     }
 
     /**
-     * Check if stdWrap_if works properly.
-     *
-     * Show:
-     *
-     *  - Delegates to the method checkIf to check for 'true'.
-     *  - The parameter to checkIf is $conf['if.'].
-     *  - Is also 'true' if $conf['if.'] is empty (PHP method empty).
-     *  - 'False' triggers a stop of further rendering.
-     *  - Returns the content as is or '' if false.
+     * Checks if getData() works with type "debug:fullRootLine"
      *
      * @test
-     * @dataProvider stdWrap_ifDataProvider
-     * @param mixed $expect The expected output.
-     * @param bool $stop Expect stop further rendering.
-     * @param mixed $content The given content.
-     * @param mixed $config The given configuration.
-     * @param int $times Times checkIf is called (0 or 1).
-     * @param bool|null $will Return of checkIf (null if not called).
-     * @return void
      */
-    public function stdWrap_if($expect, $stop, $content, $conf, $times, $will)
+    public function getDataWithTypeDebugFullRootline()
     {
-        $subject = $this->getAccessibleMock(
-            ContentObjectRenderer::class, ['checkIf']);
-        $subject->_set('stdWrapRecursionLevel', 1);
-        $subject->_set('stopRendering', [1 => false]);
-        $subject
-            ->expects($this->exactly($times))
-            ->method('checkIf')
-            ->with($conf['if.'])
-            ->willReturn($will);
-        $this->assertSame($expect, $subject->stdWrap_if($content, $conf));
-        $this->assertSame($stop, $subject->_get('stopRendering')[1]);
+        $rootline = array(
+            0 => array('uid' => 1, 'title' => 'title1'),
+            1 => array('uid' => 2, 'title' => 'title2'),
+            2 => array('uid' => 3, 'title' => ''),
+        );
+        $expectedResult = 'array(3items)0=>array(2items)uid=>1(integer)title=>"title1"(6chars)1=>array(2items)uid=>2(integer)title=>"title2"(6chars)2=>array(2items)uid=>3(integer)title=>""(0chars)';
+        $GLOBALS['TSFE']->rootLine = $rootline;
+
+        DebugUtility::useAnsiColor(false);
+        $result = $this->subject->getData('debug:fullRootLine');
+        $cleanedResult = str_replace("\r", '', $result);
+        $cleanedResult = str_replace("\n", '', $cleanedResult);
+        $cleanedResult = str_replace("\t", '', $cleanedResult);
+        $cleanedResult = str_replace(' ', '', $cleanedResult);
+
+        $this->assertEquals($expectedResult, $cleanedResult);
     }
 
     /**
-     * Data provider for stdWrap_required.
+     * Checks if getData() works with type "debug:data"
      *
-     * @return array [$expect, $stop, $content]
+     * @test
      */
-    public function stdWrap_requiredDataProvider()
+    public function getDataWithTypeDebugData()
     {
-        return [
-            // empty content
-            'empty string is empty' => ['', true, ''],
-            'null is empty' => ['', true, null],
-            'false is empty' => ['', true, false],
+        $key = $this->getUniqueId('someKey');
+        $value = $this->getUniqueId('someValue');
+        $this->subject->data = array($key => $value);
 
-            // non-empty content
-            'blank is not empty' => [' ', false, ' '],
-            'tab is not empty' => [TAB, false, TAB],
-            'linebreak is not empty' => [PHP_EOL, false, PHP_EOL],
-            '"0" is not empty' => ['0', false, '0'],
-            '0 is not empty' => [0, false, 0],
-            '1 is not empty' => [1, false, 1],
-            'true is not empty' => [true, false, true],
-        ];
+        $expectedResult = 'array(1item)' . $key . '=>"' . $value . '"(' . strlen($value) . 'chars)';
+
+        DebugUtility::useAnsiColor(false);
+        $result = $this->subject->getData('debug:data');
+        $cleanedResult = str_replace("\r", '', $result);
+        $cleanedResult = str_replace("\n", '', $cleanedResult);
+        $cleanedResult = str_replace("\t", '', $cleanedResult);
+        $cleanedResult = str_replace(' ', '', $cleanedResult);
+
+        $this->assertEquals($expectedResult, $cleanedResult);
     }
 
     /**
-     * Check if stdWrap_required works properly.
-     *
-     * Show:
-     *
-     *  - Content is empty if it equals '' after cast to string.
-     *  - Empty content triggers a stop of further rendering.
-     *  - Returns the content as is or '' for empty content.
+     * Checks if getData() works with type "debug:register"
      *
      * @test
-     * @dataProvider stdWrap_requiredDataProvider
-     * @param mixed $expect The expected output.
-     * @param bool $stop Expect stop further rendering.
-     * @param mixed $content The given input.
-     * @return void
      */
-    public function stdWrap_required($expect, $stop, $content)
+    public function getDataWithTypeDebugRegister()
     {
-        $subject = $this->subject;
-        $subject->_set('stdWrapRecursionLevel', 1);
-        $subject->_set('stopRendering', [1 => false]);
-        $this->assertSame($expect, $subject->stdWrap_required($content));
-        $this->assertSame($stop, $subject->_get('stopRendering')[1]);
-    }
+        $key = $this->getUniqueId('someKey');
+        $value = $this->getUniqueId('someValue');
+        $GLOBALS['TSFE']->register = array($key => $value);
 
-    /**
-     * Data provider for stdWrap_intval
-     *
-     * @return array [$expect, $content]
-     */
-    public function stdWrap_intvalDataProvider()
-    {
-        return [
-            // numbers
-            'int' => [123, 123],
-            'float' => [123, 123.45],
-            'float does not round up' => [123, 123.55],
-            // negative numbers
-            'negative int' => [-123, -123],
-            'negative float' => [-123, -123.45],
-            'negative float does not round down' => [-123, -123.55],
-            // strings
-            'word string' => [0, 'string'],
-            'empty string' => [0, ''],
-            'zero string' => [0, '0'],
-            'int string' => [123, '123'],
-            'float string' => [123, '123.55'],
-            'negative float string' => [-123, '-123.55'],
-            // other types
-            'null' => [0, null],
-            'true' => [1, true],
-            'false' => [0, false]
-        ];
+        $expectedResult = 'array(1item)' . $key . '=>"' . $value . '"(' . strlen($value) . 'chars)';
+
+        DebugUtility::useAnsiColor(false);
+        $result = $this->subject->getData('debug:register');
+        $cleanedResult = str_replace("\r", '', $result);
+        $cleanedResult = str_replace("\n", '', $cleanedResult);
+        $cleanedResult = str_replace("\t", '', $cleanedResult);
+        $cleanedResult = str_replace(' ', '', $cleanedResult);
+
+        $this->assertEquals($expectedResult, $cleanedResult);
     }
 
     /**
-     * Check that stdWrap_intval works properly.
-     *
-     * Show:
-     *
-     * - It does not round up.
-     * - All types of input is casted to int:
-     *   - null: 0
-     *   - false: 0
-     *   - true: 1
-     *   -
-     *
-     *
+     * Checks if getData() works with type "data:page"
      *
      * @test
-     * @dataProvider stdWrap_intvalDataProvider
-     * @param int $expect The expected output.
-     * @param string $content The given input.
-     * @return void
      */
-    public function stdWrap_intval($expect, $content)
+    public function getDataWithTypeDebugPage()
     {
-        $this->assertSame($expect, $this->subject->stdWrap_intval($content));
+        $uid = rand();
+        $GLOBALS['TSFE']->page = array('uid' => $uid);
+
+        $expectedResult = 'array(1item)uid=>' . $uid . '(integer)';
+
+        DebugUtility::useAnsiColor(false);
+        $result = $this->subject->getData('debug:page');
+        $cleanedResult = str_replace("\r", '', $result);
+        $cleanedResult = str_replace("\n", '', $cleanedResult);
+        $cleanedResult = str_replace("\t", '', $cleanedResult);
+        $cleanedResult = str_replace(' ', '', $cleanedResult);
+
+        $this->assertEquals($expectedResult, $cleanedResult);
     }
 
     /**
-     * Data provider for stdWrap_strPad.
-     *
-     * @return array [$expect, $content, $conf]
+     * @test
      */
-    public function stdWrap_strPadDataProvider()
+    public function getTreeListReturnsChildPageUids()
     {
-        return [
-            'pad string with default settings and length 10' => [
-                'Alien     ',
-                'Alien',
-                [
-                    'length' => '10',
-                ],
-            ],
-            'pad string with padWith -= and type left and length 10' => [
-                '-=-=-Alien',
-                'Alien',
-                [
-                    'length' => '10',
-                    'padWith' => '-=',
-                    'type' => 'left',
-                ],
-            ],
-            'pad string with padWith _ and type both and length 10' => [
-                '__Alien___',
-                'Alien',
-                [
-                    'length' => '10',
-                    'padWith' => '_',
-                    'type' => 'both',
-                ],
-            ],
-            'pad string with padWith 0 and type both and length 10' => [
-                '00Alien000',
-                'Alien',
-                [
-                    'length' => '10',
-                    'padWith' => '0',
-                    'type' => 'both',
-                ],
-            ],
-            'pad string with padWith ___ and type both and length 6' => [
-                'Alien_',
-                'Alien',
-                [
-                    'length' => '6',
-                    'padWith' => '___',
-                    'type' => 'both',
-                ],
-            ],
-            'pad string with padWith _ and type both and length 12, using stdWrap for length' => [
-                '___Alien____',
-                'Alien',
-                [
-                    'length' => '1',
-                    'length.' => [
-                        'wrap' => '|2',
-                    ],
-                    'padWith' => '_',
-                    'type' => 'both',
-                ],
-            ],
-            'pad string with padWith _ and type both and length 12, using stdWrap for padWidth' => [
-                '-_=Alien-_=-',
-                'Alien',
-                [
-                    'length' => '12',
-                    'padWith' => '_',
-                    'padWith.' => [
-                        'wrap' => '-|=',
-                    ],
-                    'type' => 'both',
-                ],
-            ],
-            'pad string with padWith _ and type both and length 12, using stdWrap for type' => [
-                '_______Alien',
-                'Alien',
-                [
-                    'length' => '12',
-                    'padWith' => '_',
-                    'type' => 'both',
-                    // make type become "left"
-                    'type.' => [
-                        'substring' => '2,1',
-                        'wrap' => 'lef|',
-                    ],
-                ],
-            ],
-        ];
+        $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTgetSingleRow')->with('treelist')->will($this->returnValue(null));
+        $GLOBALS['TSFE']->sys_page
+            ->expects($this->any())
+            ->method('getRawRecord')
+            ->will(
+                $this->onConsecutiveCalls(
+                    array('uid' => 17),
+                    array('uid' => 321),
+                    array('uid' => 719),
+                    array('uid' => 42)
+                )
+            );
+
+        $GLOBALS['TSFE']->sys_page->expects($this->any())->method('getMountPointInfo')->will($this->returnValue(null));
+        $GLOBALS['TYPO3_DB']
+            ->expects($this->any())
+            ->method('exec_SELECTgetRows')
+            ->will(
+                $this->onConsecutiveCalls(
+                    array(
+                        array('uid' => 321)
+                    ),
+                    array(
+                        array('uid' => 719)
+                    ),
+                    array(
+                        array('uid' => 42)
+                    )
+                )
+            );
+        // 17 = pageId, 5 = recursionLevel, 0 = begin (entry to recursion, internal), TRUE = do not check enable fields
+        // 17 is positive, we expect 17 NOT to be included in result
+        $result = $this->subject->getTreeList(17, 5, 0, true);
+        $expectedResult = '42,719,321';
+        $this->assertEquals($expectedResult, $result);
     }
 
     /**
-     * Check if stdWrap_strPad works properly.
-     *
      * @test
-     * @dataProvider stdWrap_strPadDataProvider
-     * @param string $expect The expected output.
-     * @param string $content The given input.
-     * @param array $conf The configuration of 'strPad.'.
-     * @return void
      */
-    public function stdWrap_strPad($expect, $content, $conf)
+    public function getTreeListReturnsChildPageUidsAndOriginalPidForNegativeValue()
     {
-        $conf = ['strPad.' => $conf];
-        $result = $this->subject->stdWrap_strPad($content, $conf);
-        $this->assertSame($expect, $result);
+        $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTgetSingleRow')->with('treelist')->will($this->returnValue(null));
+        $GLOBALS['TSFE']->sys_page
+            ->expects($this->any())
+            ->method('getRawRecord')
+            ->will(
+                $this->onConsecutiveCalls(
+                    array('uid' => 17),
+                    array('uid' => 321),
+                    array('uid' => 719),
+                    array('uid' => 42)
+                )
+            );
+
+        $GLOBALS['TSFE']->sys_page->expects($this->any())->method('getMountPointInfo')->will($this->returnValue(null));
+        $GLOBALS['TYPO3_DB']
+            ->expects($this->any())
+            ->method('exec_SELECTgetRows')
+            ->will(
+                $this->onConsecutiveCalls(
+                    array(
+                        array('uid' => 321)
+                    ),
+                    array(
+                        array('uid' => 719)
+                    ),
+                    array(
+                        array('uid' => 42)
+                    )
+                )
+            );
+        // 17 = pageId, 5 = recursionLevel, 0 = begin (entry to recursion, internal), TRUE = do not check enable fields
+        // 17 is negative, we expect 17 to be included in result
+        $result = $this->subject->getTreeList(-17, 5, 0, true);
+        $expectedResult = '42,719,321,17';
+        $this->assertEquals($expectedResult, $result);
     }
 
     /**
-     * Check that stdWrap_stdWrap works properly.
-     *
-     * Show:
-     *  - Delegates to method stdWrap.
-     *  - Parameter 1 is $content.
-     *  - Parameter 2 is $conf['stdWrap.'].
-     *  - Returns the return value.
-     *
-     *  @test
-     *  @return void.
+     * @test
      */
-    public function stdWrap_stdWrap()
+    public function aTagParamsHasLeadingSpaceIfNotEmpty()
     {
-        $content = $this->getUniqueId('content');
-        $conf = [
-            'stdWrap' => $this->getUniqueId('not used'),
-            'stdWrap.' => [$this->getUniqueId('stdWrap.')],
-        ];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['stdWrap'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('stdWrap')
-            ->with($content, $conf['stdWrap.'])
-            ->willReturn($return);
-        $this->assertSame($return, $subject->stdWrap_stdWrap($content, $conf));
+        $aTagParams = $this->subject->getATagParams(array('ATagParams' => 'data-test="testdata"'));
+        $this->assertEquals(' data-test="testdata"', $aTagParams);
     }
 
     /**
-     * Check that stdWrap_dataWrap works properly.
-     *
-     * Show:
-     *
-     *  - Delegates to method dataWrap.
-     *  - Parameter 1 is $content.
-     *  - Parameter 2 is $conf['dataWrap'].
-     *  - Returns the return value.
-     *
-     *  @test
-     *  @return void.
+     * @test
      */
-    public function stdWrap_dataWrap()
+    public function aTagParamsHaveSpaceBetweenLocalAndGlobalParams()
     {
-        $content = $this->getUniqueId('content');
-        $conf = [
-            'dataWrap' => $this->getUniqueId('dataWrap'),
-            'dataWrap.' => [$this->getUniqueId('not used')],
-        ];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['dataWrap'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('dataWrap')
-            ->with($content, $conf['dataWrap'])
-            ->willReturn($return);
-        $this->assertSame($return,
-            $subject->stdWrap_dataWrap($content, $conf));
+        $GLOBALS['TSFE']->ATagParams = 'data-global="dataglobal"';
+        $aTagParams = $this->subject->getATagParams(array('ATagParams' => 'data-test="testdata"'));
+        $this->assertEquals(' data-global="dataglobal" data-test="testdata"', $aTagParams);
     }
 
     /**
-     * Data provider for stdWrap_prefixComment.
-     *
-     * @retunr array [$expect, $content, $conf, $disable, $times, $will]
+     * @test
      */
-    public function stdWrap_prefixCommentDataProvider()
+    public function aTagParamsHasNoLeadingSpaceIfEmpty()
     {
-        $content = $this->getUniqueId('content');
-        $will = $this->getUniqueId('will');
-        $conf['prefixComment'] = $this->getUniqueId('prefixComment');
-        $emptyConf1 = [];
-        $emptyConf2['prefixComment'] = '';
-        return [
-            'standard case' => [$will, $content, $conf, false, 1, $will],
-            'emptyConf1' => [$content, $content, $emptyConf1, false, 0, $will],
-            'emptyConf2' => [$content, $content, $emptyConf2, false, 0, $will],
-            'disabled by bool' => [$content, $content, $conf, true, 0, $will],
-            'disabled by int' => [$content, $content, $conf, 1, 0, $will],
-        ];
+        // make sure global ATagParams are empty
+        $GLOBALS['TSFE']->ATagParams = '';
+        $aTagParams = $this->subject->getATagParams(array('ATagParams' => ''));
+        $this->assertEquals('', $aTagParams);
     }
 
     /**
-     * Check that stdWrap_prefixComment works properly.
-     *
-     * Show:
-     *
-     *  - Delegates to method prefixComment.
-     *  - Parameter 1 is $conf['prefixComment'].
-     *  - Parameter 2 is [].
-     *  - Parameter 3 is $content.
-     *  - Returns the return value.
-     *  - Returns $content as is,
-     *    - if $conf['prefixComment'] is empty.
-     *    - if 'config.disablePrefixComment' is configured by the frontend.
-     *
-     *  @test
-     *  @dataProvider stdWrap_prefixCommentDataProvider
-     *  @return void
+     * @return array
      */
-    public function stdWrap_prefixComment(
-        $expect, $content, $conf, $disable, $times, $will)
+    public function getImageTagTemplateFallsBackToDefaultTemplateIfNoTemplateIsFoundDataProvider()
     {
-        $this->frontendControllerMock
-            ->config['config']['disablePrefixComment'] = $disable;
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['prefixComment'])->getMock();
-        $subject
-            ->expects($this->exactly($times))
-            ->method('prefixComment')
-            ->with($conf['prefixComment'], [], $content)
-            ->willReturn($will);
-        $this->assertSame($expect,
-            $subject->stdWrap_prefixComment($content, $conf));
+        return array(
+            array(null, null),
+            array('', null),
+            array('', array()),
+            array('fooo', array('foo' => 'bar'))
+        );
     }
 
     /**
-     * Data provider for the hash test
+     * Make sure that the rendering falls back to the classic <img style if nothing else is found
      *
-     * @return array [$expect, $content, $conf]
+     * @test
+     * @dataProvider getImageTagTemplateFallsBackToDefaultTemplateIfNoTemplateIsFoundDataProvider
+     * @param string $key
+     * @param array $configuration
      */
-    public function hashDataProvider()
+    public function getImageTagTemplateFallsBackToDefaultTemplateIfNoTemplateIsFound($key, $configuration)
     {
-        return [
-            'md5' => [
-                'bacb98acf97e0b6112b1d1b650b84971',
-                'joh316',
-                ['hash' => 'md5']
-            ],
-            'sha1' => [
-                '063b3d108bed9f88fa618c6046de0dccadcf3158',
-                'joh316',
-                ['hash' => 'sha1']
-            ],
-            'stdWrap capability' => [
-                'bacb98acf97e0b6112b1d1b650b84971',
-                'joh316',
-                [
-                    'hash' => '5',
-                    'hash.' => ['wrap' => 'md|']
-                ]
-            ],
-            'non-existing hashing algorithm' => [
-                '',
-                'joh316',
-                ['hash' => 'non-existing']
-            ]
-        ];
+        $defaultImgTagTemplate = '<img src="###SRC###" width="###WIDTH###" height="###HEIGHT###" ###PARAMS### ###ALTPARAMS### ###BORDER######SELFCLOSINGTAGSLASH###>';
+        $result = $this->subject->getImageTagTemplate($key, $configuration);
+        $this->assertEquals($result, $defaultImgTagTemplate);
     }
 
     /**
-     * Check if stdWrap_hash works properly.
-     *
-     * Show:
-     *
-     *  - Algorithms: sha1, md5
-     *  - Returns '' for invalid algorithm.
-     *  - Value can be processed by stdWrap.
+     * @return array
+     */
+    public function getImageTagTemplateReturnTemplateElementIdentifiedByKeyDataProvider()
+    {
+        return array(
+            array(
+                'foo',
+                array(
+                    'layout.' => array(
+                        'foo.' => array(
+                            'element' => '<img src="###SRC###" srcset="###SOURCES###" ###PARAMS### ###ALTPARAMS### ###FOOBAR######SELFCLOSINGTAGSLASH###>'
+                        )
+                    )
+                ),
+                '<img src="###SRC###" srcset="###SOURCES###" ###PARAMS### ###ALTPARAMS### ###FOOBAR######SELFCLOSINGTAGSLASH###>'
+            )
+
+        );
+    }
+
+    /**
+     * Assure if a layoutKey and layout is given the selected layout is returned
      *
      * @test
-     * @dataProvider hashDataProvider
-     * @param string $expect The expected output.
-     * @param string $content The given content.
-     * @param array $conf The given configuration.
-     * @return void
+     * @dataProvider getImageTagTemplateReturnTemplateElementIdentifiedByKeyDataProvider
+     * @param string $key
+     * @param array $configuration
+     * @param string $expectation
      */
-    public function stdWrap_hash($expect, $content, $conf)
+    public function getImageTagTemplateReturnTemplateElementIdentifiedByKey($key, $configuration, $expectation)
     {
-        $this->assertSame($expect,
-            $this->subject->stdWrap_hash($content, $conf));
+        $result = $this->subject->getImageTagTemplate($key, $configuration);
+        $this->assertEquals($result, $expectation);
     }
 
     /**
-     * @test
+     * @return array
      */
-    public function recursiveStdWrapProperlyRendersBasicString()
+    public function getImageSourceCollectionReturnsEmptyStringIfNoSourcesAreDefinedDataProvider()
     {
-        $stdWrapConfiguration = array(
-            'noTrimWrap' => '|| 123|',
-            'stdWrap.' => array(
-                'wrap' => '<b>|</b>'
-            )
-        );
-        $this->assertSame(
-            '<b>Test</b> 123',
-            $this->subject->stdWrap('Test', $stdWrapConfiguration)
+        return array(
+            array(null, null, null),
+            array('foo', null, null),
+            array('foo', array('sourceCollection.' => 1), 'bar')
         );
     }
 
     /**
+     * Make sure the source collection is empty if no valid configuration or source collection is defined
+     *
      * @test
+     * @dataProvider getImageSourceCollectionReturnsEmptyStringIfNoSourcesAreDefinedDataProvider
+     * @param string $layoutKey
+     * @param array $configuration
+     * @param string $file
      */
-    public function recursiveStdWrapIsOnlyCalledOnce()
+    public function getImageSourceCollectionReturnsEmptyStringIfNoSourcesAreDefined($layoutKey, $configuration, $file)
     {
-        $stdWrapConfiguration = array(
-            'append' => 'TEXT',
-            'append.' => array(
-                'data' => 'register:Counter'
-            ),
-            'stdWrap.' => array(
-                'append' => 'LOAD_REGISTER',
-                'append.' => array(
-                    'Counter.' => array(
-                        'prioriCalc' => 'intval',
-                        'cObject' => 'TEXT',
-                        'cObject.' => array(
-                            'data' => 'register:Counter',
-                            'wrap' => '|+1',
-                        )
-                    )
-                )
-            )
-        );
-        $this->assertSame(
-            'Counter:1',
-            $this->subject->stdWrap('Counter:', $stdWrapConfiguration)
-        );
+        $result = $this->subject->getImageSourceCollection($layoutKey, $configuration, $file);
+        $this->assertSame($result, '');
     }
 
     /**
-     * Data provider for numberFormat.
+     * Make sure the generation of subimages calls the generation of the subimages and uses the layout -> source template
      *
-     * @return array [$expect, $content, $conf]
+     * @test
      */
-    public function numberFormatDataProvider()
+    public function getImageSourceCollectionRendersDefinedSources()
     {
-        return [
-            'testing decimals' => [
-                '0.80', 0.8,
-                ['decimals' => 2]
-            ],
-            'testing decimals with input as string' => [
-                '0.80', '0.8',
-                ['decimals' => 2]
-            ],
-            'testing dec_point' => [
-                '0,8', 0.8,
-                ['decimals' => 1, 'dec_point' => ',']
-            ],
-            'testing thousands_sep' => [
-                '1.000', 999.99,
-                [
-                    'decimals' => 0,
-                    'thousands_sep.' => ['char' => 46]
-                ]
-            ],
-            'testing mixture' => [
-                '1.281.731,5', 1281731.45,
-                [
-                    'decimals' => 1,
-                    'dec_point.' => ['char' => 44],
-                    'thousands_sep.' => ['char' => 46]
-                ]
-            ]
-        ];
-    }
+        /** @var $cObj \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer */
+        $cObj = $this->getMockBuilder(ContentObjectRenderer::class)
+            ->setMethods(array('stdWrap', 'getImgResource'))
+            ->getMock();
 
-    /**
-     * Check if numberFormat works properly.
-     *
-     * @dataProvider numberFormatDataProvider
-     * @test
-     */
-    public function numberFormat($expects, $content, $conf)
-    {
-        $this->assertSame($expects,
-            $this->subject->numberFormat($content, $conf));
-    }
+        $cObj->start(array(), 'tt_content');
 
-    /**
-     * Check if stdWrap_replacement works properly.
-     *
-     * Show:
-     *
-     * - Delegates to method replacement.
-     * - Parameter 1 is $content.
-     * - Parameter 2 is $conf['replacement.'].
-     * - Returns the return value.
-     *
-     * @test
-     * @return void
-     */
-    public function stdWrap_replacement()
-    {
-        $content = $this->getUniqueId('content');
-        $conf = [
-            'replacement' => $this->getUniqueId('not used'),
-            'replacement.' => [$this->getUniqueId('replacement.')],
-        ];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['replacement'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('replacement')
-            ->with($content, $conf['replacement.'])
-            ->willReturn($return);
-        $this->assertSame($return,
-            $subject->stdWrap_replacement($content, $conf));
-    }
+        $layoutKey = 'test';
 
-    /**
-     * Data provider replacement
-     *
-     * @return array [$expect, $content, $conf]
-     */
-    public function replacementDataProvider()
-    {
-        return [
-            'multiple replacements, including regex' => [
-                'There is an animal, an animal and an animal around the block! Yeah!',
-                'There_is_a_cat,_a_dog_and_a_tiger_in_da_hood!_Yeah!',
-                [
-                    '20.' => [
-                        'search' => '_',
-                        'replace.' => ['char' => '32']
-                    ],
-                    '120.' => [
-                        'search' => 'in da hood',
-                        'replace' => 'around the block'
-                    ],
-                    '130.' => [
-                        'search' => '#a (Cat|Dog|Tiger)#i',
-                        'replace' => 'an animal',
-                        'useRegExp' => '1'
-                    ]
-                ]
-            ],
-            'replacement with optionSplit, normal pattern' => [
-                'There1is2a3cat,3a3dog3and3a3tiger3in3da3hood!3Yeah!',
-                'There_is_a_cat,_a_dog_and_a_tiger_in_da_hood!_Yeah!',
-                [
-                    '10.' => [
-                        'search' => '_',
-                        'replace' => '1 || 2 || 3',
-                        'useOptionSplitReplace' => '1'
-                    ]
-                ]
-            ],
-            'replacement with optionSplit, using regex' => [
-                'There is a tiny cat, a midsized dog and a big tiger in da hood! Yeah!',
-                'There is a cat, a dog and a tiger in da hood! Yeah!',
-                [
-                    '10.' => [
-                        'search' => '#(a) (Cat|Dog|Tiger)#i',
-                        'replace' => '${1} tiny ${2} || ${1} midsized ${2} || ${1} big ${2}',
-                        'useOptionSplitReplace' => '1',
-                        'useRegExp' => '1'
-                    ]
-                ]
-            ]
-        ];
-    }
+        $configuration = array(
+            'layoutKey' => 'test',
+            'layout.' => array(
+                'test.' => array(
+                    'element' => '<img ###SRC### ###SRCCOLLECTION### ###SELFCLOSINGTAGSLASH###>',
+                    'source' => '---###SRC###---'
+                )
+            ),
+            'sourceCollection.' => array(
+                '1.' => array(
+                    'width' => '200'
+                )
+            )
+        );
 
-    /**
-     * Check if stdWrap.replacement and all of its properties work properly
-     *
-     * @test
-     * @dataProvider replacementDataProvider
-     * @param string $content The given input.
-     * @param string $expects The expected result.
-     * @param array $conf The given configuration.
-     * @return void
-     */
-    public function replacement($expects, $content, $conf)
-    {
-        $this->assertSame($expects,
-            $this->subject->_call('replacement', $content, $conf));
+        $file = 'testImageName';
+
+        // Avoid calling of stdWrap
+        $cObj
+            ->expects($this->any())
+            ->method('stdWrap')
+            ->will($this->returnArgument(0));
+
+        // Avoid calling of imgResource
+        $cObj
+            ->expects($this->exactly(1))
+            ->method('getImgResource')
+            ->with($this->equalTo('testImageName'))
+            ->will($this->returnValue(array(100, 100, null, 'bar')));
+
+        $result = $cObj->getImageSourceCollection($layoutKey, $configuration, $file);
+
+        $this->assertEquals('---bar---', $result);
     }
 
     /**
-     * Data provider for stdWrap_rawUrlEncode
+     * Data provider for the getImageSourceCollectionRendersDefinedLayoutKeyDefault test
      *
-     * @return array [$expect, $content].
+     * @return array multi-dimensional array with the second level like this:
+     * @see getImageSourceCollectionRendersDefinedLayoutKeyDefault
      */
-    public function stdWrap_rawUrlEncodeDataProvider()
+    public function getImageSourceCollectionRendersDefinedLayoutKeyDataDefaultProvider()
     {
-        return [
-            'https://typo3.org?id=10' => [
-                'https%3A%2F%2Ftypo3.org%3Fid%3D10',
-                'https://typo3.org?id=10',
-            ],
-            'https://typo3.org?id=10&foo=bar' => [
-                'https%3A%2F%2Ftypo3.org%3Fid%3D10%26foo%3Dbar',
-                'https://typo3.org?id=10&foo=bar',
-            ],
-        ];
+        /**
+         * @see css_styled_content/static/setup.txt
+         */
+        $sourceCollectionArray = array(
+            'small.' => array(
+                'width' => '200',
+                'srcsetCandidate' => '600w',
+                'mediaQuery' => '(max-device-width: 600px)',
+                'dataKey' => 'small',
+            ),
+            'smallRetina.' => array(
+                'if.directReturn' => 0,
+                'width' => '200',
+                'pixelDensity' => '2',
+                'srcsetCandidate' => '600w 2x',
+                'mediaQuery' => '(max-device-width: 600px) AND (min-resolution: 192dpi)',
+                'dataKey' => 'smallRetina',
+            )
+        );
+        return array(
+            array(
+                'default',
+                array(
+                    'layoutKey' => 'default',
+                    'layout.' => array(
+                        'default.' => array(
+                            'element' => '<img src="###SRC###" width="###WIDTH###" height="###HEIGHT###" ###PARAMS### ###ALTPARAMS### ###BORDER######SELFCLOSINGTAGSLASH###>',
+                            'source' => ''
+                        )
+                    ),
+                    'sourceCollection.' => $sourceCollectionArray
+                )
+            ),
+        );
     }
 
     /**
-     * Check if rawUrlEncode works properly.
+     * Make sure the generation of subimages renders the expected HTML Code for the sourceset
      *
      * @test
-     * @dataProvider stdWrap_rawUrlEncodeDataProvider
-     * @param string $expect The expected output.
-     * @param string $content The given input.
-     * @return void
+     * @dataProvider getImageSourceCollectionRendersDefinedLayoutKeyDataDefaultProvider
+     * @param string $layoutKey
+     * @param array $configuration
      */
-    public function stdWrap_rawUrlEncode($expect, $content)
+    public function getImageSourceCollectionRendersDefinedLayoutKeyDefault($layoutKey, $configuration)
     {
-        $this->assertSame($expect,
-            $this->subject->stdWrap_rawUrlEncode($content));
+        /** @var $cObj \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer */
+        $cObj = $this->getMockBuilder(ContentObjectRenderer::class)
+            ->setMethods(array('stdWrap', 'getImgResource'))
+            ->getMock();
+
+        $cObj->start(array(), 'tt_content');
+
+        $file = 'testImageName';
+
+        // Avoid calling of stdWrap
+        $cObj
+            ->expects($this->any())
+            ->method('stdWrap')
+            ->will($this->returnArgument(0));
+
+        $result = $cObj->getImageSourceCollection($layoutKey, $configuration, $file);
+
+        $this->assertEmpty($result);
     }
 
     /**
-     * Data provider for the getQuery test
+     * Data provider for the getImageSourceCollectionRendersDefinedLayoutKeyData test
      *
      * @return array multi-dimensional array with the second level like this:
-     * @see getQuery
+     * @see getImageSourceCollectionRendersDefinedLayoutKeyData
      */
-    public function getQueryDataProvider()
+    public function getImageSourceCollectionRendersDefinedLayoutKeyDataDataProvider()
     {
-        $data = array(
-            'testing empty conf' => array(
-                'tt_content',
-                array(),
-                array(
-                    'SELECT' => '*'
-                )
-            ),
-            'testing #17284: adding uid/pid for workspaces' => array(
-                'tt_content',
-                array(
-                    'selectFields' => 'header,bodytext'
-                ),
-                array(
-                    'SELECT' => 'header,bodytext, tt_content.uid as uid, tt_content.pid as pid, tt_content.t3ver_state as t3ver_state'
-                )
-            ),
-            'testing #17284: no need to add' => array(
-                'tt_content',
-                array(
-                    'selectFields' => 'tt_content.*'
-                ),
-                array(
-                    'SELECT' => 'tt_content.*'
-                )
-            ),
-            'testing #17284: no need to add #2' => array(
-                'tt_content',
-                array(
-                    'selectFields' => '*'
-                ),
-                array(
-                    'SELECT' => '*'
-                )
-            ),
-            'testing #29783: joined tables, prefix tablename' => array(
-                'tt_content',
-                array(
-                    'selectFields' => 'tt_content.header,be_users.username',
-                    'join' => 'be_users ON tt_content.cruser_id = be_users.uid'
-                ),
-                array(
-                    'SELECT' => 'tt_content.header,be_users.username, tt_content.uid as uid, tt_content.pid as pid, tt_content.t3ver_state as t3ver_state'
-                )
+        /**
+         * @see css_styled_content/static/setup.txt
+         */
+        $sourceCollectionArray = array(
+            'small.' => array(
+                'width' => '200',
+                'srcsetCandidate' => '600w',
+                'mediaQuery' => '(max-device-width: 600px)',
+                'dataKey' => 'small',
             ),
-            'testing #34152: single count(*), add nothing' => array(
-                'tt_content',
+            'smallRetina.' => array(
+                'if.directReturn' => 1,
+                'width' => '200',
+                'pixelDensity' => '2',
+                'srcsetCandidate' => '600w 2x',
+                'mediaQuery' => '(max-device-width: 600px) AND (min-resolution: 192dpi)',
+                'dataKey' => 'smallRetina',
+            )
+        );
+        return array(
+            array(
+                'srcset',
                 array(
-                    'selectFields' => 'count(*)'
+                    'layoutKey' => 'srcset',
+                    'layout.' => array(
+                        'srcset.' => array(
+                            'element' => '<img src="###SRC###" srcset="###SOURCECOLLECTION###" ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###>',
+                            'source' => '|*|###SRC### ###SRCSETCANDIDATE###,|*|###SRC### ###SRCSETCANDIDATE###'
+                        )
+                    ),
+                    'sourceCollection.' => $sourceCollectionArray
                 ),
-                array(
-                    'SELECT' => 'count(*)'
-                )
+                'xhtml_strict',
+                'bar-file.jpg 600w,bar-file.jpg 600w 2x',
             ),
-            'testing #34152: single max(crdate), add nothing' => array(
-                'tt_content',
+            array(
+                'picture',
                 array(
-                    'selectFields' => 'max(crdate)'
+                    'layoutKey' => 'picture',
+                    'layout.' => array(
+                        'picture.' => array(
+                            'element' => '<picture>###SOURCECOLLECTION###<img src="###SRC###" ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###></picture>',
+                            'source' => '<source src="###SRC###" media="###MEDIAQUERY###"###SELFCLOSINGTAGSLASH###>'
+                        )
+                    ),
+                    'sourceCollection.' => $sourceCollectionArray,
                 ),
-                array(
-                    'SELECT' => 'max(crdate)'
-                )
+                'xhtml_strict',
+                '<source src="bar-file.jpg" media="(max-device-width: 600px)" /><source src="bar-file.jpg" media="(max-device-width: 600px) AND (min-resolution: 192dpi)" />',
             ),
-            'testing #34152: single min(crdate), add nothing' => array(
-                'tt_content',
+            array(
+                'picture',
                 array(
-                    'selectFields' => 'min(crdate)'
+                    'layoutKey' => 'picture',
+                    'layout.' => array(
+                        'picture.' => array(
+                            'element' => '<picture>###SOURCECOLLECTION###<img src="###SRC###" ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###></picture>',
+                            'source' => '<source src="###SRC###" media="###MEDIAQUERY###"###SELFCLOSINGTAGSLASH###>'
+                        )
+                    ),
+                    'sourceCollection.' => $sourceCollectionArray,
                 ),
-                array(
-                    'SELECT' => 'min(crdate)'
-                )
+                '',
+                '<source src="bar-file.jpg" media="(max-device-width: 600px)"><source src="bar-file.jpg" media="(max-device-width: 600px) AND (min-resolution: 192dpi)">',
             ),
-            'testing #34152: single sum(is_siteroot), add nothing' => array(
-                'tt_content',
+            array(
+                'data',
                 array(
-                    'selectFields' => 'sum(is_siteroot)'
+                    'layoutKey' => 'data',
+                    'layout.' => array(
+                        'data.' => array(
+                            'element' => '<img src="###SRC###" ###SOURCECOLLECTION### ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###>',
+                            'source' => 'data-###DATAKEY###="###SRC###"'
+                        )
+                    ),
+                    'sourceCollection.' => $sourceCollectionArray
                 ),
-                array(
-                    'SELECT' => 'sum(is_siteroot)'
-                )
+                'xhtml_strict',
+                'data-small="bar-file.jpg"data-smallRetina="bar-file.jpg"',
             ),
-            'testing #34152: single avg(crdate), add nothing' => array(
-                'tt_content',
-                array(
-                    'selectFields' => 'avg(crdate)'
-                ),
-                array(
-                    'SELECT' => 'avg(crdate)'
-                )
-            )
         );
-        return $data;
     }
 
     /**
-     * Check if sanitizeSelectPart works as expected
+     * Make sure the generation of subimages renders the expected HTML Code for the sourceset
      *
-     * @dataProvider getQueryDataProvider
      * @test
+     * @dataProvider getImageSourceCollectionRendersDefinedLayoutKeyDataDataProvider
+     * @param string $layoutKey
+     * @param array $configuration
+     * @param string $xhtmlDoctype
+     * @param string $expectedHtml
      */
-    public function getQuery($table, $conf, $expected)
+    public function getImageSourceCollectionRendersDefinedLayoutKeyData($layoutKey, $configuration, $xhtmlDoctype, $expectedHtml)
     {
-        $GLOBALS['TCA'] = array(
-            'pages' => array(
-                'ctrl' => array(
-                    'enablecolumns' => array(
-                        'disabled' => 'hidden'
-                    )
-                )
-            ),
-            'tt_content' => array(
-                'ctrl' => array(
-                    'enablecolumns' => array(
-                        'disabled' => 'hidden'
-                    ),
-                    'versioningWS' => true
-                )
-            ),
-        );
-        $result = $this->subject->getQuery($table, $conf, true);
-        foreach ($expected as $field => $value) {
-            $this->assertEquals($value, $result[$field]);
-        }
-    }
+        /** @var $cObj \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer */
+        $cObj = $this->getMockBuilder(ContentObjectRenderer::class)
+            ->setMethods(array('stdWrap', 'getImgResource'))
+            ->getMock();
 
-    /**
-     * @test
-     */
-    public function getQueryCallsGetTreeListWithNegativeValuesIfRecursiveIsSet()
-    {
-        $GLOBALS['TCA'] = array(
-            'pages' => array(
-                'ctrl' => array(
-                    'enablecolumns' => array(
-                        'disabled' => 'hidden'
-                    )
-                )
-            ),
-            'tt_content' => array(
-                'ctrl' => array(
-                    'enablecolumns' => array(
-                        'disabled' => 'hidden'
-                    )
-                )
-            ),
-        );
-        $this->subject = $this->getAccessibleMock(ContentObjectRenderer::class, array('getTreeList'));
-        $this->subject->start(array(), 'tt_content');
-        $conf = array(
-            'recursive' => '15',
-            'pidInList' => '16, -35'
-        );
-        $this->subject->expects($this->at(0))
-            ->method('getTreeList')
-            ->with(-16, 15)
-            ->will($this->returnValue('15,16'));
-        $this->subject->expects($this->at(1))
-            ->method('getTreeList')
-            ->with(-35, 15)
-            ->will($this->returnValue('15,35'));
-        $this->subject->getQuery('tt_content', $conf, true);
+        $cObj->start(array(), 'tt_content');
+
+        $file = 'testImageName';
+
+        $GLOBALS['TSFE']->xhtmlDoctype = $xhtmlDoctype;
+
+        // Avoid calling of stdWrap
+        $cObj
+            ->expects($this->any())
+            ->method('stdWrap')
+            ->will($this->returnArgument(0));
+
+        // Avoid calling of imgResource
+        $cObj
+            ->expects($this->exactly(2))
+            ->method('getImgResource')
+            ->with($this->equalTo('testImageName'))
+            ->will($this->returnValue(array(100, 100, null, 'bar-file.jpg')));
+
+        $result = $cObj->getImageSourceCollection($layoutKey, $configuration, $file);
+
+        $this->assertEquals($expectedHtml, $result);
     }
 
     /**
+     * Make sure the hook in get sourceCollection is called
+     *
      * @test
      */
-    public function getQueryCallsGetTreeListWithCurrentPageIfThisIsSet()
+    public function getImageSourceCollectionHookCalled()
     {
-        $GLOBALS['TCA'] = array(
-            'pages' => array(
-                'ctrl' => array(
-                    'enablecolumns' => array(
-                        'disabled' => 'hidden'
-                    )
-                )
-            ),
-            'tt_content' => array(
-                'ctrl' => array(
-                    'enablecolumns' => array(
-                        'disabled' => 'hidden'
-                    )
-                )
-            ),
+        $this->subject = $this->getAccessibleMock(ContentObjectRenderer::class,
+            array('getResourceFactory', 'stdWrap', 'getImgResource')
         );
-        $this->subject = $this->getAccessibleMock(ContentObjectRenderer::class, array('getTreeList'));
-        $GLOBALS['TSFE']->id = 27;
         $this->subject->start(array(), 'tt_content');
-        $conf = array(
-            'pidInList' => 'this',
-            'recursive' => '4'
-        );
-        $this->subject->expects($this->once())
-            ->method('getTreeList')
-            ->with(-27)
-            ->will($this->returnValue('27'));
-        $this->subject->getQuery('tt_content', $conf, true);
-    }
 
-    /**
-     * Data provider for the stdWrap_date test
-     *
-     * @return array [$expect, $content, $conf, $now]
-     */
-    public function stdWrap_dateDataProvider()
-    {
-        // Fictive execution time: 2015-10-02 12:00
-        $now =  1443780000;
-        return [
-            'given timestamp' => [
-                '02.10.2015',
-                $now,
-                ['date' => 'd.m.Y'],
-                $now
-            ],
-            'empty string' => [
-                '02.10.2015',
-                '',
-                ['date' => 'd.m.Y'],
-                $now
-            ],
-            'testing null' => [
-                '02.10.2015',
-                null,
-                ['date' => 'd.m.Y'],
-                $now
-            ],
-            'given timestamp return GMT' => [
-                '02.10.2015 10:00:00',
-                $now,
-                [
-                    'date' => 'd.m.Y H:i:s',
-                    'date.' => ['GMT' => true],
-                ],
-                $now
-            ]
-        ];
-    }
+        // Avoid calling stdwrap and getImgResource
+        $this->subject->expects($this->any())
+            ->method('stdWrap')
+            ->will($this->returnArgument(0));
 
-    /**
-     * Check if stdWrap_date works properly.
-     *
-     * @test
-     * @dataProvider stdWrap_dateDataProvider
-     * @param string $expected The expected output.
-     * @param mixed $content The given input.
-     * @param array $conf The given configuration.
-     * @param int $now Fictive execution time.
-     * @return void
-     */
-    public function stdWrap_date($expected, $content, $conf, $now)
-    {
-        $GLOBALS['EXEC_TIME'] = $now;
-        $this->assertEquals($expected,
-            $this->subject->stdWrap_date($content, $conf));
-    }
+        $this->subject->expects($this->any())
+            ->method('getImgResource')
+            ->will($this->returnValue(array(100, 100, null, 'bar-file.jpg')));
 
-    /**
-     * Data provider for stdWrap_strftime
-     *
-     * @return array [$expect, $content, $conf, $now]
-     */
-    public function stdWrap_strftimeDataProvider()
-    {
-        // Fictive execution time is 2012-09-01 12:00 in UTC/GMT.
-        $now = 1346500800;
-        return [
-            'given timestamp' => [
-                '01-09-2012',
-                $now,
-                ['strftime' => '%d-%m-%Y'],
-                $now
-            ],
-            'empty string' => [
-                '01-09-2012',
-                '',
-                ['strftime' => '%d-%m-%Y'],
-                $now
-            ],
-            'testing null' => [
-                '01-09-2012',
-                null,
-                ['strftime' => '%d-%m-%Y'],
-                $now
-            ]
-        ];
-    }
+        $resourceFactory = $this->createMock(ResourceFactory::class);
+        $this->subject->expects($this->any())->method('getResourceFactory')->will($this->returnValue($resourceFactory));
 
-    /**
-     * Check if stdWrap_strftime works properly.
-     *
-     * @test
-     * @dataProvider stdWrap_strftimeDataProvider
-     * @param string $expect The expected output.
-     * @param mixed $content The given input.
-     * @param array $conf The given configuration.
-     * @param int $now Fictive execution time.
-     * @return void
-     */
-    public function stdWrap_strftime($expect, $content, $conf, $now)
-    {
-        // Save current timezone and set to UTC to make the system under test
-        // behave the same in all server timezone settings
-        $timezoneBackup = date_default_timezone_get();
-        date_default_timezone_set('UTC');
+        $className = $this->getUniqueId('tx_coretest_getImageSourceCollectionHookCalled');
+        $getImageSourceCollectionHookMock = $this->getMockBuilder(
+            ContentObjectOneSourceCollectionHookInterface::class)
+            ->setMethods(array('getOneSourceCollection'))
+            ->setMockClassName($className)
+            ->getMock();
+        GeneralUtility::addInstance($className, $getImageSourceCollectionHookMock);
+        $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['getImageSourceCollection'][] = $className;
 
-        $GLOBALS['EXEC_TIME'] = $now;
-        $result = $this->subject->stdWrap_strftime($content, $conf);
+        $getImageSourceCollectionHookMock
+            ->expects($this->exactly(1))
+            ->method('getOneSourceCollection')
+            ->will($this->returnCallback(array($this, 'isGetOneSourceCollectionCalledCallback')));
 
-        // Reset timezone
-        date_default_timezone_set($timezoneBackup);
+        $configuration = array(
+            'layoutKey' => 'data',
+            'layout.' => array(
+                'data.' => array(
+                    'element' => '<img src="###SRC###" ###SOURCECOLLECTION### ###PARAMS### ###ALTPARAMS######SELFCLOSINGTAGSLASH###>',
+                    'source' => 'data-###DATAKEY###="###SRC###"'
+                )
+            ),
+            'sourceCollection.' => array(
+                'small.' => array(
+                    'width' => '200',
+                    'srcsetCandidate' => '600w',
+                    'mediaQuery' => '(max-device-width: 600px)',
+                    'dataKey' => 'small',
+                ),
+            ),
+        );
 
-        $this->assertSame($expect, $result);
+        $result = $this->subject->getImageSourceCollection('data', $configuration, $this->getUniqueId('testImage-'));
+
+        $this->assertSame($result, 'isGetOneSourceCollectionCalledCallback');
     }
 
     /**
-     * Data provider for the stdWrap_strtotime test
+     * Handles the arguments that have been sent to the getImgResource hook.
      *
-     * @return array [$expect, $content, $conf]
+     * @param array $sourceRenderConfiguration
+     * @param array $sourceConfiguration
+     * @param $oneSourceCollection
+     * @param $parent
+     * @return string
+     * @see getImageSourceCollectionHookCalled
      */
-    public function stdWrap_strtotimeDataProvider()
+    public function isGetOneSourceCollectionCalledCallback($sourceRenderConfiguration, $sourceConfiguration, $oneSourceCollection, $parent)
     {
-        return [
-            'date from content' => [
-                1417651200, '2014-12-04',
-                ['strtotime' => '1']
-            ],
-            'manipulation of date from content' => [
-                1417996800, '2014-12-04',
-                ['strtotime' => '+ 2 weekdays']
-            ],
-            'date from configuration' => [
-                1417651200, '',
-                ['strtotime' => '2014-12-04']
-            ],
-            'manipulation of date from configuration' => [
-                1417996800, '',
-                ['strtotime' => '2014-12-04 + 2 weekdays']
-            ],
-            'empty input' => [
-                false, '',
-                ['strtotime' => '1']
-            ],
-            'date from content and configuration' => [
-                false, '2014-12-04',
-                ['strtotime' => '2014-12-05']
-            ]
-        ];
+        $this->assertTrue(is_array($sourceRenderConfiguration));
+        $this->assertTrue(is_array($sourceConfiguration));
+        return 'isGetOneSourceCollectionCalledCallback';
     }
 
     /**
-     * Check if stdWrap_strtotime works properly.
-     *
+     * @param string $expected The expected URL
+     * @param string $url The URL to parse and manipulate
+     * @param array $configuration The configuration array
      * @test
-     * @dataProvider stdWrap_strtotimeDataProvider
-     * @param int $expect The expected output.
-     * @param mixed $content The given input.
-     * @param array $conf The given configuration.
-     * @return void
+     * @dataProvider forceAbsoluteUrlReturnsCorrectAbsoluteUrlDataProvider
      */
-    public function stdWrap_strtotime($expect, $content, $conf)
+    public function forceAbsoluteUrlReturnsCorrectAbsoluteUrl($expected, $url, array $configuration)
     {
-        // Set exec_time to a hard timestamp
-        $GLOBALS['EXEC_TIME'] = 1417392000;
-        // Save current timezone and set to UTC to make the system under test
-        // behave the same in all server timezone settings
-        $timezoneBackup = date_default_timezone_get();
-        date_default_timezone_set('UTC');
-
-        $result = $this->subject->stdWrap_strtotime($content, $conf);
-
-        // Reset timezone
-        date_default_timezone_set($timezoneBackup);
+        // Force hostname
+        $this->subject->expects($this->any())->method('getEnvironmentVariable')->will($this->returnValueMap(
+            array(
+                array('HTTP_HOST', 'localhost'),
+                array('TYPO3_SITE_PATH', '/'),
+            )
+        ));
+        $GLOBALS['TSFE']->absRefPrefix = '';
 
-        $this->assertEquals($expect, $result);
+        $this->assertEquals($expected, $this->subject->_call('forceAbsoluteUrl', $url, $configuration));
     }
 
     /**
-     * Check if stdWrap_age works properly.
-     *
-     * Show:
-     *
-     * - Delegates to calcAge.
-     * - Parameter 1 is the difference between $content and EXEC_TIME.
-     * - Parameter 2 is $conf['age'].
-     * - Returns the return value.
-     *
-     * @test
-     * @return void
+     * @return array The test data for forceAbsoluteUrlReturnsAbsoluteUrl
      */
-    public function stdWrap_age()
+    public function forceAbsoluteUrlReturnsCorrectAbsoluteUrlDataProvider()
     {
-        $now = 10;
-        $content = '9';
-        $conf = ['age' => $this->getUniqueId('age')];
-        $return = $this->getUniqueId('return');
-        $difference = $now - (int)$content;
-        $GLOBALS['EXEC_TIME'] = $now;
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['calcAge'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('calcAge')
-            ->with($difference, $conf['age'])
-            ->willReturn($return);
-        $this->assertSame($return, $subject->stdWrap_age($content, $conf));
+        return array(
+            'Missing forceAbsoluteUrl leaves URL untouched' => array(
+                'foo',
+                'foo',
+                array()
+            ),
+            'Absolute URL stays unchanged' => array(
+                'http://example.org/',
+                'http://example.org/',
+                array(
+                    'forceAbsoluteUrl' => '1'
+                )
+            ),
+            'Absolute URL stays unchanged 2' => array(
+                'http://example.org/resource.html',
+                'http://example.org/resource.html',
+                array(
+                    'forceAbsoluteUrl' => '1'
+                )
+            ),
+            'Scheme and host w/o ending slash stays unchanged' => array(
+                'http://example.org',
+                'http://example.org',
+                array(
+                    'forceAbsoluteUrl' => '1'
+                )
+            ),
+            'Scheme can be forced' => array(
+                'typo3://example.org',
+                'http://example.org',
+                array(
+                    'forceAbsoluteUrl' => '1',
+                    'forceAbsoluteUrl.' => array(
+                        'scheme' => 'typo3'
+                    )
+                )
+            ),
+            'Relative path old-style' => array(
+                'http://localhost/fileadmin/dummy.txt',
+                '/fileadmin/dummy.txt',
+                array(
+                    'forceAbsoluteUrl' => '1',
+                )
+            ),
+            'Relative path' => array(
+                'http://localhost/fileadmin/dummy.txt',
+                'fileadmin/dummy.txt',
+                array(
+                    'forceAbsoluteUrl' => '1',
+                )
+            ),
+            'Scheme can be forced with pseudo-relative path' => array(
+                'typo3://localhost/fileadmin/dummy.txt',
+                '/fileadmin/dummy.txt',
+                array(
+                    'forceAbsoluteUrl' => '1',
+                    'forceAbsoluteUrl.' => array(
+                        'scheme' => 'typo3'
+                    )
+                )
+            ),
+            'Hostname only is not treated as valid absolute URL' => array(
+                'http://localhost/example.org',
+                'example.org',
+                array(
+                    'forceAbsoluteUrl' => '1'
+                )
+            ),
+            'Scheme and host is added to local file path' => array(
+                'typo3://localhost/fileadmin/my.pdf',
+                'fileadmin/my.pdf',
+                array(
+                    'forceAbsoluteUrl' => '1',
+                    'forceAbsoluteUrl.' => array(
+                        'scheme' => 'typo3'
+                    )
+                )
+            )
+        );
     }
 
     /**
-     * Data provider for calcAge.
-     *
-     * @return array [$expect, $timestamp, $labels]
+     * @test
      */
-    public function calcAgeDataProvider()
+    public function renderingContentObjectThrowsException()
     {
-        return [
-            'minutes' => [
-                '2 min', 120, ' min| hrs| days| yrs',
-            ],
-            'hours' => [
-                '2 hrs', 7200, ' min| hrs| days| yrs',
-            ],
-            'days' => [
-                '7 days', 604800, ' min| hrs| days| yrs',
-            ],
-            'day with provided singular labels' => [
-                '1 day', 86400, ' min| hrs| days| yrs| min| hour| day| year',
-            ],
-            'years' => [
-                '45 yrs', 1417997800, ' min| hrs| days| yrs',
-            ],
-            'different labels' => [
-                '2 Minutes', 120, ' Minutes| Hrs| Days| Yrs',
-            ],
-            'negative values' => [
-                '-7 days', -604800, ' min| hrs| days| yrs',
-            ],
-            'default label values for wrong label input' => [
-                '2 min', 121, 10,
-            ],
-            'default singular label values for wrong label input' => [
-                '1 year', 31536000, 10,
-            ]
-        ];
+        $this->expectException(\LogicException::class);
+        $this->expectExceptionCode(1414513947);
+        $contentObjectFixture = $this->createContentObjectThrowingExceptionFixture();
+        $this->subject->render($contentObjectFixture, array());
     }
 
     /**
-     * Check if calcAge works properly.
-     *
      * @test
-     * @dataProvider calcAgeDataProvider
-     * @param int $expect
-     * @param int $timestamp
-     * @param string $labels
-     * @return void
      */
-    public function calcAge($expect, $timestamp, $labels)
+    public function exceptionHandlerIsEnabledByDefaultInProductionContext()
     {
-        $this->assertSame($expect,
-            $this->subject->calcAge($timestamp, $labels));
+        $backupApplicationContext = GeneralUtility::getApplicationContext();
+        Fixtures\GeneralUtilityFixture::setApplicationContext(new ApplicationContext('Production'));
+
+        $contentObjectFixture = $this->createContentObjectThrowingExceptionFixture();
+        $this->subject->render($contentObjectFixture, array());
+
+        Fixtures\GeneralUtilityFixture::setApplicationContext($backupApplicationContext);
     }
 
     /**
-     * @return array
+     * @test
      */
-    public function stdWrapReturnsExpectationDataProvider()
+    public function renderingContentObjectDoesNotThrowExceptionIfExceptionHandlerIsConfiguredLocally()
     {
-        return [
-            'Prevent silent bool conversion' => [
-                '1+1',
-                [
-                    'prioriCalc.' => [
-                        'wrap' => '|',
-                    ],
-                ],
-                '1+1',
-            ],
-        ];
+        $contentObjectFixture = $this->createContentObjectThrowingExceptionFixture();
+
+        $configuration = array(
+            'exceptionHandler' => '1'
+        );
+        $this->subject->render($contentObjectFixture, $configuration);
     }
 
     /**
-     * @param string $content
-     * @param array $configuration
-     * @param string $expectation
-     * @dataProvider stdWrapReturnsExpectationDataProvider
      * @test
      */
-    public function stdWrapReturnsExpectation($content, array $configuration, $expectation)
+    public function renderingContentObjectDoesNotThrowExceptionIfExceptionHandlerIsConfiguredGlobally()
     {
-        $this->assertSame($expectation, $this->subject->stdWrap($content, $configuration));
+        $contentObjectFixture = $this->createContentObjectThrowingExceptionFixture();
+
+        $this->frontendControllerMock->config['config']['contentObjectExceptionHandler'] = '1';
+        $this->subject->render($contentObjectFixture, array());
     }
 
     /**
-     * Data provider for stdWrap_case test
-     *
-     * @return array
+     * @test
      */
-    public function stdWrap_caseDataProvider()
+    public function globalExceptionHandlerConfigurationCanBeOverriddenByLocalConfiguration()
     {
-        return array(
-            'lower case text to upper' => array(
-                '<span>text</span>',
-                array(
-                    'case' => 'upper',
-                ),
-                '<span>TEXT</span>',
-            ),
-            'upper case text to lower' => array(
-                '<span>TEXT</span>',
-                array(
-                    'case' => 'lower',
-                ),
-                '<span>text</span>',
-            ),
-            'capitalize text' => array(
-                '<span>this is a text</span>',
-                array(
-                    'case' => 'capitalize',
-                ),
-                '<span>This Is A Text</span>',
-            ),
-            'ucfirst text' => array(
-                '<span>this is a text</span>',
-                array(
-                    'case' => 'ucfirst',
-                ),
-                '<span>This is a text</span>',
-            ),
-            'lcfirst text' => array(
-                '<span>This is a Text</span>',
-                array(
-                    'case' => 'lcfirst',
-                ),
-                '<span>this is a Text</span>',
-            ),
-            'uppercamelcase text' => array(
-                '<span>this_is_a_text</span>',
-                array(
-                    'case' => 'uppercamelcase',
-                ),
-                '<span>ThisIsAText</span>',
-            ),
-            'lowercamelcase text' => array(
-                '<span>this_is_a_text</span>',
-                array(
-                    'case' => 'lowercamelcase',
-                ),
-                '<span>thisIsAText</span>',
-            ),
+        $contentObjectFixture = $this->createContentObjectThrowingExceptionFixture();
+        $this->expectException(\LogicException::class);
+        $this->expectExceptionCode(1414513947);
+        $this->frontendControllerMock->config['config']['contentObjectExceptionHandler'] = '1';
+        $configuration = array(
+            'exceptionHandler' => '0'
         );
+        $this->subject->render($contentObjectFixture, $configuration);
     }
 
     /**
-     * @param string|NULL $content
-     * @param array $configuration
-     * @param string $expected
-     * @dataProvider stdWrap_caseDataProvider
      * @test
      */
-    public function stdWrap_case($content, array $configuration, $expected)
+    public function renderedErrorMessageCanBeCustomized()
     {
-        $result = $this->subject->stdWrap_case($content, $configuration);
-        $this->assertEquals($expected, $result);
+        $contentObjectFixture = $this->createContentObjectThrowingExceptionFixture();
+
+        $configuration = array(
+            'exceptionHandler' => '1',
+            'exceptionHandler.' => array(
+                'errorMessage' => 'New message for testing',
+            )
+        );
+
+        $this->assertSame('New message for testing', $this->subject->render($contentObjectFixture, $configuration));
     }
 
     /**
-     * Data provider for stdWrap_bytes.
-     *
-     * @return array [$expect, $content, $conf]
+     * @test
      */
-    public function stdWrap_bytesDataProvider()
+    public function localConfigurationOverridesGlobalConfiguration()
     {
-        return [
-            'value 1234 default' => [
-                '1.21 Ki', '1234',
-                ['labels' => '', 'base' => 0],
-            ],
-            'value 1234 si' => [
-                '1.23 k', '1234',
-                ['labels' => 'si', 'base' => 0],
-            ],
-            'value 1234 iec' => [
-                '1.21 Ki', '1234',
-                ['labels' => 'iec', 'base' => 0],
-            ],
-            'value 1234 a-i' => [
-                '1.23b', '1234',
-                ['labels' => 'a|b|c|d|e|f|g|h|i', 'base' => 1000],
-            ],
-            'value 1234 a-i invalid base' => [
-                '1.21b', '1234',
-                ['labels' => 'a|b|c|d|e|f|g|h|i', 'base' => 54],
-            ],
-            'value 1234567890 default' => [
-                '1.15 Gi', '1234567890',
-                ['labels' => '', 'base' => 0],
-            ]
-        ];
+        $contentObjectFixture = $this->createContentObjectThrowingExceptionFixture();
+
+        $this->frontendControllerMock
+            ->config['config']['contentObjectExceptionHandler.'] = array(
+                'errorMessage' => 'Global message for testing',
+            );
+        $configuration = array(
+            'exceptionHandler' => '1',
+            'exceptionHandler.' => array(
+                'errorMessage' => 'New message for testing',
+            )
+        );
+
+        $this->assertSame('New message for testing', $this->subject->render($contentObjectFixture, $configuration));
     }
 
     /**
-     * Check if stdWrap_bytes works properly.
-     *
-     * Show:
-     *
-     * - Delegates to GeneralUtility::formatSize
-     * - Parameter 1 is $conf['bytes.'][labels'].
-     * - Parameter 2 is $conf['bytes.'][base'].
-     * - Returns the return value.
-     *
-     * Note: As PHPUnit can't mock static methods, the call to
-     *       GeneralUtility::formatSize can't be easily intercepted. The test
-     *       is done by testing input/output pairs instead. To not duplicate
-     *       the testing of formatSize just a few smoke tests are done here.
-     *
      * @test
-     * @dataProvider stdWrap_bytesDataProvider
-     * @param string $expect The expected output.
-     * @param string $content The given input.
-     * @param array $conf The given configuration for 'bytes.'.
-     * @return void
      */
-    public function stdWrap_bytes($expect, $content, $conf)
+    public function specificExceptionsCanBeIgnoredByExceptionHandler()
     {
-        $locale = 'en_US.UTF-8';
-        if (!setlocale(LC_NUMERIC, $locale)) {
-            $this->markTestSkipped('Locale ' . $locale . ' is not available.');
-        }
-        $conf = ['bytes.' => $conf];
-        $this->assertSame($expect,
-            $this->subject->stdWrap_bytes($content, $conf));
+        $contentObjectFixture = $this->createContentObjectThrowingExceptionFixture();
+
+        $configuration = array(
+            'exceptionHandler' => '1',
+            'exceptionHandler.' => array(
+                'ignoreCodes.' => array('10.' => '1414513947'),
+            )
+        );
+        $this->expectException(\LogicException::class);
+        $this->expectExceptionCode(1414513947);
+        $this->subject->render($contentObjectFixture, $configuration);
     }
 
     /**
-     * Data provider for substring
-     *
-     * @return array [$expect, $content, $conf]
+     * @return \PHPUnit_Framework_MockObject_MockObject | AbstractContentObject
      */
-    public function substringDataProvider()
+    protected function createContentObjectThrowingExceptionFixture()
     {
-        return [
-            'sub -1'    => ['g', 'substring', '-1'],
-            'sub -1,0'  => ['g', 'substring', '-1,0'],
-            'sub -1,-1' => ['', 'substring', '-1,-1'],
-            'sub -1,1'  => ['g', 'substring', '-1,1'],
-            'sub 0'     => ['substring', 'substring', '0'],
-            'sub 0,0'   => ['substring', 'substring', '0,0'],
-            'sub 0,-1'  => ['substrin', 'substring', '0,-1'],
-            'sub 0,1'   => ['s', 'substring', '0,1'],
-            'sub 1'     => ['ubstring', 'substring', '1'],
-            'sub 1,0'   => ['ubstring', 'substring', '1,0'],
-            'sub 1,-1'  => ['ubstrin', 'substring', '1,-1'],
-            'sub 1,1'   => ['u', 'substring', '1,1'],
-            'sub'       => ['substring', 'substring', ''],
-        ];
+        $contentObjectFixture = $this->getMockBuilder(AbstractContentObject::class)
+            ->setConstructorArgs(array($this->subject))
+            ->getMock();
+        $contentObjectFixture->expects($this->once())
+            ->method('render')
+            ->willReturnCallback(function () {
+                throw new \LogicException('Exception during rendering', 1414513947);
+            });
+        return $contentObjectFixture;
     }
 
     /**
-     * Check if substring works properly.
-     *
      * @test
-     * @dataProvider substringDataProvider
-     * @param string $expect The expected output.
-     * @param string $content The given input.
-     * @param array $conf The given configutation.
-     * @return void
      */
-    public function substring($expect, $content, $conf)
+    public function forceAbsoluteUrlReturnsCorrectAbsoluteUrlWithSubfolder()
     {
-        $this->assertSame($expect, $this->subject->substring($content, $conf));
+        // Force hostname and subfolder
+        $this->subject->expects($this->any())->method('getEnvironmentVariable')->will($this->returnValueMap(
+            array(
+                array('HTTP_HOST', 'localhost'),
+                array('TYPO3_SITE_PATH', '/subfolder/'),
+            )
+        ));
+
+        $expected = 'http://localhost/subfolder/fileadmin/my.pdf';
+        $url = 'fileadmin/my.pdf';
+        $configuration = array(
+            'forceAbsoluteUrl' => '1'
+        );
+
+        $this->assertEquals($expected, $this->subject->_call('forceAbsoluteUrl', $url, $configuration));
     }
 
     /**
-     * Check if stdWrap_substring works properly.
-     *
-     * Show:
-     *
-     * - Delegates to method substring.
-     * - Parameter 1 is $content.
-     * - Parameter 2 is $conf['substring'].
-     * - Returns the return value.
-     *
-     * @test
-     * @return void
+     * @return array
      */
-    public function stdWrap_substring()
+    protected function getLibParseTarget()
     {
-        $content = $this->getUniqueId('content');
-        $conf = [
-            'substring' => $this->getUniqueId('substring'),
-            'substring.' => $this->getUniqueId('not used'),
-        ];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['substring'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('substring')
-            ->with($content, $conf['substring'])
-            ->willReturn($return);
-        $this->assertSame($return,
-            $subject->stdWrap_substring($content, $conf));
+        return array(
+            'override' => '',
+            'override.' => array(
+                'if.' => array(
+                    'isTrue.' => array(
+                        'data' => 'TSFE:dtdAllowsFrames',
+                    ),
+                ),
+            ),
+        );
     }
 
     /**
-     * Data provider for stdWrap_stdWrapValue test
-     *
      * @return array
      */
-    public function stdWrap_stdWrapValueDataProvider()
+    protected function getLibParseFunc()
     {
         return array(
-            'only key returns value' => array(
-                'ifNull',
-                array(
-                    'ifNull' => '1',
-                ),
-                '',
-                '1',
-            ),
-            'array without key returns empty string' => array(
-                'ifNull',
-                array(
-                    'ifNull.' => '1',
-                ),
-                '',
-                '',
-            ),
-            'array without key returns default' => array(
-                'ifNull',
-                array(
-                    'ifNull.' => '1',
+            'makelinks' => '1',
+            'makelinks.' => array(
+                'http.' => array(
+                    'keep' => '{$styles.content.links.keep}',
+                    'extTarget' => '',
+                    'extTarget.' => $this->getLibParseTarget(),
+                    'mailto.' => array(
+                        'keep' => 'path',
+                    ),
                 ),
-                'default',
-                'default',
             ),
-            'non existing key returns default' => array(
-                'ifNull',
-                array(
-                    'noTrimWrap' => 'test',
-                    'noTrimWrap.' => '1',
+            'tags' => array(
+                'link' => 'TEXT',
+                'link.' => array(
+                    'current' => '1',
+                    'typolink.' => array(
+                        'parameter.' => array(
+                            'data' => 'parameters : allParams',
+                        ),
+                        'extTarget.' => $this->getLibParseTarget(),
+                        'target.' => $this->getLibParseTarget(),
+                    ),
+                    'parseFunc.' => array(
+                        'constants' => '1',
+                    ),
                 ),
-                'default',
-                'default',
             ),
-            'existing key and array returns stdWrap' => array(
-                'test',
-                array(
-                    'test' => 'value',
-                    'test.' => array('case' => 'upper'),
+
+            'allowTags' => 'a, abbr, acronym, address, article, aside, b, bdo, big, blockquote, br, caption, center, cite, code, col, colgroup, dd, del, dfn, dl, div, dt, em, font, footer, header, h1, h2, h3, h4, h5, h6, hr, i, img, ins, kbd, label, li, link, meta, nav, ol, p, pre, q, samp, sdfield, section, small, span, strike, strong, style, sub, sup, table, thead, tbody, tfoot, td, th, tr, title, tt, u, ul, var',
+            'denyTags' => '*',
+            'sword' => '<span class="csc-sword">|</span>',
+            'constants' => '1',
+            'nonTypoTagStdWrap.' => array(
+                'HTMLparser' => '1',
+                'HTMLparser.' => array(
+                    'keepNonMatchedTags' => '1',
+                    'htmlSpecialChars' => '2',
                 ),
-                'default',
-                'VALUE'
             ),
         );
     }
 
     /**
-     * @param string $key
-     * @param array $configuration
-     * @param string $defaultValue
-     * @param string $expected
-     * @dataProvider stdWrap_stdWrapValueDataProvider
-     * @test
+     * @return array
      */
-    public function stdWrap_stdWrapValue($key, array $configuration, $defaultValue, $expected)
+    protected function getLibParseFunc_RTE()
     {
-        $result = $this->subject->stdWrapValue($key, $configuration, $defaultValue);
-        $this->assertEquals($expected, $result);
+        return array(
+            'parseFunc' => '',
+            'parseFunc.' => array(
+                'allowTags' => 'a, abbr, acronym, address, article, aside, b, bdo, big, blockquote, br, caption, center, cite, code, col, colgroup, dd, del, dfn, dl, div, dt, em, font, footer, header, h1, h2, h3, h4, h5, h6, hr, i, img, ins, kbd, label, li, link, meta, nav, ol, p, pre, q, samp, sdfield, section, small, span, strike, strong, style, sub, sup, table, thead, tbody, tfoot, td, th, tr, title, tt, u, ul, var',
+                'constants' => '1',
+                'denyTags' => '*',
+                'externalBlocks' => 'article, aside, blockquote, div, dd, dl, footer, header, nav, ol, section, table, ul',
+                'externalBlocks.' => array(
+                    'article.' => array(
+                        'callRecursive' => '1',
+                        'stripNL' => '1',
+                    ),
+                    'aside.' => array(
+                        'callRecursive' => '1',
+                        'stripNL' => '1',
+                    ),
+                    'blockquote.' => array(
+                        'callRecursive' => '1',
+                        'stripNL' => '1',
+                    ),
+                    'dd.' => array(
+                        'callRecursive' => '1',
+                        'stripNL' => '1',
+                    ),
+                    'div.' => array(
+                        'callRecursive' => '1',
+                        'stripNL' => '1',
+                    ),
+                    'dl.' => array(
+                        'callRecursive' => '1',
+                        'stripNL' => '1',
+                    ),
+                    'footer.' => array(
+                        'callRecursive' => '1',
+                        'stripNL' => '1',
+                    ),
+                    'header.' => array(
+                        'callRecursive' => '1',
+                        'stripNL' => '1',
+                    ),
+                    'nav.' => array(
+                        'callRecursive' => '1',
+                        'stripNL' => '1',
+                    ),
+                    'ol.' => array(
+                        'callRecursive' => '1',
+                        'stripNL' => '1',
+                    ),
+                    'section.' => array(
+                        'callRecursive' => '1',
+                        'stripNL' => '1',
+                    ),
+                    'table.' => array(
+                        'HTMLtableCells' => '1',
+                        'HTMLtableCells.' => array(
+                            'addChr10BetweenParagraphs' => '1',
+                            'default.' => array(
+                                'stdWrap.' => array(
+                                    'parseFunc' => '=< lib.parseFunc_RTE',
+                                    'parseFunc.' => array(
+                                        'nonTypoTagStdWrap.' => array(
+                                            'encapsLines.' => array(
+                                                'nonWrappedTag' => '',
+                                            ),
+                                        ),
+                                    ),
+                                ),
+                            ),
+                        ),
+                        'stdWrap.' => array(
+                            'HTMLparser' => '1',
+                            'HTMLparser.' => array(
+                                'keepNonMatchedTags' => '1',
+                                'tags.' => array(
+                                    'table.' => array(
+                                        'fixAttrib.' => array(
+                                            'class.' => array(
+                                                'always' => '1',
+                                                'default' => 'contenttable',
+                                                'list' => 'contenttable',
+                                            ),
+                                        ),
+                                    ),
+                                ),
+                            ),
+                        ),
+                        'stripNL' => '1',
+                    ),
+                    'ul.' => array(
+                        'callRecursive' => '1',
+                        'stripNL' => '1',
+                    ),
+                ),
+                'makelinks' => '1',
+                'makelinks.' => array(
+                    'http.' => array(
+                        'extTarget.' =>  array(
+                            'override' => '_blank',
+                            'override.' => array(
+                                'if.' => array(
+                                    'isTrue.' => array(
+                                        'data' => 'TSFE:dtdAllowsFrames',
+                                    ),
+                                ),
+                            ),
+                        ),
+                        'keep' => 'path',
+                    ),
+                ),
+                'nonTypoTagStdWrap.' => array(
+                    'encapsLines.' => array(
+                        'addAttributes.' => array(
+                            'P.' => array(
+                                'class' => 'bodytext',
+                                'class.' => array(
+                                    'setOnly' => 'blank',
+                                ),
+                            ),
+                        ),
+                        'encapsTagList' => 'p,pre,h1,h2,h3,h4,h5,h6,hr,dt,li',
+                        'innerStdWrap_all.' => array(
+                            'ifBlank' => '&nbsp;',
+                        ),
+                        'nonWrappedTag' => 'P',
+                        'remapTag.' => array(
+                            'DIV' => 'P',
+                        ),
+                    ),
+                    'HTMLparser' => '1',
+                    'HTMLparser.' => array(
+                        'htmlSpecialChars' => '2',
+                        'keepNonMatchedTags' => '1',
+                    ),
+                ),
+                'sword' => '<span class="csc-sword">|</span>',
+                'tags.' => array(
+                    'link' => 'TEXT',
+                    'link.' => array(
+                        'current' => '1',
+                        'parseFunc.' => array(
+                            'constants' => '1',
+                        ),
+                        'typolink.' => array(
+                            'extTarget.' =>  array(
+                                'override' => '',
+                                'override.' => array(
+                                    'if.' => array(
+                                        'isTrue.' => array(
+                                            'data' => 'TSFE:dtdAllowsFrames',
+                                        ),
+                                    ),
+                                ),
+                            ),
+                            'parameter.' => array(
+                                'data' => 'parameters : allParams',
+                            ),
+                            'target.' =>  array(
+                                'override' => '',
+                                'override.' => array(
+                                    'if.' => array(
+                                        'isTrue.' => array(
+                                            'data' => 'TSFE:dtdAllowsFrames',
+                                        ),
+                                    ),
+                                ),
+                            ),
+                        ),
+                    ),
+                ),
+            ),
+        );
     }
 
     /**
-     * Data provider for stdWrap_ifNull.
-     *
-     * @return array [$expect, $content, $conf]
+     * @return array
      */
-    public function stdWrap_ifNullDataProvider()
+    public function _parseFuncReturnsCorrectHtmlDataProvider()
     {
-        $alt = $this->getUniqueId('alternative content');
-        $conf = ['ifNull' => $alt];
-        return [
-            'only null is null' => [$alt, null, $conf],
-            'zero is not null' => [0, 0, $conf],
-            'float zero is not null' => [0.0, 0.0, $conf],
-            'false is not null' => [false, false, $conf],
-            'zero is not null' => [0, 0, $conf],
-            'zero string is not null' => ['0', '0', $conf],
-            'empty string is not null' => ['', '', $conf],
-            'whitespace is not null' => [TAB . '', TAB . '', $conf],
-        ];
+        return array(
+            'Text without tag is wrapped with <p> tag' => array(
+                'Text without tag',
+                $this->getLibParseFunc_RTE(),
+                '<p class="bodytext">Text without tag</p>',
+            ),
+            'Text wrapped with <p> tag remains the same' => array(
+                '<p class="myclass">Text with &lt;p&gt; tag</p>',
+                $this->getLibParseFunc_RTE(),
+                '<p class="myclass">Text with &lt;p&gt; tag</p>',
+            ),
+            'Text with absolute external link' => array(
+                'Text with <link http://example.com/foo/>external link</link>',
+                $this->getLibParseFunc_RTE(),
+                '<p class="bodytext">Text with <a href="http://example.com/foo/">external link</a></p>',
+            ),
+        );
     }
 
     /**
-     * Check that stdWrap_ifNull works properly.
-     *
-     * Show:
-     *
-     * - Returns the content, if not null.
-     * - Otherwise returns $conf['ifNull'].
-     * - Null is strictly checked by identiy with null.
-     *
      * @test
-     * @dataProvider stdWrap_ifNullDataProvider
-     * @param mixed $expected The expected output.
-     * @param mixed $content The given input.
-     * @param array $conf The given configuration.
-     * @return void
+     * @dataProvider _parseFuncReturnsCorrectHtmlDataProvider
+     * @param string $value
+     * @param array $configuration
+     * @param string $expectedResult
      */
-    public function stdWrap_ifNull($expect, $content, $conf)
+    public function stdWrap_parseFuncReturnsParsedHtml($value, $configuration, $expectedResult)
     {
-        $result = $this->subject->stdWrap_ifNull($content, $conf);
-        $this->assertSame($expect, $result);
+        $this->assertEquals($expectedResult, $this->subject->stdWrap_parseFunc($value, $configuration));
     }
 
     /**
-     * Data provider for stdWrap_ifEmpty.
-     *
-     * @return array [$expect, $content, $conf]
+     * @return array
      */
-    public function stdWrap_ifEmptyDataProvider()
+    public function detectLinkTypeFromLinkParameterDataProvider()
     {
-        $alt = $this->getUniqueId('alternative content');
-        $conf = ['ifEmpty' => $alt];
         return [
-            // empty cases
-            'null is empty' => [$alt, null, $conf ],
-            'false is empty' => [$alt, false, $conf ],
-            'zero is empty' => [$alt, 0, $conf ],
-            'float zero is empty' => [$alt, 0.0, $conf ],
-            'whitespace is empty' => [$alt, TAB . ' ', $conf ],
-            'empty string is empty' => [$alt, '', $conf ],
-            'zero string is empty' => [$alt, '0', $conf ],
-            'zero string is empty with whitespace' => [
-                $alt, TAB . ' 0 ' . TAB, $conf
+            'Domain only' => [
+                'example.com',
+                'url'
             ],
-            // non-empty cases
-            'string is not empty' => ['string', 'string', $conf ],
-            '1 is not empty' => [1, 1, $conf ],
-            '-1 is not empty' => [-1, -1, $conf ],
-            '0.1 is not empty' => [0.1, 0.1, $conf ],
-            '-0.1 is not empty' => [-0.1, -0.1, $conf ],
-            'true is not empty' => [true, true, $conf ],
-        ];
-    }
-
-    /**
-     * Check that stdWrap_ifEmpty works properly.
-     *
-     * Show:
-     *
-     * - Returns the content, if not empty.
-     * - Otherwise returns $conf['ifEmpty'].
-     * - Empty is checked by cast to boolean after trimming.
-     *
-     * @test
-     * @dataProvider stdWrap_ifEmptyDataProvider
-     * @param mixed $expect The expected output.
-     * @param mixed $content The given content.
-     * @param array $conf The given configuration.
-     * @return void
-     */
-    public function stdWrap_ifEmpty($expect, $content, $conf)
-    {
-        $result = $this->subject->stdWrap_ifEmpty($content, $conf);
-        $this->assertSame($expect, $result);
-    }
-
-    /**
-     * Data provider for stdWrap_ifBlank.
-     *
-     * @return array [$expect, $content, $conf]
-     */
-    public function stdWrap_ifBlankDataProvider()
-    {
-        $alt = $this->getUniqueId('alternative content');
-        $conf = ['ifBlank' => $alt];
-        return [
-            // blank cases
-            'null is blank' => [$alt, null, $conf],
-            'false is blank' => [$alt, false, $conf],
-            'empty string is blank' => [$alt, '', $conf],
-            'whitespace is blank' => [$alt, TAB . '', $conf],
-            // non-blank cases
-            'string is not blank' => ['string', 'string', $conf],
-            'zero is not blank' => [0, 0, $conf],
-            'zero string is not blank' => ['0', '0', $conf],
-            'zero float is not blank' => [0.0, 0.0, $conf],
-            'true is not blank' => [true, true, $conf],
-        ];
-    }
-
-    /**
-     * Check that stdWrap_ifBlank works properly.
-     *
-     * Show:
-     *
-     * - The content is returned if not blank.
-     * - Otherwise $conf['ifBlank'] is returned.
-     * - The check for blank is done by comparing the trimmed content
-     *   with the empty string for equality.
-     *
-     * @test
-     * @dataProvider stdWrap_ifBlankDataProvider
-     * @param mixed $expected The expected output.
-     * @param mixed $content The given input.
-     * @param array $conf The given configuration.
-     * @return void
-     */
-    public function stdWrap_ifBlank($expect, $content, $conf)
-    {
-        $result = $this->subject->stdWrap_ifBlank($content, $conf);
-        $this->assertSame($expect, $result);
-    }
-
-    /**
-     * Data provider for stdWrap_noTrimWrap.
-     *
-     * @return array [$expect, $content, $conf]
-     */
-    public function stdWrap_noTrimWrapDataProvider()
-    {
-        return [
-            'Standard case' => [
-                ' left middle right ',
-                'middle',
-                [
-                    'noTrimWrap' => '| left | right |',
-                ],
-            ],
-            'Tabs as whitespace' => [
-                TAB . 'left' . TAB . 'middle' . TAB . 'right' . TAB,
-                'middle',
-                [
-                    'noTrimWrap' =>
-                    '|' . TAB . 'left' . TAB . '|' . TAB . 'right' . TAB . '|',
-                ],
-            ],
-            'Split char is 0' => [
-                ' left middle right ',
-                'middle',
-                [
-                    'noTrimWrap' => '0 left 0 right 0',
-                    'noTrimWrap.' => ['splitChar' => '0'],
-                ],
-            ],
-            'Split char is pipe (default)' => [
-                ' left middle right ',
-                'middle',
-                [
-                    'noTrimWrap' => '| left | right |',
-                    'noTrimWrap.' => ['splitChar' => '|'],
-                ],
+            'URL without a file' => [
+                'http://example.com',
+                'url'
             ],
-            'Split char is a' => [
-                ' left middle right ',
-                'middle',
-                [
-                    'noTrimWrap' => 'a left a right a',
-                    'noTrimWrap.' => ['splitChar' => 'a'],
-                ],
+            'URL with schema and a file' => [
+                'http://example.com/index.php',
+                'url'
             ],
-            'Split char is a word (ab)' => [
-                ' left middle right ',
-                'middle',
-                [
-                    'noTrimWrap' => 'ab left ab right ab',
-                    'noTrimWrap.' => ['splitChar' => 'ab'],
-                ],
+            'URL with a file but without a schema' => [
+                'example.com/index.php',
+                'url'
             ],
-            'Split char accepts stdWrap' => [
-                ' left middle right ',
-                'middle',
-                [
-                    'noTrimWrap' => 'abc left abc right abc',
-                    'noTrimWrap.' => [
-                        'splitChar' => 'b',
-                        'splitChar.' => ['wrap' => 'a|c'],
-                    ],
-                ],
+            'file' => [
+                '/index.php',
+                'file'
             ],
         ];
     }
 
     /**
-     * Check if stdWrap_noTrimWrap works properly.
-     *
      * @test
-     * @dataProvider stdWrap_noTrimWrapDataProvider
-     * @param string $expect The expected output.
-     * @param string $content The given input.
-     * @param array $conf The given configuration.
-     * @return void
+     * @param string $linkParameter
+     * @param string $expectedResult
+     * @dataProvider detectLinkTypeFromLinkParameterDataProvider
      */
-    public function stdWrap_noTrimWrap($expect, $content, $conf)
+    public function detectLinkTypeFromLinkParameter($linkParameter, $expectedResult)
     {
-        $this->assertSame($expect,
-            $this->subject->stdWrap_noTrimWrap($content, $conf));
-    }
+        /** @var TemplateService|\PHPUnit_Framework_MockObject_MockObject $templateServiceObjectMock */
+        $templateServiceObjectMock = $this->getMockBuilder(TemplateService::class)
+            ->setMethods(array('dummy'))
+            ->getMock();
+        $templateServiceObjectMock->setup = array(
+            'lib.' => array(
+                'parseFunc.' => $this->getLibParseFunc(),
+            ),
+        );
+        /** @var TypoScriptFrontendController|\PHPUnit_Framework_MockObject_MockObject $typoScriptFrontendControllerMockObject */
+        $typoScriptFrontendControllerMockObject = $this->createMock(TypoScriptFrontendController::class);
+        $typoScriptFrontendControllerMockObject->config = array(
+            'config' => array(),
+            'mainScript' => 'index.php',
+        );
+        $typoScriptFrontendControllerMockObject->tmpl = $templateServiceObjectMock;
+        $GLOBALS['TSFE'] = $typoScriptFrontendControllerMockObject;
+        $this->subject->_set('typoScriptFrontendController', $typoScriptFrontendControllerMockObject);
 
-    /**
-     * @param array $expectedTags
-     * @param array $configuration
-     * @test
-     * @dataProvider stdWrap_addPageCacheTagsAddsPageTagsDataProvider
-     */
-    public function stdWrap_addPageCacheTagsAddsPageTags(array $expectedTags, array $configuration)
-    {
-        $this->subject->stdWrap_addPageCacheTags('', $configuration);
-        $this->assertEquals($expectedTags, $this->frontendControllerMock->_get('pageCacheTags'));
+        $this->assertEquals($expectedResult, $this->subject->_call('detectLinkTypeFromLinkParameter', $linkParameter));
     }
 
     /**
      * @return array
      */
-    public function stdWrap_addPageCacheTagsAddsPageTagsDataProvider()
+    public function typolinkReturnsCorrectLinksForEmailsAndUrlsDataProvider()
     {
         return array(
-            'No Tag' => array(
-                array(),
-                array('addPageCacheTags' => ''),
+            'Link to url' => array(
+                'TYPO3',
+                array(
+                    'parameter' => 'http://typo3.org',
+                ),
+                '<a href="http://typo3.org">TYPO3</a>',
             ),
-            'Two expectedTags' => array(
-                array('tag1', 'tag2'),
-                array('addPageCacheTags' => 'tag1,tag2'),
+            'Link to url without schema' => array(
+                'TYPO3',
+                array(
+                    'parameter' => 'typo3.org',
+                ),
+                '<a href="http://typo3.org">TYPO3</a>',
             ),
-            'Two expectedTags plus one with stdWrap' => array(
-                array('tag1', 'tag2', 'tag3'),
+            'Link to url without link text' => array(
+                '',
                 array(
-                    'addPageCacheTags' => 'tag1,tag2',
-                    'addPageCacheTags.' => array('wrap' => '|,tag3')
+                    'parameter' => 'http://typo3.org',
                 ),
+                '<a href="http://typo3.org">http://typo3.org</a>',
             ),
-        );
-    }
-
-    /**
-     * Data provider for stdWrap_htmlSpecialChars
-     *
-     * @return array Order: expected, input, conf
-     */
-    public function stdWrap_htmlSpecialCharsDataProvider()
-    {
-        return [
-            'void conf' => [
-                '&lt;span&gt;1 &amp;lt; 2&lt;/span&gt;',
-                '<span>1 &lt; 2</span>',
-                [],
-            ],
-            'void preserveEntities' => [
-                '&lt;span&gt;1 &amp;lt; 2&lt;/span&gt;',
-                '<span>1 &lt; 2</span>',
-                ['htmlSpecialChars.' => []],
-            ],
-            'false preserveEntities' => [
-                '&lt;span&gt;1 &amp;lt; 2&lt;/span&gt;',
-                '<span>1 &lt; 2</span>',
-                ['htmlSpecialChars.' => ['preserveEntities' => 0]],
-            ],
-            'true preserveEntities' => [
-                '&lt;span&gt;1 &lt; 2&lt;/span&gt;',
-                '<span>1 &lt; 2</span>',
-                ['htmlSpecialChars.' => ['preserveEntities' => 1]],
-            ],
-        ];
-    }
+            'Link to url with attributes' => array(
+                'TYPO3',
+                array(
+                    'parameter' => 'http://typo3.org',
+                    'ATagParams' => 'class="url-class"',
+                    'extTarget' => '_blank',
+                    'title' => 'Open new window',
+                ),
+                '<a href="http://typo3.org" title="Open new window" target="_blank" class="url-class">TYPO3</a>',
+            ),
+            'Link to url with attributes in parameter' => array(
+                'TYPO3',
+                array(
+                    'parameter' => 'http://typo3.org _blank url-class "Open new window"',
+                ),
+                '<a href="http://typo3.org" title="Open new window" target="_blank" class="url-class">TYPO3</a>',
+            ),
+            'Link to url with script tag' => array(
+                '',
+                array(
+                    'parameter' => 'http://typo3.org<script>alert(123)</script>',
+                ),
+                '<a href="http://typo3.org&lt;script&gt;alert(123)&lt;/script&gt;">http://typo3.org&lt;script&gt;alert(123)&lt;/script&gt;</a>',
+            ),
+            'Link to email address' => array(
+                'Email address',
+                array(
+                    'parameter' => 'foo@bar.org',
+                ),
+                '<a href="mailto:foo@bar.org">Email address</a>',
+            ),
+            'Link to email address without link text' => array(
+                '',
+                array(
+                    'parameter' => 'foo@bar.org',
+                ),
+                '<a href="mailto:foo@bar.org">foo@bar.org</a>',
+            ),
+            'Link to email with attributes' => array(
+                'Email address',
+                array(
+                    'parameter' => 'foo@bar.org',
+                    'ATagParams' => 'class="email-class"',
+                    'title' => 'Write an email',
+                ),
+                '<a href="mailto:foo@bar.org" title="Write an email" class="email-class">Email address</a>',
+            ),
+            'Link to email with attributes in parameter' => array(
+                'Email address',
+                array(
+                    'parameter' => 'foo@bar.org - email-class "Write an email"',
+                ),
+                '<a href="mailto:foo@bar.org" title="Write an email" class="email-class">Email address</a>',
+            ),
+        );
+    }
 
     /**
-     * Check if stdWrap_htmlSpecialChars works properly
-     *
      * @test
-     * @dataProvider stdWrap_htmlSpecialCharsDataProvider
-     * @param string $expected The expected value.
-     * @param string $input The input value.
-     * @param array $conf htmlSpecialChars.preserveEntities
-     * @return void
+     * @param string $linkText
+     * @param array $configuration
+     * @param string $expectedResult
+     * @dataProvider typolinkReturnsCorrectLinksForEmailsAndUrlsDataProvider
      */
-    public function stdWrap_htmlSpecialChars($expected, $input, $conf)
+    public function typolinkReturnsCorrectLinksForEmailsAndUrls($linkText, $configuration, $expectedResult)
     {
-        $this->assertSame($expected,
-            $this->subject->stdWrap_htmlSpecialChars($input, $conf));
+        $templateServiceObjectMock = $this->getMockBuilder(TemplateService::class)
+            ->setMethods(array('dummy'))
+            ->getMock();
+        $templateServiceObjectMock->setup = array(
+            'lib.' => array(
+                'parseFunc.' => $this->getLibParseFunc(),
+            ),
+        );
+        $typoScriptFrontendControllerMockObject = $this->createMock(TypoScriptFrontendController::class);
+        $typoScriptFrontendControllerMockObject->config = array(
+            'config' => array(),
+            'mainScript' => 'index.php',
+        );
+        $typoScriptFrontendControllerMockObject->tmpl = $templateServiceObjectMock;
+        $GLOBALS['TSFE'] = $typoScriptFrontendControllerMockObject;
+        $this->subject->_set('typoScriptFrontendController', $typoScriptFrontendControllerMockObject);
+
+        $this->assertEquals($expectedResult, $this->subject->typoLink($linkText, $configuration));
     }
 
     /**
-     * Data provider for stdWrap_encodeForJavaScriptValue.
-     *
-     * @return array []
+     * @return array
      */
-    public function stdWrap_encodeForJavaScriptValueDataProvider()
+    public function typolinkReturnsCorrectLinksForPagesDataProvider()
     {
-        return [
-            'double quote in string' => [
-                '\'double\u0020quote\u0022\'', 'double quote"'
-            ],
-            'backslash in string' => [
-                '\'backslash\u0020\u005C\'', 'backslash \\'
-            ],
-            'exclamation mark' => [
-                '\'exclamation\u0021\'', 'exclamation!'
-            ],
-            'whitespace tab, newline and carriage return' => [
-                '\'white\u0009space\u000As\u000D\'', "white\tspace\ns\r"
-            ],
-            'single quote in string' => [
-                '\'single\u0020quote\u0020\u0027\'', 'single quote \''
-            ],
-            'tag' => [
-                '\'\u003Ctag\u003E\'', '<tag>'
-            ],
-            'ampersand in string' => [
-                '\'amper\u0026sand\'', 'amper&sand'
-            ]
-        ];
+        return array(
+            'Link to page' => array(
+                'My page',
+                array(
+                    'parameter' => 42,
+                ),
+                array(
+                    'uid' => 42,
+                    'title' => 'Page title',
+                ),
+                '<a href="index.php?id=42">My page</a>',
+            ),
+            'Link to page without link text' => array(
+                '',
+                array(
+                    'parameter' => 42,
+                ),
+                array(
+                    'uid' => 42,
+                    'title' => 'Page title',
+                ),
+                '<a href="index.php?id=42">Page title</a>',
+            ),
+            'Link to page with attributes' => array(
+                'My page',
+                array(
+                    'parameter' => '42',
+                    'ATagParams' => 'class="page-class"',
+                    'target' => '_self',
+                    'title' => 'Link to internal page',
+                ),
+                array(
+                    'uid' => 42,
+                    'title' => 'Page title',
+                ),
+                '<a href="index.php?id=42" title="Link to internal page" target="_self" class="page-class">My page</a>',
+            ),
+            'Link to page with attributes in parameter' => array(
+                'My page',
+                array(
+                    'parameter' => '42 _self page-class "Link to internal page"',
+                ),
+                array(
+                    'uid' => 42,
+                    'title' => 'Page title',
+                ),
+                '<a href="index.php?id=42" title="Link to internal page" target="_self" class="page-class">My page</a>',
+            ),
+            'Link to page with bold tag in title' => array(
+                '',
+                array(
+                    'parameter' => 42,
+                ),
+                array(
+                    'uid' => 42,
+                    'title' => 'Page <b>title</b>',
+                ),
+                '<a href="index.php?id=42">Page <b>title</b></a>',
+            ),
+            'Link to page with script tag in title' => array(
+                '',
+                array(
+                    'parameter' => 42,
+                ),
+                array(
+                    'uid' => 42,
+                    'title' => '<script>alert(123)</script>Page title',
+                ),
+                '<a href="index.php?id=42">&lt;script&gt;alert(123)&lt;/script&gt;Page title</a>',
+            ),
+        );
     }
 
     /**
-     * Check if encodeForJavaScriptValue works properly.
-     *
+     * @param array $settings
+     * @param string $linkText
+     * @param string $mailAddress
+     * @param string $expected
+     * @dataProvider typoLinkEncodesMailAddressForSpamProtectionDataProvider
      * @test
-     * @dataProvider stdWrap_encodeForJavaScriptValueDataProvider
-     * @param string $expect The expected output.
-     * @param string $content The given input.
-     * @return void
      */
-    public function stdWrap_encodeForJavaScriptValue($expect, $content)
+    public function typoLinkEncodesMailAddressForSpamProtection(array $settings, $linkText, $mailAddress, $expected)
     {
-        $this->assertSame($expect,
-            $this->subject->stdWrap_encodeForJavaScriptValue($content));
+        $this->getFrontendController()->spamProtectEmailAddresses = $settings['spamProtectEmailAddresses'];
+        $this->getFrontendController()->config['config'] = $settings;
+        $typoScript = array('parameter' => $mailAddress);
+
+        $this->assertEquals($expected, $this->subject->typoLink($linkText, $typoScript));
     }
 
     /**
-     * Data provider for stdWrap_doubleBrTag
-     *
-     * @return array Order expected, input, config
+     * @return array
      */
-    public function stdWrapDoubleBrTagDataProvider()
+    public function typoLinkEncodesMailAddressForSpamProtectionDataProvider()
     {
-        return [
-            'no config: void input' => [
-                '',
-                '',
-                [],
-            ],
-            'no config: single break' => [
-                'one' . LF . 'two',
-                'one' . LF . 'two',
-                [],
-            ],
-            'no config: double break' => [
-                'onetwo',
-                'one' . LF . LF . 'two',
-                [],
-            ],
-            'no config: double break with whitespace' => [
-                'onetwo',
-                'one' . LF . TAB . ' ' . TAB . ' ' . LF . 'two',
-                [],
-            ],
-            'no config: single break around' => [
-                LF . 'one' . LF,
-                LF . 'one' . LF,
-                [],
-            ],
-            'no config: double break around' => [
-                'one',
-                LF . LF . 'one' . LF . LF,
-                [],
-            ],
-            'empty string: double break around' => [
-                'one',
-                LF . LF . 'one' . LF . LF,
-                ['doubleBrTag' => ''],
-            ],
-            'br tag: double break' => [
-                'one<br/>two',
-                'one' . LF . LF . 'two',
-                ['doubleBrTag' => '<br/>'],
-            ],
-            'br tag: double break around' => [
-                '<br/>one<br/>',
-                LF . LF . 'one' . LF . LF,
-                ['doubleBrTag' => '<br/>'],
-            ],
-            'double br tag: double break around' => [
-                '<br/><br/>one<br/><br/>',
-                LF . LF . 'one' . LF . LF,
-                ['doubleBrTag' => '<br/><br/>'],
-            ],
-        ];
+        return array(
+            'plain mail without mailto scheme' => array(
+                array(
+                    'spamProtectEmailAddresses' => '',
+                    'spamProtectEmailAddresses_atSubst' => '',
+                    'spamProtectEmailAddresses_lastDotSubst' => '',
+                ),
+                'some.body@test.typo3.org',
+                'some.body@test.typo3.org',
+                '<a href="mailto:some.body@test.typo3.org">some.body@test.typo3.org</a>',
+            ),
+            'plain mail with mailto scheme' => array(
+                array(
+                    'spamProtectEmailAddresses' => '',
+                    'spamProtectEmailAddresses_atSubst' => '',
+                    'spamProtectEmailAddresses_lastDotSubst' => '',
+                ),
+                'some.body@test.typo3.org',
+                'mailto:some.body@test.typo3.org',
+                '<a href="mailto:some.body@test.typo3.org">some.body@test.typo3.org</a>',
+            ),
+            'plain with at and dot substitution' => array(
+                array(
+                    'spamProtectEmailAddresses' => '0',
+                    'spamProtectEmailAddresses_atSubst' => '(at)',
+                    'spamProtectEmailAddresses_lastDotSubst' => '(dot)',
+                ),
+                'some.body@test.typo3.org',
+                'mailto:some.body@test.typo3.org',
+                '<a href="mailto:some.body@test.typo3.org">some.body@test.typo3.org</a>',
+            ),
+            'mono-alphabetic substitution offset +1' => array(
+                array(
+                    'spamProtectEmailAddresses' => '1',
+                    'spamProtectEmailAddresses_atSubst' => '',
+                    'spamProtectEmailAddresses_lastDotSubst' => '',
+                ),
+                'some.body@test.typo3.org',
+                'mailto:some.body@test.typo3.org',
+                '<a href="javascript:linkTo_UnCryptMailto(\'nbjmup+tpnf\/cpezAuftu\/uzqp4\/psh\');">some.body(at)test.typo3.org</a>',
+            ),
+            'mono-alphabetic substitution offset +1 with at substitution' => array(
+                array(
+                    'spamProtectEmailAddresses' => '1',
+                    'spamProtectEmailAddresses_atSubst' => '@',
+                    'spamProtectEmailAddresses_lastDotSubst' => '',
+                ),
+                'some.body@test.typo3.org',
+                'mailto:some.body@test.typo3.org',
+                '<a href="javascript:linkTo_UnCryptMailto(\'nbjmup+tpnf\/cpezAuftu\/uzqp4\/psh\');">some.body@test.typo3.org</a>',
+            ),
+            'mono-alphabetic substitution offset +1 with at and dot substitution' => array(
+                array(
+                    'spamProtectEmailAddresses' => '1',
+                    'spamProtectEmailAddresses_atSubst' => '(at)',
+                    'spamProtectEmailAddresses_lastDotSubst' => '(dot)',
+                ),
+                'some.body@test.typo3.org',
+                'mailto:some.body@test.typo3.org',
+                '<a href="javascript:linkTo_UnCryptMailto(\'nbjmup+tpnf\/cpezAuftu\/uzqp4\/psh\');">some.body(at)test.typo3(dot)org</a>',
+            ),
+            'mono-alphabetic substitution offset -1 with at and dot substitution' => array(
+                array(
+                    'spamProtectEmailAddresses' => '-1',
+                    'spamProtectEmailAddresses_atSubst' => '(at)',
+                    'spamProtectEmailAddresses_lastDotSubst' => '(dot)',
+                ),
+                'some.body@test.typo3.org',
+                'mailto:some.body@test.typo3.org',
+                '<a href="javascript:linkTo_UnCryptMailto(\'lzhksn9rnld-ancxZsdrs-sxon2-nqf\');">some.body(at)test.typo3(dot)org</a>',
+            ),
+            'entity substitution with at and dot substitution' => array(
+                array(
+                    'spamProtectEmailAddresses' => 'ascii',
+                    'spamProtectEmailAddresses_atSubst' => '',
+                    'spamProtectEmailAddresses_lastDotSubst' => '',
+                ),
+                'some.body@test.typo3.org',
+                'mailto:some.body@test.typo3.org',
+                '<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#115;&#111;&#109;&#101;&#46;&#98;&#111;&#100;&#121;&#64;&#116;&#101;&#115;&#116;&#46;&#116;&#121;&#112;&#111;&#51;&#46;&#111;&#114;&#103;">some.body(at)test.typo3.org</a>',
+            ),
+            'entity substitution with at and dot substitution with at and dot substitution' => array(
+                array(
+                    'spamProtectEmailAddresses' => 'ascii',
+                    'spamProtectEmailAddresses_atSubst' => '(at)',
+                    'spamProtectEmailAddresses_lastDotSubst' => '(dot)',
+                ),
+                'some.body@test.typo3.org',
+                'mailto:some.body@test.typo3.org',
+                '<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#115;&#111;&#109;&#101;&#46;&#98;&#111;&#100;&#121;&#64;&#116;&#101;&#115;&#116;&#46;&#116;&#121;&#112;&#111;&#51;&#46;&#111;&#114;&#103;">some.body(at)test.typo3(dot)org</a>',
+            ),
+        );
     }
 
     /**
-     * Check if doubleBrTag works properly
-     *
      * @test
-     * @dataProvider stdWrapDoubleBrTagDataProvider
-     * @param string $expected The expected value.
-     * @param string $input The input value.
-     * @param array $config The property 'doubleBrTag'.
-     * @return void
+     * @param string $linkText
+     * @param array $configuration
+     * @param array $pageArray
+     * @param string $expectedResult
+     * @dataProvider typolinkReturnsCorrectLinksForPagesDataProvider
      */
-    public function stdWrap_doubleBrTag($expected, $input, $config)
+    public function typolinkReturnsCorrectLinksForPages($linkText, $configuration, $pageArray, $expectedResult)
     {
-        $this->assertEquals($expected, $this->subject->stdWrap_doubleBrTag($input, $config));
+        $pageRepositoryMockObject = $this->getMockBuilder(PageRepository::class)
+            ->setMethods(array('getPage'))
+            ->getMock();
+        $pageRepositoryMockObject->expects($this->any())->method('getPage')->willReturn($pageArray);
+        $templateServiceObjectMock = $this->getMockBuilder(TemplateService::class)
+            ->setMethods(array('dummy'))
+            ->getMock();
+        $templateServiceObjectMock->setup = array(
+            'lib.' => array(
+                'parseFunc.' => $this->getLibParseFunc(),
+            ),
+        );
+        $typoScriptFrontendControllerMockObject = $this->createMock(TypoScriptFrontendController::class);
+        $typoScriptFrontendControllerMockObject->config = array(
+            'config' => array(),
+            'mainScript' => 'index.php',
+        );
+        $typoScriptFrontendControllerMockObject->sys_page = $pageRepositoryMockObject;
+        $typoScriptFrontendControllerMockObject->tmpl = $templateServiceObjectMock;
+        $GLOBALS['TSFE'] = $typoScriptFrontendControllerMockObject;
+        $this->subject->_set('typoScriptFrontendController', $typoScriptFrontendControllerMockObject);
+
+        $this->assertEquals($expectedResult, $this->subject->typoLink($linkText, $configuration));
     }
 
     /**
-     * Data provider for stdWrap_brTag
-     *
      * @return array
      */
-    public function stdWrapBrTagDataProvider()
+    public function typolinkReturnsCorrectLinksFilesDataProvider()
     {
-        $noConfig = [];
-        $config1 = ['brTag' => '<br/>'];
-        $config2 = ['brTag' => '<br>'];
-        return [
-            'no config: one break at the beginning' => [LF . 'one' . LF . 'two', 'onetwo', $noConfig],
-            'no config: multiple breaks at the beginning' => [LF . LF . 'one' . LF . 'two', 'onetwo', $noConfig],
-            'no config: one break at the end' => ['one' . LF . 'two' . LF, 'onetwo', $noConfig],
-            'no config: multiple breaks at the end' => ['one' . LF . 'two' . LF . LF, 'onetwo', $noConfig],
-
-            'config1: one break at the beginning' => [LF . 'one' . LF . 'two', '<br/>one<br/>two', $config1],
-            'config1: multiple breaks at the beginning' => [LF . LF . 'one' . LF . 'two', '<br/><br/>one<br/>two', $config1],
-            'config1: one break at the end' => ['one' . LF . 'two' . LF, 'one<br/>two<br/>', $config1],
-            'config1: multiple breaks at the end' => ['one' . LF . 'two' . LF . LF, 'one<br/>two<br/><br/>', $config1],
-
-            'config2: one break at the beginning' => [LF . 'one' . LF . 'two', '<br>one<br>two', $config2],
-            'config2: multiple breaks at the beginning' => [LF . LF . 'one' . LF . 'two', '<br><br>one<br>two', $config2],
-            'config2: one break at the end' => ['one' . LF . 'two' . LF, 'one<br>two<br>', $config2],
-            'config2: multiple breaks at the end' => ['one' . LF . 'two' . LF . LF, 'one<br>two<br><br>', $config2],
-        ];
+        return array(
+            'Link to file' => array(
+                'My file',
+                array(
+                    'parameter' => 'fileadmin/foo.bar',
+                ),
+                '<a href="fileadmin/foo.bar">My file</a>',
+            ),
+            'Link to file without link text' => array(
+                '',
+                array(
+                    'parameter' => 'fileadmin/foo.bar',
+                ),
+                '<a href="fileadmin/foo.bar">fileadmin/foo.bar</a>',
+            ),
+            'Link to file with attributes' => array(
+                'My file',
+                array(
+                    'parameter' => 'fileadmin/foo.bar',
+                    'ATagParams' => 'class="file-class"',
+                    'fileTarget' => '_blank',
+                    'title' => 'Title of the file',
+                ),
+                '<a href="fileadmin/foo.bar" title="Title of the file" target="_blank" class="file-class">My file</a>',
+            ),
+            'Link to file with attributes in parameter' => array(
+                'My file',
+                array(
+                    'parameter' => 'fileadmin/foo.bar _blank file-class "Title of the file"',
+                ),
+                '<a href="fileadmin/foo.bar" title="Title of the file" target="_blank" class="file-class">My file</a>',
+            ),
+            'Link to file with script tag in name' => array(
+                '',
+                array(
+                    'parameter' => 'fileadmin/<script>alert(123)</script>',
+                ),
+                '<a href="fileadmin/&lt;script&gt;alert(123)&lt;/script&gt;">fileadmin/&lt;script&gt;alert(123)&lt;/script&gt;</a>',
+            ),
+        );
     }
 
     /**
-     * Check if brTag works properly
-     *
      * @test
-     * @dataProvider stdWrapBrTagDataProvider
+     * @param string $linkText
+     * @param array $configuration
+     * @param string $expectedResult
+     * @dataProvider typolinkReturnsCorrectLinksFilesDataProvider
      */
-    public function stdWrap_brTag($input, $expected, $config)
+    public function typolinkReturnsCorrectLinksFiles($linkText, $configuration, $expectedResult)
     {
-        $this->assertEquals($expected, $this->subject->stdWrap_brTag($input, $config));
+        $templateServiceObjectMock = $this->getMockBuilder(TemplateService::class)
+            ->setMethods(array('dummy'))
+            ->getMock();
+        $templateServiceObjectMock->setup = array(
+            'lib.' => array(
+                'parseFunc.' => $this->getLibParseFunc(),
+            ),
+        );
+        $typoScriptFrontendControllerMockObject = $this->createMock(TypoScriptFrontendController::class);
+        $typoScriptFrontendControllerMockObject->config = array(
+            'config' => array(),
+            'mainScript' => 'index.php',
+        );
+        $typoScriptFrontendControllerMockObject->tmpl = $templateServiceObjectMock;
+        $GLOBALS['TSFE'] = $typoScriptFrontendControllerMockObject;
+        $this->subject->_set('typoScriptFrontendController', $typoScriptFrontendControllerMockObject);
+
+        $this->assertEquals($expectedResult, $this->subject->typoLink($linkText, $configuration));
     }
 
     /**
-     * Check if stdWrap_encapsLines works properly.
-     *
-     * Show:
-     *
-     * - Delegates to method encaps_lineSplit.
-     * - Parameter 1 is $content.
-     * - Prameter 2 is $conf['encapsLines'].
-     * - Returns the return value.
-     *
-     * @test
-     * @return void
+     * @return array
      */
-     public function stdWrap_encapsLines()
-     {
-         $content = $this->getUniqueId('content');
-         $conf = [
-             'encapsLines' => [$this->getUniqueId('not used')],
-             'encapsLines.' => [$this->getUniqueId('encapsLines.')],
-         ];
-         $return = $this->getUniqueId('return');
-         $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-             ->setMethods(['encaps_lineSplit'])->getMock();
-         $subject
-             ->expects($this->once())
-             ->method('encaps_lineSplit')
-             ->with($content, $conf['encapsLines.'])
-             ->willReturn($return);
-         $this->assertSame($return,
-             $subject->stdWrap_encapsLines($content, $conf));
-     }
-
-    /**
-     * Data provider for stdWrap_keywords
-     *
-     * @return string[][] Order expected, input
-     */
-    public function stdWrapKeywordsDataProvider()
+    public function typolinkReturnsCorrectLinksForFilesWithAbsRefPrefixDataProvider()
     {
-        return [
-            'empty string' => ['', ''],
-            'blank' => ['', ' '],
-            'tab' => ['', "\t"],
-            'single semicolon' => [',', ' ; '],
-            'single comma' => [',', ' , '],
-            'single nl' => [',', ' ' . PHP_EOL . ' '],
-            'double semicolon' => [',,', ' ; ; '],
-            'double comma' => [',,', ' , , '],
-            'double nl' => [',,', ' ' . PHP_EOL . ' ' . PHP_EOL . ' '],
-            'simple word' => ['one', ' one '],
-            'simple word trimmed' => ['one', 'one'],
-            ', separated' => ['one,two', ' one , two '],
-            '; separated' => ['one,two', ' one ; two '],
-            'nl separated' => ['one,two', ' one ' . PHP_EOL . ' two '],
-            ', typical' => ['one,two,three', 'one, two, three'],
-            '; typical' => ['one,two,three', ' one; two; three'],
-            'nl typical' => [
-                'one,two,three',
-                'one' . PHP_EOL . 'two' . PHP_EOL . 'three'
-            ],
-            ', sourounded' => [',one,two,', ' , one , two , '],
-            '; sourounded' => [',one,two,', ' ; one ; two ; '],
-            'nl sourounded' => [
-                ',one,two,',
-                ' ' . PHP_EOL . ' one ' . PHP_EOL . ' two ' . PHP_EOL . ' '
-            ],
-            'mixed' => [
-                'one,two,three,four',
-                ' one, two; three' . PHP_EOL . 'four'
-            ],
-            'keywods with blanks in words' => [
-                'one plus,two minus',
-                ' one plus , two minus ',
-            ]
-        ];
+        return array(
+            'Link to file' => array(
+                'My file',
+                array(
+                    'parameter' => 'fileadmin/foo.bar',
+                ),
+                '/',
+                '<a href="/fileadmin/foo.bar">My file</a>',
+            ),
+            'Link to file with longer absRefPrefix' => array(
+                'My file',
+                array(
+                    'parameter' => 'fileadmin/foo.bar',
+                ),
+                '/sub/',
+                '<a href="/sub/fileadmin/foo.bar">My file</a>',
+            ),
+            'Link to absolute file' => array(
+                'My file',
+                array(
+                    'parameter' => '/images/foo.bar',
+                ),
+                '/',
+                '<a href="/images/foo.bar">My file</a>',
+            ),
+            'Link to absolute file with longer absRefPrefix' => array(
+                'My file',
+                array(
+                    'parameter' => '/images/foo.bar',
+                ),
+                '/sub/',
+                '<a href="/images/foo.bar">My file</a>',
+            ),
+            'Link to absolute file with identical longer absRefPrefix' => array(
+                'My file',
+                array(
+                    'parameter' => '/sub/fileadmin/foo.bar',
+                ),
+                '/sub/',
+                '<a href="/sub/fileadmin/foo.bar">My file</a>',
+            ),
+            'Link to file with empty absRefPrefix' => array(
+                'My file',
+                array(
+                    'parameter' => 'fileadmin/foo.bar',
+                ),
+                '',
+                '<a href="fileadmin/foo.bar">My file</a>',
+            ),
+            'Link to absolute file with empty absRefPrefix' => array(
+                'My file',
+                array(
+                    'parameter' => '/fileadmin/foo.bar',
+                ),
+                '',
+                '<a href="/fileadmin/foo.bar">My file</a>',
+            ),
+            'Link to file with attributes with absRefPrefix' => array(
+                'My file',
+                array(
+                    'parameter' => 'fileadmin/foo.bar',
+                    'ATagParams' => 'class="file-class"',
+                    'fileTarget' => '_blank',
+                    'title' => 'Title of the file',
+                ),
+                '/',
+                '<a href="/fileadmin/foo.bar" title="Title of the file" target="_blank" class="file-class">My file</a>',
+            ),
+            'Link to file with attributes with longer absRefPrefix' => array(
+                'My file',
+                array(
+                    'parameter' => 'fileadmin/foo.bar',
+                    'ATagParams' => 'class="file-class"',
+                    'fileTarget' => '_blank',
+                    'title' => 'Title of the file',
+                ),
+                '/sub/',
+                '<a href="/sub/fileadmin/foo.bar" title="Title of the file" target="_blank" class="file-class">My file</a>',
+            ),
+            'Link to absolute file with attributes with absRefPrefix' => array(
+                'My file',
+                array(
+                    'parameter' => '/images/foo.bar',
+                    'ATagParams' => 'class="file-class"',
+                    'fileTarget' => '_blank',
+                    'title' => 'Title of the file',
+                ),
+                '/',
+                '<a href="/images/foo.bar" title="Title of the file" target="_blank" class="file-class">My file</a>',
+            ),
+            'Link to absolute file with attributes with longer absRefPrefix' => array(
+                'My file',
+                array(
+                    'parameter' => '/images/foo.bar',
+                    'ATagParams' => 'class="file-class"',
+                    'fileTarget' => '_blank',
+                    'title' => 'Title of the file',
+                ),
+                '/sub/',
+                '<a href="/images/foo.bar" title="Title of the file" target="_blank" class="file-class">My file</a>',
+            ),
+            'Link to absolute file with attributes with identical longer absRefPrefix' => array(
+                'My file',
+                array(
+                    'parameter' => '/sub/fileadmin/foo.bar',
+                    'ATagParams' => 'class="file-class"',
+                    'fileTarget' => '_blank',
+                    'title' => 'Title of the file',
+                ),
+                '/sub/',
+                '<a href="/sub/fileadmin/foo.bar" title="Title of the file" target="_blank" class="file-class">My file</a>',
+            ),
+        );
     }
 
     /**
-     * Check if stdWrap_keywords works properly.
-     *
-     * @param string $expected The expected value.
-     * @param string $input The input value.
-     * @return void
      * @test
-     * @dataProvider stdWrapKeywordsDataProvider
+     * @param string $linkText
+     * @param array $configuration
+     * @param string $absRefPrefix
+     * @param string $expectedResult
+     * @dataProvider typolinkReturnsCorrectLinksForFilesWithAbsRefPrefixDataProvider
      */
-    public function stdWrap_keywords($expected, $input)
+    public function typolinkReturnsCorrectLinksForFilesWithAbsRefPrefix($linkText, $configuration, $absRefPrefix, $expectedResult)
     {
-        $this->assertSame($expected, $this->subject->stdWrap_keywords($input));
-    }
+        $templateServiceObjectMock = $this->getMockBuilder(TemplateService::class)
+            ->setMethods(array('dummy'))
+            ->getMock();
+        $templateServiceObjectMock->setup = array(
+            'lib.' => array(
+                'parseFunc.' => $this->getLibParseFunc(),
+            ),
+        );
+        $typoScriptFrontendControllerMockObject = $this->createMock(TypoScriptFrontendController::class);
+        $typoScriptFrontendControllerMockObject->config = array(
+            'config' => array(),
+            'mainScript' => 'index.php',
+        );
+        $typoScriptFrontendControllerMockObject->tmpl = $templateServiceObjectMock;
+        $GLOBALS['TSFE'] = $typoScriptFrontendControllerMockObject;
+        $GLOBALS['TSFE']->absRefPrefix = $absRefPrefix;
+        $this->subject->_set('typoScriptFrontendController', $typoScriptFrontendControllerMockObject);
 
-    /**
-     * Data provider for stdWrap_outerWrap
-     *
-     * @return array Order expected, input, conf
-     */
-    public function stdWrap_outerWrapDataProvider()
-    {
-        return [
-            'no conf' => [
-                'XXX',
-                'XXX',
-                [],
-            ],
-            'simple' => [
-                '<wrap>XXX</wrap>',
-                'XXX',
-                ['outerWrap' => '<wrap>|</wrap>'],
-            ],
-            'missing pipe puts wrap before' => [
-                '<pre>XXX',
-                'XXX',
-                ['outerWrap' => '<pre>'],
-            ],
-            'trims whitespace' => [
-                '<wrap>XXX</wrap>',
-                'XXX',
-                ['outerWrap' => '<wrap>' . TAB . ' | ' . TAB . '</wrap>'],
-            ],
-            'split char change is not possible' => [
-                '<wrap> # </wrap>XXX',
-                'XXX',
-                [
-                    'outerWrap' => '<wrap> # </wrap>',
-                    'outerWrap.' => ['splitChar' => '#'],
-                ],
-            ],
-        ];
+        $this->assertEquals($expectedResult, $this->subject->typoLink($linkText, $configuration));
     }
 
     /**
-     * Check if stdWrap_outerWrap works properly.
-     *
-     * @param string $expected The expected value.
-     * @param string $input The input value.
-     * @param array $conf Property: outerWrap
-     * @return void
      * @test
-     * @dataProvider stdWrap_outerWrapDataProvider
      */
-    public function stdWrap_outerWrap($expected, $input, $conf)
+    public function stdWrap_splitObjReturnsCount()
     {
-        $this->assertSame($expected,
-            $this->subject->stdWrap_outerWrap($input, $conf));
+        $conf = array(
+            'token' => ',',
+            'returnCount' => 1
+        );
+        $expectedResult = 5;
+        $amountOfEntries = $this->subject->splitObj('1, 2, 3, 4, 5', $conf);
+        $this->assertSame(
+            $expectedResult,
+            $amountOfEntries
+        );
     }
 
     /**
-     * Data provider for stdWrap_innerWrap2
-     *
-     * @return array Order expected, input, conf
+     * @return array
      */
-    public function stdWrap_innerWrap2DataProvider()
+    public function getWhereReturnCorrectQueryDataProvider()
     {
-        return [
-            'no conf' => [
-                'XXX',
-                'XXX',
-                [],
-            ],
-            'simple' => [
-                '<wrap>XXX</wrap>',
-                'XXX',
-                ['innerWrap2' => '<wrap>|</wrap>'],
-            ],
-            'missing pipe puts wrap before' => [
-                '<pre>XXX',
-                'XXX',
-                ['innerWrap2' => '<pre>'],
-            ],
-            'trims whitespace' => [
-                '<wrap>XXX</wrap>',
-                'XXX',
-                ['innerWrap2' => '<wrap>' . TAB . ' | ' . TAB . '</wrap>'],
-            ],
-            'split char change is not possible' => [
-                '<wrap> # </wrap>XXX',
-                'XXX',
-                [
-                    'innerWrap2' => '<wrap> # </wrap>',
-                    'innerWrap2.' => ['splitChar' => '#'],
-                ],
-            ],
-        ];
+        return array(
+            array(
+                array(
+                    'tt_content' => array(
+                        'ctrl' => array(
+                        ),
+                        'columns' => array(
+                        )
+                    ),
+                ),
+                'tt_content',
+                array(
+                    'uidInList' => '42',
+                    'pidInList' => 43,
+                    'where' => 'tt_content.cruser_id=5',
+                    'groupBy' => 'tt_content.title',
+                    'orderBy' => 'tt_content.sorting',
+                ),
+                'WHERE tt_content.uid=42 AND tt_content.pid IN (43) AND tt_content.cruser_id=5 GROUP BY tt_content.title ORDER BY tt_content.sorting',
+            ),
+            array(
+                array(
+                    'tt_content' => array(
+                        'ctrl' => array(
+                            'delete' => 'deleted',
+                            'enablecolumns' => array(
+                                'disabled' => 'hidden',
+                                'starttime' => 'startdate',
+                                'endtime' => 'enddate',
+                            ),
+                            'languageField' => 'sys_language_uid',
+                            'transOrigPointerField' => 'l18n_parent',
+                        ),
+                        'columns' => array(
+                        )
+                    ),
+                ),
+                'tt_content',
+                array(
+                    'uidInList' => 42,
+                    'pidInList' => 43,
+                    'where' => 'tt_content.cruser_id=5',
+                    'groupBy' => 'tt_content.title',
+                    'orderBy' => 'tt_content.sorting',
+                ),
+                'WHERE tt_content.uid=42 AND tt_content.pid IN (43) AND tt_content.cruser_id=5 AND (tt_content.sys_language_uid = 13) AND tt_content.deleted=0 AND tt_content.hidden=0 AND tt_content.startdate<=4242 AND (tt_content.enddate=0 OR tt_content.enddate>4242) GROUP BY tt_content.title ORDER BY tt_content.sorting',
+            ),
+            array(
+                array(
+                    'tt_content' => array(
+                        'ctrl' => array(
+                            'languageField' => 'sys_language_uid',
+                            'transOrigPointerField' => 'l18n_parent',
+                        ),
+                        'columns' => array(
+                        )
+                    ),
+                ),
+                'tt_content',
+                array(
+                    'uidInList' => 42,
+                    'pidInList' => 43,
+                    'where' => 'tt_content.cruser_id=5',
+                    'languageField' => 0,
+                ),
+                'WHERE tt_content.uid=42 AND tt_content.pid IN (43) AND tt_content.cruser_id=5',
+            ),
+        );
     }
 
     /**
-     * Check if stdWrap_innerWrap2 works properly.
-     *
-     * @param string $expected The expected value.
-     * @param string $input The input value.
-     * @param array $conf Property: innerWrap2
-     * @return void
      * @test
-     * @dataProvider stdWrap_innerWrap2DataProvider
+     * @param array $tca
+     * @param string $table
+     * @param array $configuration
+     * @param string $expectedResult
+     * @dataProvider getWhereReturnCorrectQueryDataProvider
      */
-    public function stdWrap_innerWrap2($expected, $input, $conf)
+    public function getWhereReturnCorrectQuery($tca, $table, $configuration, $expectedResult)
     {
-        $this->assertSame($expected,
-            $this->subject->stdWrap_innerWrap2($input, $conf));
+        $GLOBALS['TCA'] = $tca;
+        $GLOBALS['SIM_ACCESS_TIME'] = '4242';
+        $GLOBALS['TSFE']->sys_language_content = 13;
+        /** @var \PHPUnit_Framework_MockObject_MockObject|ContentObjectRenderer $contentObjectRenderer */
+        $contentObjectRenderer = $this->getMockBuilder(ContentObjectRenderer::class)
+            ->setMethods(array('checkPidArray'))
+            ->getMock();
+        $contentObjectRenderer->expects($this->any())->method('checkPidArray')->willReturn(explode(',', $configuration['pidInList']));
+        $this->assertEquals($expectedResult, $contentObjectRenderer->getWhere($table, $configuration));
     }
 
-    /**
-     * Data provider for stdWrap_wrap2
-     *
-     * @return array Order expected, input, conf
-     */
-    public function stdWrap_wrap2DataProvider()
-    {
-        return [
-            'no conf' => [
-                'XXX',
-                'XXX',
-                [],
-            ],
-            'simple' => [
-                '<wrapper>XXX</wrapper>',
-                'XXX',
-                ['wrap2' => '<wrapper>|</wrapper>'],
-            ],
-            'trims whitespace' => [
-                '<wrapper>XXX</wrapper>',
-                'XXX',
-                ['wrap2' => '<wrapper>' . TAB . ' | ' . TAB . '</wrapper>'],
-            ],
-            'missing pipe puts wrap2 before' => [
-                '<pre>XXX',
-                'XXX',
-                [
-                    'wrap2' => '<pre>',
-                ],
-            ],
-            'split char change' => [
-                '<wrapper>XXX</wrapper>',
-                'XXX',
-                [
-                    'wrap2' => '<wrapper> # </wrapper>',
-                    'wrap2.' => ['splitChar' => '#'],
-                ],
-            ],
-            'split by pattern' => [
-                '<wrapper>XXX</wrapper>',
-                'XXX',
-                [
-                    'wrap2' => '<wrapper> ###splitter### </wrapper>',
-                    'wrap2.' => ['splitChar' => '###splitter###'],
-                ],
-            ],
-        ];
-    }
+    ////////////////////////////////////
+    // Test concerning link generation
+    ////////////////////////////////////
 
     /**
-     * Check if stdWrap_wrap2 works properly.
-     *
-     * @param string $expected The expected value.
-     * @param string $input The input value.
-     * @param array $conf Properties: wrap2, wrap2.splitChar
-     * @return void
      * @test
-     * @dataProvider stdWrap_wrap2DataProvider
      */
-    public function stdWrap_wrap2($expected, $input, $conf)
+    public function filelinkCreatesCorrectUrlForFileWithUrlEncodedSpecialChars()
     {
-        $this->assertSame($expected, $this->subject->stdWrap_wrap2($input, $conf));
-    }
+        $fileNameAndPath = PATH_site . 'typo3temp/var/tests/phpunitJumpUrlTestFile with spaces & amps.txt';
+        file_put_contents($fileNameAndPath, 'Some test data');
+        $relativeFileNameAndPath = substr($fileNameAndPath, strlen(PATH_site));
+        $fileName = substr($fileNameAndPath, strlen(PATH_site . 'typo3temp/var/tests/'));
 
-    /**
-     * Data provider for stdWrap_wrap3
-     *
-     * @return array Order expected, input, conf
-     */
-    public function stdWrap_wrap3DataProvider()
-    {
-        return [
-            'no conf' => [
-                'XXX',
-                'XXX',
-                [],
-            ],
-            'simple' => [
-                '<wrapper>XXX</wrapper>',
-                'XXX',
-                ['wrap3' => '<wrapper>|</wrapper>'],
-            ],
-            'trims whitespace' => [
-                '<wrapper>XXX</wrapper>',
-                'XXX',
-                ['wrap3' => '<wrapper>' . TAB . ' | ' . TAB . '</wrapper>'],
-            ],
-            'missing pipe puts wrap3 before' => [
-                '<pre>XXX',
-                'XXX',
-                [
-                    'wrap3' => '<pre>',
-                ],
-            ],
-            'split char change' => [
-                '<wrapper>XXX</wrapper>',
-                'XXX',
-                [
-                    'wrap3' => '<wrapper> # </wrapper>',
-                    'wrap3.' => ['splitChar' => '#'],
-                ],
-            ],
-            'split by pattern' => [
-                '<wrapper>XXX</wrapper>',
-                'XXX',
-                [
-                    'wrap3' => '<wrapper> ###splitter### </wrapper>',
-                    'wrap3.' => ['splitChar' => '###splitter###'],
-                ],
-            ],
-        ];
+        $expectedLink = str_replace('%2F', '/', rawurlencode($relativeFileNameAndPath));
+        $result = $this->subject->filelink($fileName, array('path' => 'typo3temp/var/tests/'));
+        $this->assertEquals('<a href="' . $expectedLink . '">' . $fileName . '</a>', $result);
+
+        GeneralUtility::unlink_tempfile($fileNameAndPath);
     }
 
     /**
-     * Check if stdWrap_wrap3 works properly.
-     *
-     * @param string $expected The expected value.
-     * @param string $input The input value.
-     * @param array $conf Properties: wrap3, wrap3.splitChar
-     * @return void
-     * @test
-     * @dataProvider stdWrap_wrap3DataProvider
+     * @return array
      */
-    public function stdWrap_wrap3($expected, $input, $conf)
+    public function substituteMarkerArrayCachedReturnsExpectedContentDataProvider()
     {
-        $this->assertSame($expected, $this->subject->stdWrap_wrap3($input, $conf));
+        return array(
+            'no markers defined' => array(
+                'dummy content with ###UNREPLACED### marker',
+                array(),
+                array(),
+                array(),
+                'dummy content with ###UNREPLACED### marker',
+                false,
+                false
+            ),
+            'no markers used' => array(
+                'dummy content with no marker',
+                array(
+                    '###REPLACED###' => '_replaced_'
+                ),
+                array(),
+                array(),
+                'dummy content with no marker',
+                true,
+                false
+            ),
+            'one marker' => array(
+                'dummy content with ###REPLACED### marker',
+                array(
+                    '###REPLACED###' => '_replaced_'
+                ),
+                array(),
+                array(),
+                'dummy content with _replaced_ marker'
+            ),
+            'one marker with lots of chars' => array(
+                'dummy content with ###RE.:##-=_()LACED### marker',
+                array(
+                    '###RE.:##-=_()LACED###' => '_replaced_'
+                ),
+                array(),
+                array(),
+                'dummy content with _replaced_ marker'
+            ),
+            'markers which are special' => array(
+                'dummy ###aa##.#######A### ######',
+                array(
+                    '###aa##.###' => 'content ',
+                    '###A###' => 'is',
+                    '######' => '-is not considered-'
+                ),
+                array(),
+                array(),
+                'dummy content #is ######'
+            ),
+            'two markers in content, but more defined' => array(
+                'dummy ###CONTENT### with ###REPLACED### marker',
+                array(
+                    '###REPLACED###' => '_replaced_',
+                    '###CONTENT###' => 'content',
+                    '###NEVERUSED###' => 'bar'
+                ),
+                array(),
+                array(),
+                'dummy content with _replaced_ marker'
+            ),
+            'one subpart' => array(
+                'dummy content with ###ASUBPART### around some text###ASUBPART###.',
+                array(),
+                array(
+                    '###ASUBPART###' => 'some other text'
+                ),
+                array(),
+                'dummy content with some other text.'
+            ),
+            'one wrapped subpart' => array(
+                'dummy content with ###AWRAPPEDSUBPART### around some text###AWRAPPEDSUBPART###.',
+                array(),
+                array(),
+                array(
+                    '###AWRAPPEDSUBPART###' => array(
+                        'more content',
+                        'content'
+                    )
+                ),
+                'dummy content with more content around some textcontent.'
+            ),
+            'one subpart with markers, not replaced recursively' => array(
+                'dummy ###CONTENT### with ###ASUBPART### around ###SOME### text###ASUBPART###.',
+                array(
+                    '###CONTENT###' => 'content',
+                    '###SOME###' => '-this should never make it into output-',
+                    '###OTHER_NOT_REPLACED###' => '-this should never make it into output-'
+                ),
+                array(
+                    '###ASUBPART###' => 'some ###OTHER_NOT_REPLACED### text'
+                ),
+                array(),
+                'dummy content with some ###OTHER_NOT_REPLACED### text.'
+            ),
+        );
     }
 
     /**
-     * Data provider for stdWrap_wrap
+     * @test
+     * @dataProvider substituteMarkerArrayCachedReturnsExpectedContentDataProvider
      *
-     * @return array Order expected, input, conf
+     * @param string $content
+     * @param array $markContentArray
+     * @param array $subpartContentArray
+     * @param array $wrappedSubpartContentArray
+     * @param string $expectedContent
+     * @param bool $shouldQueryCache
+     * @param bool $shouldStoreCache
      */
-    public function stdWrap_wrapDataProvider()
+    public function substituteMarkerArrayCachedReturnsExpectedContent($content, array $markContentArray, array $subpartContentArray, array $wrappedSubpartContentArray, $expectedContent, $shouldQueryCache = true, $shouldStoreCache = true)
     {
-        return [
-            'no conf' => [
-                'XXX',
-                'XXX',
-                [],
-            ],
-            'simple' => [
-                '<wrapper>XXX</wrapper>',
-                'XXX',
-                ['wrap' => '<wrapper>|</wrapper>'],
-            ],
-            'trims whitespace' => [
-                '<wrapper>XXX</wrapper>',
-                'XXX',
-                ['wrap' => '<wrapper>' . TAB . ' | ' . TAB . '</wrapper>'],
-            ],
-            'missing pipe puts wrap before' => [
-                '<pre>XXX',
-                'XXX',
-                [
-                    'wrap' => '<pre>',
-                ],
-            ],
-            'split char change' => [
-                '<wrapper>XXX</wrapper>',
-                'XXX',
-                [
-                    'wrap' => '<wrapper> # </wrapper>',
-                    'wrap.' => ['splitChar' => '#'],
-                ],
-            ],
-            'split by pattern' => [
-                '<wrapper>XXX</wrapper>',
-                'XXX',
-                [
-                    'wrap' => '<wrapper> ###splitter### </wrapper>',
-                    'wrap.' => ['splitChar' => '###splitter###'],
-                ],
-            ],
-        ];
+        /** @var PageRepositoryFixture|\PHPUnit_Framework_MockObject_MockObject $pageRepo */
+        $pageRepo = $this->frontendControllerMock->sys_page;
+        $pageRepo->resetCallCount();
+
+        $resultContent = $this->subject->substituteMarkerArrayCached($content, $markContentArray, $subpartContentArray, $wrappedSubpartContentArray);
+
+        $this->assertSame((int)$shouldQueryCache, $pageRepo::$getHashCallCount, 'getHash call count mismatch');
+        $this->assertSame((int)$shouldStoreCache, $pageRepo::$storeHashCallCount, 'storeHash call count mismatch');
+        $this->assertSame($expectedContent, $resultContent);
     }
 
     /**
-     * Check if stdWrap_wrap works properly.
-     *
-     * @param string $expected The expected value.
-     * @param string $input The input value.
-     * @param array $conf Properties: wrap, wrap.splitChar
-     * @return void
      * @test
-     * @dataProvider stdWrap_wrapDataProvider
      */
-    public function stdWrap_wrap($expected, $input, $conf)
+    public function substituteMarkerArrayCachedRetrievesCachedValueFromRuntimeCache()
     {
-        $this->assertSame($expected,
-            $this->subject->stdWrap_wrap($input, $conf));
+        /** @var PageRepositoryFixture|\PHPUnit_Framework_MockObject_MockObject $pageRepo */
+        $pageRepo = $this->frontendControllerMock->sys_page;
+        $pageRepo->resetCallCount();
+
+        $content = 'Please tell me this ###FOO###.';
+        $markContentArray = array(
+            '###FOO###' => 'foo',
+            '###NOTUSED###' => 'blub'
+        );
+        $storeKey = md5('substituteMarkerArrayCached_storeKey:' . serialize(array($content, array_keys($markContentArray))));
+        $this->subject->substMarkerCache[$storeKey] = array(
+            'c' => array(
+                'Please tell me this ',
+                '.'
+            ),
+            'k' => array(
+                '###FOO###'
+            ),
+        );
+        $resultContent = $this->subject->substituteMarkerArrayCached($content, $markContentArray);
+        $this->assertSame(0, $pageRepo::$getHashCallCount);
+        $this->assertSame('Please tell me this foo.', $resultContent);
     }
 
     /**
-     * Data provider for stdWrap_lang
-     *
-     * @return array Order expected, input, conf, language
+     * @test
      */
-    public function stdWrap_langDataProvider()
+    public function substituteMarkerArrayCachedRetrievesCachedValueFromDbCache()
     {
-        return [
-            'empty conf' => [
-                'original',
-                'original',
-                [],
-                'de',
-            ],
-            'translation de' => [
-                'Übersetzung',
-                'original',
-                [
-                    'lang.' => [
-                        'de' => 'Übersetzung',
-                        'it' => 'traduzione',
-                    ]
-                ],
-                'de',
-            ],
-            'translation it' => [
-                'traduzione',
-                'original',
-                [
-                    'lang.' => [
-                        'de' => 'Übersetzung',
-                        'it' => 'traduzione',
-                    ]
-                ],
-                'it',
-            ],
-            'no translation' => [
-                'original',
-                'original',
-                [
-                    'lang.' => [
-                        'de' => 'Übersetzung',
-                        'it' => 'traduzione',
-                    ]
-                ],
-                '',
-            ],
-            'missing label' => [
-                'original',
-                'original',
-                [
-                    'lang.' => [
-                        'de' => 'Übersetzung',
-                        'it' => 'traduzione',
-                    ]
-                ],
-                'fr',
-            ],
-        ];
-    }
+        /** @var PageRepositoryFixture|\PHPUnit_Framework_MockObject_MockObject $pageRepo */
+        $pageRepo = $this->frontendControllerMock->sys_page;
+        $pageRepo->resetCallCount();
 
-    /**
-     * Check if stdWrap_lang works properly.
-     *
-     * @param string $expected The expected value.
-     * @param string $input The input value.
-     * @param array $conf Properties: lang.xy.
-     * @param string $language For $TSFE->config[config][language].
-     * @return void
+        $content = 'Please tell me this ###FOO###.';
+        $markContentArray = array(
+            '###FOO###' => 'foo',
+            '###NOTUSED###' => 'blub'
+        );
+        $pageRepo::$dbCacheContent = array(
+            'c' => array(
+                'Please tell me this ',
+                '.'
+            ),
+            'k' => array(
+                '###FOO###'
+            ),
+        );
+        $resultContent = $this->subject->substituteMarkerArrayCached($content, $markContentArray);
+        $this->assertSame(1, $pageRepo::$getHashCallCount, 'getHash call count mismatch');
+        $this->assertSame(0, $pageRepo::$storeHashCallCount, 'storeHash call count mismatch');
+        $this->assertSame('Please tell me this foo.', $resultContent);
+    }
+
+    /**
      * @test
-     * @dataProvider stdWrap_langDataProvider
      */
-    public function stdWrap_lang($expected, $input, $conf, $language)
+    public function substituteMarkerArrayCachedStoresResultInCaches()
     {
-        if ($language) {
-            $this->frontendControllerMock
-                ->config['config']['language'] = $language;
-        }
-        $this->assertSame($expected,
-            $this->subject->stdWrap_lang($input, $conf));
+        /** @var PageRepositoryFixture|\PHPUnit_Framework_MockObject_MockObject $pageRepo */
+        $pageRepo = $this->frontendControllerMock->sys_page;
+        $pageRepo->resetCallCount();
+
+        $content = 'Please tell me this ###FOO###.';
+        $markContentArray = array(
+            '###FOO###' => 'foo',
+            '###NOTUSED###' => 'blub'
+        );
+        $resultContent = $this->subject->substituteMarkerArrayCached($content, $markContentArray);
+
+        $storeKey = md5('substituteMarkerArrayCached_storeKey:' . serialize(array($content, array_keys($markContentArray))));
+        $storeArr = array(
+            'c' => array(
+                'Please tell me this ',
+                '.'
+            ),
+            'k' => array(
+                '###FOO###'
+            ),
+        );
+        $this->assertSame(1, $pageRepo::$getHashCallCount);
+        $this->assertSame('Please tell me this foo.', $resultContent);
+        $this->assertSame($storeArr, $this->subject->substMarkerCache[$storeKey]);
+        $this->assertSame(1, $pageRepo::$storeHashCallCount);
     }
 
     /**
-     * Data provider for stdWrap_innerWrap
+     * Check if calculateCacheKey works properly.
      *
-     * @return array Order expected, input, conf
+     * @return array Order: expect, conf, times, with, withWrap, will
      */
-    public function stdWrap_innerWrapDataProvider()
+    public function calculateCacheKeyDataProvider()
     {
+        $value = $this->getUniqueId('value');
+        $wrap = [$this->getUniqueId('wrap')];
+        $valueConf = ['key' => $value];
+        $wrapConf = ['key.' => $wrap];
+        $conf = array_merge($valueConf, $wrapConf);
+        $will = $this->getUniqueId('stdWrap');
+
         return [
             'no conf' => [
-                'XXX',
-                'XXX',
+                '',
                 [],
+                0,
+                null,
+                null,
+                null
             ],
-            'simple' => [
-                '<wrap>XXX</wrap>',
-                'XXX',
-                ['innerWrap' => '<wrap>|</wrap>'],
-            ],
-            'missing pipe puts wrap before' => [
-                '<pre>XXX',
-                'XXX',
-                ['innerWrap' => '<pre>'],
+            'value conf only' => [
+                $value,
+                $valueConf,
+                0,
+                null,
+                null,
+                null
             ],
-            'trims whitespace' => [
-                '<wrap>XXX</wrap>',
-                'XXX',
-                ['innerWrap' => '<wrap>' . TAB . ' | ' . TAB . '</wrap>'],
+            'wrap conf only' => [
+                $will,
+                $wrapConf,
+                1,
+                '',
+                $wrap,
+                $will
             ],
-            'split char change is not possible' => [
-                '<wrap> # </wrap>XXX',
-                'XXX',
-                [
-                    'innerWrap' => '<wrap> # </wrap>',
-                    'innerWrap.' => ['splitChar' => '#'],
-                ],
+            'full conf' => [
+                $will,
+                $conf,
+                1,
+                $value,
+                $wrap,
+                $will
             ],
         ];
     }
 
     /**
-     * Check if stdWrap_innerWrap works properly.
+     * Check if calculateCacheKey works properly.
+     *
+     * - takes key from $conf['key']
+     * - processes key with stdWrap based on $conf['key.']
      *
-     * @param string $expected The expected value.
-     * @param string $input The input value.
-     * @param array $conf Property: innerWrap
-     * @return void
      * @test
-     * @dataProvider stdWrap_innerWrapDataProvider
+     * @dataProvider calculateCacheKeyDataProvider
+     * @param string $expect Expected result.
+     * @param array $conf Properties 'key', 'key.'
+     * @param int $times Times called mocked method.
+     * @param array $with Parameter passed to mocked method.
+     * @param string $will Return value of mocked method.
+     * @return void
      */
-    public function stdWrap_innerWrap($expected, $input, $conf)
+    public function calculateCacheKey($expect, $conf, $times, $with, $withWrap, $will)
     {
-        $this->assertSame($expected,
-            $this->subject->stdWrap_innerWrap($input, $conf));
+        $subject = $this->getAccessibleMock(ContentObjectRenderer::class, ['stdWrap']);
+        $subject->expects($this->exactly($times))
+            ->method('stdWrap')
+            ->with($with, $withWrap)
+            ->willReturn($will);
+
+        $result = $subject->_call('calculateCacheKey', $conf);
+        $this->assertSame($expect, $result);
     }
 
     /**
-     * Data provider for stdWrap_br
+     * Data provider for getFromCache
      *
-     * @return string[][] Order expected, given, xhtmlDoctype
+     * @return array Order: expect, conf, cacheKey, times, cached.
      */
-    public function stdWrapBrDataProvider()
+    public function getFromCacheDtataProvider()
     {
+        $conf = [$this->getUniqueId('conf')];
         return [
-            'no xhtml with LF in between' => [
-                'one<br>' . LF . 'two',
-                'one' . LF . 'two',
-                null
-            ],
-            'no xhtml with LF in between and around' => [
-                '<br>' . LF . 'one<br>' . LF . 'two<br>' . LF,
-                LF . 'one' . LF . 'two' . LF,
-                null
-            ],
-            'xhtml with LF in between' => [
-                'one<br />' . LF . 'two',
-                'one' . LF . 'two',
-                'xhtml_strict'
+            'empty cache key' => [
+                false, $conf, '', 0, null,
             ],
-            'xhtml with LF in between and around' => [
-                '<br />' . LF . 'one<br />' . LF . 'two<br />' . LF,
-                LF . 'one' . LF . 'two' . LF,
-                'xhtml_strict'
+            'non-empty cache key' => [
+                'value', $conf, 'non-empty-key', 1, 'value',
             ],
         ];
     }
 
     /**
-     * Test that stdWrap_br works as expected.
+     * Check if getFromCache works properly.
+     *
+     * - CalculateCacheKey is called to calc the cache key.
+     * - $conf is passed on as parameter
+     * - CacheFrontend is created and called if $cacheKey is not empty.
+     * - Else false is returned.
      *
-     * @param string $expected The expected value.
-     * @param string $input The input value.
-     * @param string $xhtmlDoctype Xhtml document type.
-     * @return void
      * @test
-     * @dataProvider stdWrapBrDataProvider
+     * @dataProvider getFromCacheDtataProvider
+     * @param string $expect Expected result.
+     * @param array $conf Configuration to pass to calculateCacheKey mock.
+     * @param string $cacheKey Return from calculateCacheKey mock.
+     * @param int $times Times the cache is expected to be called (0 or 1).
+     * @param string $cached Return from cacheFrontend mock.
+     * @return void
      */
-    public function stdWrap_br($expected, $input, $xhtmlDoctype)
+    public function getFromCache($expect, $conf, $cacheKey, $times, $cached)
     {
-        $GLOBALS['TSFE']->xhtmlDoctype = $xhtmlDoctype;
-        $this->assertSame($expected, $this->subject->stdWrap_br($input));
+        $subject = $this->getAccessibleMock(
+            ContentObjectRenderer::class, ['calculateCacheKey']);
+        $subject
+            ->expects($this->exactly(1))
+            ->method('calculateCacheKey')
+            ->with($conf)
+            ->willReturn($cacheKey);
+        $cacheFrontend = $this->createMock(CacheFrontendInterface::class);
+        $cacheFrontend
+            ->expects($this->exactly($times))
+            ->method('get')
+            ->with($cacheKey)
+            ->willReturn($cached);
+        $cacheManager = $this->createMock(CacheManager::class);
+        $cacheManager
+            ->method('getCache')
+            ->willReturn($cacheFrontend);
+        GeneralUtility::setSingletonInstance(
+            CacheManager::class, $cacheManager);
+        $this->assertSame($expect, $subject->_call('getFromCache', $conf));
     }
 
     /**
-     * Check if stdWrap_space works properly.
-     *
-     * Show:
-     *
-     *  - Delegates to method wrapSpace.
-     *  - Parameter 1 is $content.
-     *  - Parameter 2 is $conf['space'],
-     *  - trimmed.
-     *  - Parameter 3 is $conf['space.'].
-     *  - Returns the return value.
+     * Data provider for getFieldVal
      *
-     *  @test
-     *  @return void.
+     * @return array [$expect, $fields]
      */
-    public function stdWrap_space()
+    public function getFieldValDataProvider()
     {
-        $content = $this->getUniqueId('content');
-        $trimmed = $this->getUniqueId('space trimmed');
-        $conf = [
-            'space' => TAB . ' ' . $trimmed . ' ' . TAB,
-            'space.' => [$this->getUniqueId('space.')],
-        ];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['wrapSpace'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('wrapSpace')
-            ->with($content, $trimmed, $conf['space.'])
-            ->willReturn($return);
-        $this->assertSame($return, $subject->stdWrap_space($content, $conf));
-    }
-
+        return [
+            'invalid single key' => [null, 'invalid'],
+            'single key of null' => [null, 'null'],
+            'single key of empty string' => ['', 'empty'],
+            'single key of non-empty string' => ['string 1', 'string1'],
+            'single key of boolean false' => [false, 'false'],
+            'single key of boolean true' => [true, 'true'],
+            'single key of integer 0' => [0, 'zero'],
+            'single key of integer 1' => [1, 'one'],
+            'single key to be trimmed' => ['string 1', ' string1 '],
+
+            'split nothing' => ['', '//'],
+            'split one before' => ['string 1', 'string1//'],
+            'split one after' => ['string 1', '//string1'],
+            'split two ' => ['string 1', 'string1//string2'],
+            'split three ' => ['string 1', 'string1//string2//string3'],
+            'split to be trimmed' => ['string 1', ' string1 // string2 '],
+            '0 is not empty' => [0, '// zero'],
+            '1 is not empty' => [1, '// one'],
+            'true is not empty' => [true, '// true'],
+            'false is empty' => ['', '// false'],
+            'null is empty' => ['', '// null'],
+            'empty string is empty' => ['', '// empty'],
+            'string is not empty' => ['string 1', '// string1'],
+            'first non-empty winns' => [0, 'false//empty//null//zero//one'],
+            'empty string is fallback' => ['', 'false // empty // null'],
+        ];
+    }
+
     /**
-     * Check if stdWrap_spaceBefore works properly.
+     * Check that getFieldVal works properly.
      *
      * Show:
      *
-     *  - Delegates to method wrapSpace.
-     *  - Parameter 1 is $content.
-     *  - Parameter 2 is $conf['spaceBefore'],
-     *  - trimmed,
-     *  - appended with '|'.
-     *  - Parameter 3 is $conf['space.'] !!!
-     *  - Returns the return value.
+     * - Returns the field from $this->data.
+     * - The keys are trimmed.
      *
-     *  @test
-     *  @return void.
+     * - For a single key (no //) returns the field as is:
+     *
+     *   - '' => ''
+     *   - null => null
+     *   - false => false
+     *   - true => true
+     *   -  0 => 0
+     *   -  1 => 1
+     *   - 'string' => 'string'
+     *
+     * - If '//' is present, explodes key candidates.
+     * - Returns the first field, that is not "empty".
+     * - "Empty" is checked after type cast to string by comparing to ''.
+     * - The winning non-empty value is returned as is.
+     * - The fallback, if all evals to empty, is the empty string ''.
+     * - '//' with single elements and empty string fallback results in:
+     *
+     *   - '' => ''
+     *   - null => ''
+     *   - false => ''
+     *   - true => true
+     *   -  0 => 0
+     *   -  1 => 1
+     *   - 'string' => 'string'
+     *
+     * @test
+     * @dataProvider getFieldValDataProvider
+     * @param string $expect The expected string.
+     * @param string $fields Field names divides by //.
+     * @return void
      */
-    public function stdWrap_spaceBefore()
+    public function getFieldVal($expect, $fields)
     {
-        $content = $this->getUniqueId('content');
-        $trimmed = $this->getUniqueId('spaceBefore trimmed');
-        $conf = [
-            'spaceBefore' => TAB . ' ' . $trimmed . ' ' . TAB,
-            'space.' => [$this->getUniqueId('space.')],
+        $data = [
+            'string1' => 'string 1',
+            'string2' => 'string 2',
+            'string3' => 'string 3',
+            'empty' => '',
+            'null' => null,
+            'false' => false,
+            'true' => true,
+            'zero' => 0,
+            'one' => 1,
         ];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['wrapSpace'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('wrapSpace')
-            ->with($content, $trimmed . '|', $conf['space.'])
-            ->willReturn($return);
-        $this->assertSame($return,
-            $subject->stdWrap_spaceBefore($content, $conf));
+        $this->subject->_set('data', $data);
+        $this->assertSame($expect, $this->subject->getFieldVal($fields));
     }
 
+  /***************************************************************************
+   * Tests for stdWrap_ in alphabetical order (all uppercase before lowercase)
+   ***************************************************************************/
+
     /**
-     * Check if stdWrap_spaceAfter works properly.
-     *
-     * Show:
-     *
-     *  - Delegates to method wrapSpace.
-     *  - Parameter 1 is $content.
-     *  - Parameter 2 is $conf['spaceAfter'],
-     *  - trimmed,
-     *  - prepended with '|'.
-     *  - Parameter 3 is $conf['space.'] !!!
-     *  - Returns the return value.
+     * Data provider for fourTypesOfStdWrapHookObjectProcessors
      *
-     *  @test
-     *  @return void.
+     * @return array Order: stdWrap, hookObjectCall
      */
-    public function stdWrap_spaceAfter()
+    public function fourTypesOfStdWrapHookObjectProcessorsDataProvider()
     {
-        $content = $this->getUniqueId('content');
-        $trimmed = $this->getUniqueId('spaceAfter trimmed');
-        $conf = [
-            'spaceAfter' => TAB . ' ' . $trimmed . ' ' . TAB,
-            'space.' => [$this->getUniqueId('space.')],
+        return [
+            'preProcess' => [
+                'stdWrap_stdWrapPreProcess', 'stdWrapPreProcess'
+            ],
+            'override' => [
+                'stdWrap_stdWrapOverride', 'stdWrapOverride'
+            ],
+            'process' => [
+                'stdWrap_stdWrapProcess', 'stdWrapProcess'
+            ],
+            'postProcess' => [
+                'stdWrap_stdWrapPostProcess', 'stdWrapPostProcess'
+            ],
         ];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['wrapSpace'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('wrapSpace')
-            ->with($content, '|' . $trimmed, $conf['space.'])
-            ->willReturn($return);
-        $this->assertSame($return,
-            $subject->stdWrap_spaceAfter($content, $conf));
     }
 
     /**
-     * Check if stdWrap_char works properly.
+     * Check if stdWrapHookObject processors work properly.
+     *
+     * Checks:
+     *
+     * - stdWrap_stdWrapPreProcess
+     * - stdWrap_stdWrapOverride
+     * - stdWrap_stdWrapProcess
+     * - stdWrap_stdWrapPostProcess
      *
      * @test
+     * @dataProvider fourTypesOfStdWrapHookObjectProcessorsDataProvider
+     * @param string $stdWrapMethod: The method to cover.
+     * @param string $hookObjectCall: The expected hook object call.
      * @return void
      */
-    public function stdWrap_char()
+    public function fourTypesOfStdWrapHookObjectProcessors(
+        $stdWrapMethod, $hookObjectCall)
     {
-        $input = 'discarded';
-        $expected = 'C';
-        $this->assertEquals($expected, $this->subject->stdWrap_char($input, ['char' => '67']));
+        $conf = [$this->getUniqueId('conf')];
+        $content = $this->getUniqueId('content');
+        $processed1 = $this->getUniqueId('processed1');
+        $processed2 = $this->getUniqueId('processed2');
+        $hookObject1 = $this->createMock(
+            ContentObjectStdWrapHookInterface::class);
+        $hookObject1->expects($this->once())
+            ->method($hookObjectCall)
+            ->with($content, $conf)
+            ->willReturn($processed1);
+        $hookObject2 = $this->createMock(
+            ContentObjectStdWrapHookInterface::class);
+        $hookObject2->expects($this->once())
+            ->method($hookObjectCall)
+            ->with($processed1, $conf)
+            ->willReturn($processed2);
+        $this->subject->_set('stdWrapHookObjects',
+            [$hookObject1, $hookObject2]);
+        $result = $this->subject->$stdWrapMethod($content, $conf);
+        $this->assertSame($processed2, $result);
     }
 
     /**
-     * Check that stdWrap_typolink works properly.
-     *
-     * Show:
-     *  - Delegates to method typolink.
-     *  - Parameter 1 is $content.
-     *  - Parameter 2 is $conf['typolink.'].
-     *  - Returns the return value.
+     * Data provider for stdWrap_HTMLparser
      *
-     *  @test
-     *  @return void.
+     * @return array [$expect, $content, $conf, $times, $will].
      */
-    public function stdWrap_typolink()
+    public function stdWrap_HTMLparserDataProvider()
     {
         $content = $this->getUniqueId('content');
-        $conf = [
-            'typolink' => $this->getUniqueId('not used'),
-            'typolink.' => [$this->getUniqueId('typolink.')],
+        $parsed = $this->getUniqueId('parsed');
+        return [
+            'no config' => [
+                $content, $content, [], 0, $parsed
+            ],
+            'no array' => [
+                $content, $content, ['HTMLparser.' => 1], 0, $parsed
+            ],
+            'empty array' => [
+                $parsed, $content, ['HTMLparser.' => []], 1, $parsed
+            ],
+            'non-empty array' => [
+                $parsed, $content, ['HTMLparser.' => [true]], 1, $parsed
+            ],
         ];
-        $return = $this->getUniqueId('return');
-        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['typolink'])->getMock();
-        $subject
-            ->expects($this->once())
-            ->method('typolink')
-            ->with($content, $conf['typolink.'])
-            ->willReturn($return);
-        $this->assertSame($return, $subject->stdWrap_typolink($content, $conf));
     }
 
     /**
-     * Check that stdWrap_postUserFunc works properly.
+     * Check if stdWrap_HTMLparser works properly
      *
      * Show:
-     *  - Delegates to method callUserFunction.
-     *  - Parameter 1 is $conf['postUserFunc'].
-     *  - Parameter 2 is $conf['postUserFunc.'].
-     *  - Returns the return value.
      *
-     *  @test
-     *  @return void.
+     * - Checks if $conf['HTMLparser.'] is an array.
+     * - No:
+     *   - Returns $content as is.
+     * - Yes:
+     *   - Delegates to method HTMLparser_TSbridge.
+     *   - Parameter 1 is $content.
+     *   - Parameter 2 is $conf['HTMLparser'].
+     *   - Returns the return value.
+     *
+     * @test
+     * @dataProvider stdWrap_HTMLparserDataProvider
+     * @param string $expect The expected output.
+     * @param string $content The given content.
+     * @param array $conf The given configuration.
+     * @param int $times Times HTMLparser_TSbridge is called (0 or 1).
+     * @param string $will Return of HTMLparser_TSbridge.
+     * @return void.
      */
-    public function stdWrap_postUserFunc()
+    public function stdWrap_HTMLparser(
+        $expect, $content, $conf, $times, $will)
     {
-        $content = $this->getUniqueId('content');
-        $conf = [
-            'postUserFunc' => $this->getUniqueId('postUserFunc'),
-            'postUserFunc.' => [$this->getUniqueId('postUserFunc.')],
-        ];
-        $return = $this->getUniqueId('return');
         $subject = $this->getMockBuilder(ContentObjectRenderer::class)
-            ->setMethods(['callUserFunction'])->getMock();
+            ->setMethods(['HTMLparser_TSbridge'])->getMock();
         $subject
-            ->expects($this->once())
-            ->method('callUserFunction')
-            ->with($conf['postUserFunc'], $conf['postUserFunc.'])
-            ->willReturn($return);
-        $this->assertSame($return,
-            $subject->stdWrap_postUserFunc($content, $conf));
-    }
-
-    /**
-     * Check if stdWrap_debug works properly.
-     *
-     * @test
-     * @return void
-     */
-    public function stdWrap_debug()
-    {
-        $expect = '<pre>&lt;p class=&quot;class&quot;&gt;&lt;br/&gt;'
-            . '&lt;/p&gt;</pre>';
-        $content = '<p class="class"><br/></p>';
-        $this->assertSame($expect, $this->subject->stdWrap_debug($content));
+            ->expects($this->exactly($times))
+            ->method('HTMLparser_TSbridge')
+            ->with($content, $conf['HTMLparser.'])
+            ->willReturn($will);
+        $this->assertSame($expect,
+            $subject->stdWrap_HTMLparser($content, $conf));
     }
 
-    ///////////////////////////////
-    // Tests concerning getData()
-    ///////////////////////////////
-
     /**
      * @return array
      */
-    public function getDataWithTypeGpDataProvider()
+    public function stdWrap_addPageCacheTagsAddsPageTagsDataProvider()
     {
         return array(
-            'Value in get-data' => array('onlyInGet', 'GetValue'),
-            'Value in post-data' => array('onlyInPost', 'PostValue'),
-            'Value in post-data overriding get-data' => array('inGetAndPost', 'ValueInPost'),
+            'No Tag' => array(
+                array(),
+                array('addPageCacheTags' => ''),
+            ),
+            'Two expectedTags' => array(
+                array('tag1', 'tag2'),
+                array('addPageCacheTags' => 'tag1,tag2'),
+            ),
+            'Two expectedTags plus one with stdWrap' => array(
+                array('tag1', 'tag2', 'tag3'),
+                array(
+                    'addPageCacheTags' => 'tag1,tag2',
+                    'addPageCacheTags.' => array('wrap' => '|,tag3')
+                ),
+            ),
         );
     }
 
     /**
-     * Checks if getData() works with type "gp"
-     *
+     * @param array $expectedTags
+     * @param array $configuration
      * @test
-     * @dataProvider getDataWithTypeGpDataProvider
+     * @dataProvider stdWrap_addPageCacheTagsAddsPageTagsDataProvider
      */
-    public function getDataWithTypeGp($key, $expectedValue)
+    public function stdWrap_addPageCacheTagsAddsPageTags(array $expectedTags, array $configuration)
     {
-        $_GET = array(
-            'onlyInGet' => 'GetValue',
-            'inGetAndPost' => 'ValueInGet',
-        );
-        $_POST = array(
-            'onlyInPost' => 'PostValue',
-            'inGetAndPost' => 'ValueInPost',
-        );
-        $this->assertEquals($expectedValue, $this->subject->getData('gp:' . $key));
+        $this->subject->stdWrap_addPageCacheTags('', $configuration);
+        $this->assertEquals($expectedTags, $this->frontendControllerMock->_get('pageCacheTags'));
     }
 
     /**
-     * Checks if getData() works with type "tsfe"
+     * Check if stdWrap_age works properly.
      *
-     * @test
-     */
-    public function getDataWithTypeTsfe()
-    {
-        $this->assertEquals($GLOBALS['TSFE']->metaCharset, $this->subject->getData('tsfe:metaCharset'));
-    }
-
-    /**
-     * Checks if getData() works with type "getenv"
+     * Show:
      *
-     * @test
-     */
-    public function getDataWithTypeGetenv()
-    {
-        $envName = $this->getUniqueId('frontendtest');
-        $value = $this->getUniqueId('someValue');
-        putenv($envName . '=' . $value);
-        $this->assertEquals($value, $this->subject->getData('getenv:' . $envName));
-    }
-
-    /**
-     * Checks if getData() works with type "getindpenv"
+     * - Delegates to calcAge.
+     * - Parameter 1 is the difference between $content and EXEC_TIME.
+     * - Parameter 2 is $conf['age'].
+     * - Returns the return value.
      *
      * @test
+     * @return void
      */
-    public function getDataWithTypeGetindpenv()
+    public function stdWrap_age()
     {
-        $this->subject->expects($this->once())->method('getEnvironmentVariable')
-            ->with($this->equalTo('SCRIPT_FILENAME'))->will($this->returnValue('dummyPath'));
-        $this->assertEquals('dummyPath', $this->subject->getData('getindpenv:SCRIPT_FILENAME'));
+        $now = 10;
+        $content = '9';
+        $conf = ['age' => $this->getUniqueId('age')];
+        $return = $this->getUniqueId('return');
+        $difference = $now - (int)$content;
+        $GLOBALS['EXEC_TIME'] = $now;
+        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
+            ->setMethods(['calcAge'])->getMock();
+        $subject
+            ->expects($this->once())
+            ->method('calcAge')
+            ->with($difference, $conf['age'])
+            ->willReturn($return);
+        $this->assertSame($return, $subject->stdWrap_age($content, $conf));
     }
 
     /**
-     * Checks if getData() works with type "field"
+     * Check if stdWrap_append works properly.
+     *
+     * Show:
+     *
+     * - Delegates to the method cObjGetSingle().
+     * - First parameter is $conf['append'].
+     * - Second parameter is $conf['append.'].
+     * - Third parameter is '/stdWrap/.append'.
+     * - Returns the return value appended to $content.
      *
      * @test
+     * @return void
      */
-    public function getDataWithTypeField()
+    public function stdWrap_append()
     {
-        $key = 'someKey';
-        $value = 'someValue';
-        $field = array($key => $value);
-
-        $this->assertEquals($value, $this->subject->getData('field:' . $key, $field));
+        $debugKey =  '/stdWrap/.append';
+        $content = $this->getUniqueId('content');
+        $conf = [
+            'append' => $this->getUniqueId('append'),
+            'append.' => [$this->getUniqueId('append.')],
+        ];
+        $return = $this->getUniqueId('return');
+        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
+            ->setMethods(['cObjGetSingle'])->getMock();
+        $subject
+            ->expects($this->once())
+            ->method('cObjGetSingle')
+            ->with($conf['append'], $conf['append.'], $debugKey)
+            ->willReturn($return);
+        $this->assertSame($content . $return,
+            $subject->stdWrap_append($content, $conf));
     }
 
     /**
-     * Checks if getData() works with type "field" of the field content
-     * is multi-dimensional (e.g. an array)
+     * Data provider for stdWrap_br
      *
-     * @test
+     * @return string[][] Order expected, given, xhtmlDoctype
      */
-    public function getDataWithTypeFieldAndFieldIsMultiDimensional()
+    public function stdWrapBrDataProvider()
     {
-        $key = 'somekey|level1|level2';
-        $value = 'somevalue';
-        $field = array('somekey' => array('level1' => array('level2' => 'somevalue')));
-
-        $this->assertEquals($value, $this->subject->getData('field:' . $key, $field));
+        return [
+            'no xhtml with LF in between' => [
+                'one<br>' . LF . 'two',
+                'one' . LF . 'two',
+                null
+            ],
+            'no xhtml with LF in between and around' => [
+                '<br>' . LF . 'one<br>' . LF . 'two<br>' . LF,
+                LF . 'one' . LF . 'two' . LF,
+                null
+            ],
+            'xhtml with LF in between' => [
+                'one<br />' . LF . 'two',
+                'one' . LF . 'two',
+                'xhtml_strict'
+            ],
+            'xhtml with LF in between and around' => [
+                '<br />' . LF . 'one<br />' . LF . 'two<br />' . LF,
+                LF . 'one' . LF . 'two' . LF,
+                'xhtml_strict'
+            ],
+        ];
     }
 
     /**
-     * Basic check if getData gets the uid of a file object
+     * Test that stdWrap_br works as expected.
      *
+     * @param string $expected The expected value.
+     * @param string $input The input value.
+     * @param string $xhtmlDoctype Xhtml document type.
+     * @return void
      * @test
+     * @dataProvider stdWrapBrDataProvider
      */
-    public function getDataWithTypeFileReturnsUidOfFileObject()
+    public function stdWrap_br($expected, $input, $xhtmlDoctype)
     {
-        $uid = $this->getUniqueId();
-        $file = $this->createMock(File::class);
-        $file->expects($this->once())->method('getUid')->will($this->returnValue($uid));
-        $this->subject->setCurrentFile($file);
-        $this->assertEquals($uid, $this->subject->getData('file:current:uid'));
+        $GLOBALS['TSFE']->xhtmlDoctype = $xhtmlDoctype;
+        $this->assertSame($expected, $this->subject->stdWrap_br($input));
     }
 
     /**
-     * Checks if getData() works with type "parameters"
+     * Data provider for stdWrap_brTag
      *
-     * @test
+     * @return array
      */
-    public function getDataWithTypeParameters()
+    public function stdWrapBrTagDataProvider()
     {
-        $key = $this->getUniqueId('someKey');
-        $value = $this->getUniqueId('someValue');
-        $this->subject->parameters[$key] = $value;
+        $noConfig = [];
+        $config1 = ['brTag' => '<br/>'];
+        $config2 = ['brTag' => '<br>'];
+        return [
+            'no config: one break at the beginning' => [LF . 'one' . LF . 'two', 'onetwo', $noConfig],
+            'no config: multiple breaks at the beginning' => [LF . LF . 'one' . LF . 'two', 'onetwo', $noConfig],
+            'no config: one break at the end' => ['one' . LF . 'two' . LF, 'onetwo', $noConfig],
+            'no config: multiple breaks at the end' => ['one' . LF . 'two' . LF . LF, 'onetwo', $noConfig],
 
-        $this->assertEquals($value, $this->subject->getData('parameters:' . $key));
+            'config1: one break at the beginning' => [LF . 'one' . LF . 'two', '<br/>one<br/>two', $config1],
+            'config1: multiple breaks at the beginning' => [LF . LF . 'one' . LF . 'two', '<br/><br/>one<br/>two', $config1],
+            'config1: one break at the end' => ['one' . LF . 'two' . LF, 'one<br/>two<br/>', $config1],
+            'config1: multiple breaks at the end' => ['one' . LF . 'two' . LF . LF, 'one<br/>two<br/><br/>', $config1],
+
+            'config2: one break at the beginning' => [LF . 'one' . LF . 'two', '<br>one<br>two', $config2],
+            'config2: multiple breaks at the beginning' => [LF . LF . 'one' . LF . 'two', '<br><br>one<br>two', $config2],
+            'config2: one break at the end' => ['one' . LF . 'two' . LF, 'one<br>two<br>', $config2],
+            'config2: multiple breaks at the end' => ['one' . LF . 'two' . LF . LF, 'one<br>two<br><br>', $config2],
+        ];
     }
 
     /**
-     * Checks if getData() works with type "register"
+     * Check if brTag works properly
      *
      * @test
+     * @dataProvider stdWrapBrTagDataProvider
      */
-    public function getDataWithTypeRegister()
+    public function stdWrap_brTag($input, $expected, $config)
     {
-        $key = $this->getUniqueId('someKey');
-        $value = $this->getUniqueId('someValue');
-        $GLOBALS['TSFE']->register[$key] = $value;
-
-        $this->assertEquals($value, $this->subject->getData('register:' . $key));
+        $this->assertEquals($expected, $this->subject->stdWrap_brTag($input, $config));
     }
 
     /**
-     * Checks if getData() works with type "level"
+     * Data provider for stdWrap_bytes.
      *
-     * @test
+     * @return array [$expect, $content, $conf]
      */
-    public function getDataWithTypeLevel()
+    public function stdWrap_bytesDataProvider()
     {
-        $rootline = array(
-            0 => array('uid' => 1, 'title' => 'title1'),
-            1 => array('uid' => 2, 'title' => 'title2'),
-            2 => array('uid' => 3, 'title' => 'title3'),
-        );
-
-        $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
-        $this->assertEquals(2, $this->subject->getData('level'));
+        return [
+            'value 1234 default' => [
+                '1.21 Ki', '1234',
+                ['labels' => '', 'base' => 0],
+            ],
+            'value 1234 si' => [
+                '1.23 k', '1234',
+                ['labels' => 'si', 'base' => 0],
+            ],
+            'value 1234 iec' => [
+                '1.21 Ki', '1234',
+                ['labels' => 'iec', 'base' => 0],
+            ],
+            'value 1234 a-i' => [
+                '1.23b', '1234',
+                ['labels' => 'a|b|c|d|e|f|g|h|i', 'base' => 1000],
+            ],
+            'value 1234 a-i invalid base' => [
+                '1.21b', '1234',
+                ['labels' => 'a|b|c|d|e|f|g|h|i', 'base' => 54],
+            ],
+            'value 1234567890 default' => [
+                '1.15 Gi', '1234567890',
+                ['labels' => '', 'base' => 0],
+            ]
+        ];
     }
 
     /**
-     * Checks if getData() works with type "global"
+     * Check if stdWrap_bytes works properly.
+     *
+     * Show:
+     *
+     * - Delegates to GeneralUtility::formatSize
+     * - Parameter 1 is $conf['bytes.'][labels'].
+     * - Parameter 2 is $conf['bytes.'][base'].
+     * - Returns the return value.
+     *
+     * Note: As PHPUnit can't mock static methods, the call to
+     *       GeneralUtility::formatSize can't be easily intercepted. The test
+     *       is done by testing input/output pairs instead. To not duplicate
+     *       the testing of formatSize just a few smoke tests are done here.
      *
      * @test
+     * @dataProvider stdWrap_bytesDataProvider
+     * @param string $expect The expected output.
+     * @param string $content The given input.
+     * @param array $conf The given configuration for 'bytes.'.
+     * @return void
      */
-    public function getDataWithTypeGlobal()
+    public function stdWrap_bytes($expect, $content, $conf)
     {
-        $this->assertEquals($GLOBALS['TSFE']->metaCharset, $this->subject->getData('global:TSFE|metaCharset'));
+        $locale = 'en_US.UTF-8';
+        if (!setlocale(LC_NUMERIC, $locale)) {
+            $this->markTestSkipped('Locale ' . $locale . ' is not available.');
+        }
+        $conf = ['bytes.' => $conf];
+        $this->assertSame($expect,
+            $this->subject->stdWrap_bytes($content, $conf));
     }
 
     /**
-     * Checks if getData() works with type "leveltitle"
+     * Check if stdWrap_cObject works properly.
+     *
+     * Show:
+     *
+     * - Delegates to the method cObjGetSingle().
+     * - First parameter is $conf['cObject'].
+     * - Second parameter is $conf['cObject.'].
+     * - Third parameter is '/stdWrap/.cObject'.
+     * - Returns the return.
      *
      * @test
+     * @return void
      */
-    public function getDataWithTypeLeveltitle()
+    public function stdWrap_cObject()
     {
-        $rootline = array(
-            0 => array('uid' => 1, 'title' => 'title1'),
-            1 => array('uid' => 2, 'title' => 'title2'),
-            2 => array('uid' => 3, 'title' => ''),
-        );
-
-        $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
-        $this->assertEquals('', $this->subject->getData('leveltitle:-1'));
-        // since "title3" is not set, it will slide to "title2"
-        $this->assertEquals('title2', $this->subject->getData('leveltitle:-1,slide'));
+        $debugKey =  '/stdWrap/.cObject';
+        $conf = [
+            'cObject' => $this->getUniqueId('cObject'),
+            'cObject.' => [$this->getUniqueId('cObject.')],
+        ];
+        $return = $this->getUniqueId('return');
+        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
+            ->setMethods(['cObjGetSingle'])->getMock();
+        $subject
+            ->expects($this->once())
+            ->method('cObjGetSingle')
+            ->with($conf['cObject'], $conf['cObject.'], $debugKey)
+            ->willReturn($return);
+        $this->assertSame($return,
+            $subject->stdWrap_cObject('discard', $conf));
     }
 
     /**
-     * Checks if getData() works with type "levelmedia"
+     * Data provider for stdWrap_cacheRead
      *
-     * @test
+     * @return array Order: expect, input, conf, times, with, will
      */
-    public function getDataWithTypeLevelmedia()
+    public function stdWrap_cacheReadDataProvider()
     {
-        $rootline = array(
-            0 => array('uid' => 1, 'title' => 'title1', 'media' => 'media1'),
-            1 => array('uid' => 2, 'title' => 'title2', 'media' => 'media2'),
-            2 => array('uid' => 3, 'title' => 'title3', 'media' => ''),
-        );
-
-        $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
-        $this->assertEquals('', $this->subject->getData('levelmedia:-1'));
-        // since "title3" is not set, it will slide to "title2"
-        $this->assertEquals('media2', $this->subject->getData('levelmedia:-1,slide'));
+        $cacheConf = [$this->getUniqueId('cache.')];
+        $conf = ['cache.' => $cacheConf];
+        return [
+            'no conf' => [
+                'content', 'content', [],
+                0, null, null,
+            ],
+            'no cache. conf' => [
+                'content', 'content', ['otherConf' => 1],
+                0, null, null,
+            ],
+            'non-cached simulation' => [
+                'content', 'content', $conf,
+                1, $cacheConf, false,
+            ],
+            'cached simulation' => [
+                'cachedContent', 'content', $conf,
+                1, $cacheConf, 'cachedContent',
+            ],
+        ];
     }
 
     /**
-     * Checks if getData() works with type "leveluid"
+     * Check if stdWrap_cacheRead works properly.
+     *
+     * - the method branches correctly
+     * - getFromCache is called to fetch from cache
+     * - $conf['cache.'] is passed on as parameter
      *
      * @test
+     * @dataProvider stdWrap_cacheReadDataProvider
+     * @param string $expect Expected result.
+     * @param string $input Given input string.
+     * @param array $conf Property 'cache.'
+     * @param int $times Times called mocked method.
+     * @param array $with Parameter passed to mocked method.
+     * @param string|false $will Return value of mocked method.
+     * @return void
      */
-    public function getDataWithTypeLeveluid()
+    public function stdWrap_cacheRead(
+        $expect, $input, $conf, $times, $with, $will)
     {
-        $rootline = array(
-            0 => array('uid' => 1, 'title' => 'title1'),
-            1 => array('uid' => 2, 'title' => 'title2'),
-            2 => array('uid' => 3, 'title' => 'title3'),
-        );
-
-        $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
-        $this->assertEquals(3, $this->subject->getData('leveluid:-1'));
-        // every element will have a uid - so adding slide doesn't really make sense, just for completeness
-        $this->assertEquals(3, $this->subject->getData('leveluid:-1,slide'));
+        $subject = $this->getAccessibleMock(
+            ContentObjectRenderer::class, ['getFromCache']);
+        $subject
+            ->expects($this->exactly($times))
+            ->method('getFromCache')
+            ->with($with)
+            ->willReturn($will);
+        $this->assertSame($expect,
+            $subject->stdWrap_cacheRead($input, $conf));
     }
 
     /**
-     * Checks if getData() works with type "levelfield"
+     * Data provider for stdWrap_case test
      *
-     * @test
+     * @return array
      */
-    public function getDataWithTypeLevelfield()
+    public function stdWrap_caseDataProvider()
     {
-        $rootline = array(
-            0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
-            1 => array('uid' => 2, 'title' => 'title2', 'testfield' => 'field2'),
-            2 => array('uid' => 3, 'title' => 'title3', 'testfield' => ''),
+        return array(
+            'lower case text to upper' => array(
+                '<span>text</span>',
+                array(
+                    'case' => 'upper',
+                ),
+                '<span>TEXT</span>',
+            ),
+            'upper case text to lower' => array(
+                '<span>TEXT</span>',
+                array(
+                    'case' => 'lower',
+                ),
+                '<span>text</span>',
+            ),
+            'capitalize text' => array(
+                '<span>this is a text</span>',
+                array(
+                    'case' => 'capitalize',
+                ),
+                '<span>This Is A Text</span>',
+            ),
+            'ucfirst text' => array(
+                '<span>this is a text</span>',
+                array(
+                    'case' => 'ucfirst',
+                ),
+                '<span>This is a text</span>',
+            ),
+            'lcfirst text' => array(
+                '<span>This is a Text</span>',
+                array(
+                    'case' => 'lcfirst',
+                ),
+                '<span>this is a Text</span>',
+            ),
+            'uppercamelcase text' => array(
+                '<span>this_is_a_text</span>',
+                array(
+                    'case' => 'uppercamelcase',
+                ),
+                '<span>ThisIsAText</span>',
+            ),
+            'lowercamelcase text' => array(
+                '<span>this_is_a_text</span>',
+                array(
+                    'case' => 'lowercamelcase',
+                ),
+                '<span>thisIsAText</span>',
+            ),
         );
-
-        $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
-        $this->assertEquals('', $this->subject->getData('levelfield:-1,testfield'));
-        $this->assertEquals('field2', $this->subject->getData('levelfield:-1,testfield,slide'));
     }
 
     /**
-     * Checks if getData() works with type "fullrootline"
-     *
+     * @param string|NULL $content
+     * @param array $configuration
+     * @param string $expected
+     * @dataProvider stdWrap_caseDataProvider
      * @test
      */
-    public function getDataWithTypeFullrootline()
+    public function stdWrap_case($content, array $configuration, $expected)
     {
-        $rootline1 = array(
-            0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
-        );
-        $rootline2 = array(
-            0 => array('uid' => 1, 'title' => 'title1', 'testfield' => 'field1'),
-            1 => array('uid' => 2, 'title' => 'title2', 'testfield' => 'field2'),
-            2 => array('uid' => 3, 'title' => 'title3', 'testfield' => 'field3'),
-        );
-
-        $GLOBALS['TSFE']->tmpl->rootLine = $rootline1;
-        $GLOBALS['TSFE']->rootLine = $rootline2;
-        $this->assertEquals('field2', $this->subject->getData('fullrootline:-1,testfield'));
+        $result = $this->subject->stdWrap_case($content, $configuration);
+        $this->assertEquals($expected, $result);
     }
 
     /**
-     * Checks if getData() works with type "date"
+     * Check if stdWrap_char works properly.
      *
      * @test
+     * @return void
      */
-    public function getDataWithTypeDate()
+    public function stdWrap_char()
     {
-        $format = 'Y-M-D';
-        $defaultFormat = 'd/m Y';
-
-        $this->assertEquals(date($format, $GLOBALS['EXEC_TIME']), $this->subject->getData('date:' . $format));
-        $this->assertEquals(date($defaultFormat, $GLOBALS['EXEC_TIME']), $this->subject->getData('date'));
+        $input = 'discarded';
+        $expected = 'C';
+        $this->assertEquals($expected, $this->subject->stdWrap_char($input, ['char' => '67']));
     }
 
     /**
-     * Checks if getData() works with type "page"
+     * Check if stdWrap_crop works properly.
+     *
+     * Show:
+     *
+     * - Delegates to method listNum.
+     * - Parameter 1 is $content.
+     * - Parameter 2 is $conf['crop'].
+     * - Returns the return value.
      *
      * @test
+     * @return void
      */
-    public function getDataWithTypePage()
+    public function stdWrap_crop()
     {
-        $uid = rand();
-        $GLOBALS['TSFE']->page['uid'] = $uid;
-        $this->assertEquals($uid, $this->subject->getData('page:uid'));
+        $content = $this->getUniqueId('content');
+        $conf = [
+            'crop' => $this->getUniqueId('crop'),
+            'crop.' => $this->getUniqueId('not used'),
+        ];
+        $return = $this->getUniqueId('return');
+        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
+            ->setMethods(['crop'])->getMock();
+        $subject
+            ->expects($this->once())
+            ->method('crop')
+            ->with($content, $conf['crop'])
+            ->willReturn($return);
+        $this->assertSame($return,
+            $subject->stdWrap_crop($content, $conf));
     }
 
     /**
-     * Checks if getData() works with type "current"
+     * Check if stdWrap_cropHTML works properly.
+     *
+     * Show:
+     *
+     * - Delegates to method cropHTML.
+     * - Parameter 1 is $content.
+     * - Parameter 2 is $conf['cropHTML'].
+     * - Returns the return value.
      *
      * @test
+     * @return void
      */
-    public function getDataWithTypeCurrent()
+    public function stdWrap_cropHTML()
     {
-        $key = $this->getUniqueId('someKey');
-        $value = $this->getUniqueId('someValue');
-        $this->subject->data[$key] = $value;
-        $this->subject->currentValKey = $key;
-        $this->assertEquals($value, $this->subject->getData('current'));
+        $content = $this->getUniqueId('content');
+        $conf = [
+            'cropHTML' => $this->getUniqueId('cropHTML'),
+            'cropHTML.' => $this->getUniqueId('not used'),
+        ];
+        $return = $this->getUniqueId('return');
+        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
+            ->setMethods(['cropHTML'])->getMock();
+        $subject
+            ->expects($this->once())
+            ->method('cropHTML')
+            ->with($content, $conf['cropHTML'])
+            ->willReturn($return);
+        $this->assertSame($return,
+            $subject->stdWrap_cropHTML($content, $conf));
     }
 
     /**
-     * Checks if getData() works with type "db"
+     * Data provider for stdWrap_csConv
      *
-     * @test
+     * @return array Order expected, input, conf
      */
-    public function getDataWithTypeDb()
+    public function stdWrap_csConvDataProvider()
     {
-        $dummyRecord = array('uid' => 5, 'title' => 'someTitle');
-
-        $GLOBALS['TSFE']->sys_page->expects($this->atLeastOnce())->method('getRawRecord')->with('tt_content', '106')->will($this->returnValue($dummyRecord));
-        $this->assertEquals($dummyRecord['title'], $this->subject->getData('db:tt_content:106:title'));
+        return [
+            'empty string from ISO-8859-15' => [
+                '',
+                iconv('UTF-8', 'ISO-8859-15', ''),
+                ['csConv' => 'ISO-8859-15']
+            ],
+            'empty string from BIG-5' => [
+                '',
+                mb_convert_encoding('', 'BIG-5'),
+                ['csConv' => 'BIG-5']
+            ],
+            '"0" from ISO-8859-15' => [
+                '0',
+                iconv('UTF-8', 'ISO-8859-15', '0'),
+                ['csConv' => 'ISO-8859-15']
+            ],
+            '"0" from BIG-5' => [
+                '0',
+                mb_convert_encoding('0', 'BIG-5'),
+                ['csConv' => 'BIG-5']
+            ],
+            'euro symbol from ISO-88859-15' => [
+                '€',
+                iconv('UTF-8', 'ISO-8859-15', '€'),
+                ['csConv' => 'ISO-8859-15']
+            ],
+            'good morning from BIG-5' => [
+                '早安',
+                mb_convert_encoding('早安', 'BIG-5'),
+                ['csConv' => 'BIG-5']
+            ],
+        ];
     }
 
     /**
-     * Checks if getData() works with type "lll"
+     * Check if stdWrap_csConv works properly.
      *
      * @test
+     * @dataProvider stdWrap_csConvDataProvider
+     * @param string $expected The expected value.
+     * @param string $value The input value.
+     * @param array $conf Property: csConv
+     * @return void
      */
-    public function getDataWithTypeLll()
+    public function stdWrap_csConv($expected, $input, $conf)
     {
-        $key = $this->getUniqueId('someKey');
-        $value = $this->getUniqueId('someValue');
-        $language = $this->getUniqueId('someLanguage');
-        $GLOBALS['TSFE']->LL_labels_cache[$language]['LLL:' . $key] = $value;
-        $GLOBALS['TSFE']->lang = $language;
-
-        $this->assertEquals($value, $this->subject->getData('lll:' . $key));
+        $this->assertSame($expected,
+            $this->subject->stdWrap_csConv($input, $conf));
     }
 
     /**
-     * Checks if getData() works with type "path"
+     * Check if stdWrap_current works properly.
+     *
+     * Show:
+     *
+     * - current is returned from $this->data
+     * - the key is stored in $this->currentValKey
+     * - the key defaults to 'currentValue_kidjls9dksoje'
      *
      * @test
+     * @return void
      */
-    public function getDataWithTypePath()
+    public function stdWrap_current()
     {
-        $filenameIn = $this->getUniqueId('someValue');
-        $filenameOut = $this->getUniqueId('someValue');
-        $this->templateServiceMock->expects($this->atLeastOnce())->method('getFileName')->with($filenameIn)->will($this->returnValue($filenameOut));
-        $this->assertEquals($filenameOut, $this->subject->getData('path:' . $filenameIn));
+        $data = [
+            'currentValue_kidjls9dksoje' => 'default',
+            'currentValue_new' => 'new',
+        ];
+        $this->subject->_set('data', $data);
+        $this->assertSame('currentValue_kidjls9dksoje',
+            $this->subject->_get('currentValKey'));
+        $this->assertSame('default',
+            $this->subject->stdWrap_current('discarded', ['discarded']));
+        $this->subject->_set('currentValKey', 'currentValue_new');
+        $this->assertSame('new',
+            $this->subject->stdWrap_current('discarded', ['discarded']));
     }
 
     /**
-     * Checks if getData() works with type "parentRecordNumber"
+     * Data provider for stdWrap_data.
      *
-     * @test
+     * @return array [$expect, $data, $alt]
      */
-    public function getDataWithTypeParentRecordNumber()
+    public function stdWrap_dataDataProvider()
     {
-        $recordNumber = rand();
-        $this->subject->parentRecordNumber = $recordNumber;
-        $this->assertEquals($recordNumber, $this->subject->getData('cobj:parentRecordNumber'));
+        $data = [$this->getUniqueId('data')];
+        $alt = [$this->getUniqueId('alternativeData')];
+        return [
+            'default' => [$data, $data, ''],
+            'alt is array' => [$alt, $data, $alt],
+            'alt is empty array' => [[], $data, []],
+            'alt null' => [$data, $data, null],
+            'alt string' => [$data, $data, 'xxx'],
+            'alt int' => [$data, $data, 1],
+            'alt bool' => [$data, $data, true],
+        ];
     }
 
     /**
-     * Checks if getData() works with type "debug:rootLine"
+     * Checks that stdWrap_data works properly.
+     *
+     * Show:
+     *
+     * - Delegates to method getData.
+     * - Parameter 1 is $conf['data'].
+     * - Parameter 2 is property data by default.
+     * - Parameter 2 is property alternativeData, if set as array.
+     * - Property alternativeData is always unset to ''.
+     * - Returns the return value.
      *
      * @test
+     * @dataProvider stdWrap_dataDataProvider
+     * @param mixed $expect Expect either $data or $alternativeData.
+     * @param array $data The data.
+     * @param mixed $alt The alternativeData.
+     * @return void
      */
-    public function getDataWithTypeDebugRootline()
+    public function stdWrap_data($expect, $data, $alt)
     {
-        $rootline = array(
-            0 => array('uid' => 1, 'title' => 'title1'),
-            1 => array('uid' => 2, 'title' => 'title2'),
-            2 => array('uid' => 3, 'title' => ''),
-        );
-        $expectedResult = 'array(3items)0=>array(2items)uid=>1(integer)title=>"title1"(6chars)1=>array(2items)uid=>2(integer)title=>"title2"(6chars)2=>array(2items)uid=>3(integer)title=>""(0chars)';
-        $GLOBALS['TSFE']->tmpl->rootLine = $rootline;
-
-        DebugUtility::useAnsiColor(false);
-        $result = $this->subject->getData('debug:rootLine');
-        $cleanedResult = str_replace("\r", '', $result);
-        $cleanedResult = str_replace("\n", '', $cleanedResult);
-        $cleanedResult = str_replace("\t", '', $cleanedResult);
-        $cleanedResult = str_replace(' ', '', $cleanedResult);
-
-        $this->assertEquals($expectedResult, $cleanedResult);
+        $conf = ['data' => $this->getUniqueId('conf.data')];
+        $return = $this->getUniqueId('return');
+        $subject = $this->getAccessibleMock(
+            ContentObjectRenderer::class, ['getData']);
+        $subject->_set('data', $data);
+        $subject->_set('alternativeData', $alt);
+        $subject
+            ->expects($this->once())
+            ->method('getData')
+            ->with($conf['data'], $expect)
+            ->willReturn($return);
+        $this->assertSame($return, $subject->stdWrap_data('discard', $conf));
+        $this->assertSame('', $subject->_get('alternativeData'));
     }
 
     /**
-     * Checks if getData() works with type "debug:fullRootLine"
+     * Check that stdWrap_dataWrap works properly.
      *
-     * @test
+     * Show:
+     *
+     *  - Delegates to method dataWrap.
+     *  - Parameter 1 is $content.
+     *  - Parameter 2 is $conf['dataWrap'].
+     *  - Returns the return value.
+     *
+     *  @test
+     *  @return void.
      */
-    public function getDataWithTypeDebugFullRootline()
+    public function stdWrap_dataWrap()
     {
-        $rootline = array(
-            0 => array('uid' => 1, 'title' => 'title1'),
-            1 => array('uid' => 2, 'title' => 'title2'),
-            2 => array('uid' => 3, 'title' => ''),
-        );
-        $expectedResult = 'array(3items)0=>array(2items)uid=>1(integer)title=>"title1"(6chars)1=>array(2items)uid=>2(integer)title=>"title2"(6chars)2=>array(2items)uid=>3(integer)title=>""(0chars)';
-        $GLOBALS['TSFE']->rootLine = $rootline;
-
-        DebugUtility::useAnsiColor(false);
-        $result = $this->subject->getData('debug:fullRootLine');
-        $cleanedResult = str_replace("\r", '', $result);
-        $cleanedResult = str_replace("\n", '', $cleanedResult);
-        $cleanedResult = str_replace("\t", '', $cleanedResult);
-        $cleanedResult = str_replace(' ', '', $cleanedResult);
-
-        $this->assertEquals($expectedResult, $cleanedResult);
+        $content = $this->getUniqueId('content');
+        $conf = [
+            'dataWrap' => $this->getUniqueId('dataWrap'),
+            'dataWrap.' => [$this->getUniqueId('not used')],
+        ];
+        $return = $this->getUniqueId('return');
+        $subject = $this->getMockBuilder(ContentObjectRenderer::class)
+            ->setMethods(['dataWrap'])->getMock();
+        $subject
+            ->expects($this->once())
+            ->method('dataWrap')
+            ->with($content, $conf['dataWrap'])
+            ->willReturn($return);
+        $this->assertSame($return,
+            $subject->stdWrap_dataWrap($content, $conf));
     }
 
     /**
-     * Checks if getData() works with type "debug:data"
+     * Data provider for the stdWrap_date test
      *
-     * @test
+     * @return array [$expect, $content, $conf, $now]
      */
-    public function getDataWithTypeDebugData()
+    public function stdWrap_dateDataProvider()
     {
-        $key = $this->getUniqueId('someKey');
-        $value = $this->getUniqueId('someValue');
-        $this->subject->data = array($key => $value);
-
-        $expectedResult = 'array(1item)' . $key . '=>"' . $value . '"(' . strlen($value) . 'chars)';
-
-        DebugUtility::useAnsiColor(false);
-        $result = $this->subject->getData('debug:data');
-        $cleanedResult = str_replace("\r", '', $result);
-        $cleanedResult = str_replace("\n", '', $cleanedResult);
-        $cleanedResult = str_replace("\t", '', $cleanedResult);
-        $cleanedResult = str_replace(' ', '', $cleanedResult);
-
-        $this->assertEquals($expectedResult, $cleanedResult);
+        // Fictive execution time: 2015-10-02 12:00
+        $now =  1443780000;
+        return [
+            'given timestamp' => [
+                '02.10.2015',
+                $now,
+                ['date' => 'd.m.Y'],
+                $now
+            ],
+            'empty string' => [
+                '02.10.2015',
+                '',
+                ['date' => 'd.m.Y'],
+                $now
+            ],
+            'testing null' => [
+                '02.10.2015',
+                null,
+                ['date' => 'd.m.Y'],
+                $now
+            ],
+            'given timestamp return GMT' => [
+                '02.10.2015 10:00:00',
+                $now,
+                [
+                    'date' => 'd.m.Y H:i:s',
+                    'date.' => ['GMT' => true],
+                ],
+                $now
+            ]
+        ];
     }
 
     /**
-     * Checks if getData() works with type "debug:register"
+     * Check if stdWrap_date works properly.
      *
      * @test
+     * @dataProvider stdWrap_dateDataProvider
+     * @param string $expected The expected output.
+     * @param mixed $content The given input.
+     * @param array $conf The given configuration.
+     * @param int $now Fictive execution time.
+     * @return void
      */
-    public function getDataWithTypeDebugRegister()
+    public function stdWrap_date($expected, $content, $conf, $now)
     {
-        $key = $this->getUniqueId('someKey');
-        $value = $this->getUniqueId('someValue');
-        $GLOBALS['TSFE']->register = array($key => $value);
-
-        $expectedResult = 'array(1item)' . $key . '=>"' . $value . '"(' . strlen($value) . 'chars)';
-
-        DebugUtility::useAnsiColor(false);
-        $result = $this->subject->getData('debug:register');
-        $cleanedResult = str_replace("\r", '', $result);
-        $cleanedResult = str_replace("\n", '', $cleanedResult);
-        $cleanedResult = str_replace("\t", '', $cleanedResult);
-        $cleanedResult = str_replace(' ', '', $cleanedResult);
-
-        $this->assertEquals($expectedResult, $cleanedResult);
+        $GLOBALS['EXEC_TIME'] = $now;
+        $this->assertEquals($expected,
+            $this->subject->stdWrap_date($content, $conf));
     }
 
     /**
-     * Checks if getData() works with type "data:page"
+     * Check if stdWrap_debug works properly.
      *
      * @test
+     * @return void
      */
-    public function getDataWithTypeDebugPage()
+    public function stdWrap_debug()
     {
-        $uid = rand();
-        $GLOBALS['TSFE']->page = array('uid' => $uid);
-
-        $expectedResult = 'array(1item)uid=>' . $uid . '(integer)';
-
-        DebugUtility::useAnsiColor(false);
-        $result = $this->subject->getData('debug:page');
-        $cleanedResult = str_replace("\r", '', $result);
-        $cleanedResult = str_replace("\n", '', $cleanedResult);
-        $cleanedResult = str_replace("\t", '', $cleanedResult);
-        $cleanedResult = str_replace(' ', '', $cleanedResult);
-
-        $this->assertEquals($expectedResult, $cleanedResult);
+        $expect = '<pre>&lt;p class=&quot;class&quot;&gt;&lt;br/&gt;'
+            . '&lt;/p&gt;</pre>';
+        $content = '<p class="class"><br/></p>';
+        $this->assertSame($expect, $this->subject->stdWrap_debug($content));
     }
 
     /**
-     * @test
+     * Data provider for stdWrap_doubleBrTag
+     *
+     * @return array Order expected, input, config
      */
-    public function getTreeListReturnsChildPageUids()
+    public function stdWrapDoubleBrTagDataProvider()
     {
-        $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTgetSingleRow')->with('treelist')->will($this->returnValue(null));
-        $GLOBALS['TSFE']->sys_page
-            ->expects($this->any())
-            ->method('getRawRecord')
-            ->will(
-                $this->onConsecutiveCalls(
-                    array('uid' => 17),
-                    array('uid' => 321),
-                    array('uid' => 719),
-                    array('uid' => 42)
-                )
-            );
-
-        $GLOBALS['TSFE']->sys_page->expects($this->any())->method('getMountPointInfo')->will($this->returnValue(null));
-        $GLOBALS['TYPO3_DB']
-            ->expects($this->any())
-            ->method('exec_SELECTgetRows')
-            ->will(
-                $this->onConsecutiveCalls(
-                    array(
-                        array('uid' => 321)
-                    ),
-                    array(
-                        array('uid' => 719)
-                    ),
-                    array(
-                        array('uid' => 42)
-                    )
-                )
-            );
-        // 17 = pageId, 5 = recursionLevel, 0 = begin (entry to recursion, internal), TRUE = do not check enable fields
-        // 17 is positive, we expect 17 NOT to be included in result
-        $result = $this->subject->getTreeList(17, 5, 0, true);
-        $expectedResult = '42,719,321';
-        $this->assertEquals($expectedResult, $result);
+        return [
+            'no config: void input' => [
+                '',
+                '',
+                [],
+            ],
+            'no config: single break' => [
+                'one' . LF . 'two',
+                'one' . LF . 'two',
+                [],
+            ],
+            'no config: double break' => [
+                'onetwo',
+                'one' . LF . LF . 'two',
+                [],
+            ],
+            'no config: double break with whitespace' => [
+                'onetwo',
+                'one' . LF . TAB . ' ' . TAB . ' ' . LF . 'two',
+                [],
+            ],
+            'no config: single break around' => [
+                LF . 'one' . LF,
+                LF . 'one' . LF,
+                [],
+            ],
+            'no config: double break around' => [
+                'one',
+                LF . LF . 'one' . LF . LF,
+                [],
+            ],
+            'empty string: double break around' => [
+                'one',
+                LF . LF . 'one' . LF . LF,
+                ['doubleBrTag' => ''],
+            ],
+            'br tag: double break' => [
+                'one<br/>two',
+                'one' . LF . LF . 'two',
+                ['doubleBrTag' => '<br/>'],
+            ],
+            'br tag: double break around' => [
+                '<br/>one<br/>',
+                LF . LF . 'one' . LF . LF,
+                ['doubleBrTag' => '<br/>'],
+            ],
+            'double br tag: double break around' => [
+                '<br/><br/>one<br/><br/>',
+                LF . LF . 'one' . LF . LF,
+                ['doubleBrTag' => '<br/><br/>'],
+            ],
+        ];
     }
 
     /**
+     * Check if doubleBrTag works properly
+     *
      * @test
+     * @dataProvider stdWrapDoubleBrTagDataProvider
+     * @param string $expected The expected value.
+     * @param string $input The input value.
+     * @param array $config The property 'doubleBrTag'.
+     * @return void
      */
-    public function getTreeListReturnsChildPageUidsAndOriginalPidForNegativeValue()
+    public function stdWrap_doubleBrTag($expected, $input, $config)
     {
-        $GLOBALS['TYPO3_DB']->expects($this->any())->method('exec_SELECTgetSingleRow')->with('treelist')->will($this->returnValue(null));
-        $GLOBALS['TSFE']->sys_page
-            ->expects($this->any())
-            ->method('getRawRecord')
-            ->will(
-                $this->onConsecutiveCalls(
-                    array('uid' => 17),
-                    array('uid' => 321),
-                    array('uid' => 719),
-                    array('uid' => 42)
-                )
-            );
-
-        $GLOBALS['TSFE']->sys_page->expects($this->any())->method('getMountPointInfo')->will($this->returnValue(null));
-        $GLOBALS['TYPO3_DB']
-            ->expects($this->any())
-            ->method('exec_SELECTgetRows')
-            ->will(
-                $this->onConsecutiveCalls(
-                    array(
-                        array('uid' => 321)
-                    ),
-                    array(
-                        array('uid' => 719)
-                    ),
-                    array(
-