diff --git a/Documentation/Concept.rst b/Documentation/Concept.rst
index 7d3bf589c9200975486ae8b2c7ded999d4671af1..d6d7dbde60ef0247c61951b4a04e9c5a8b63c871 100644
--- a/Documentation/Concept.rst
+++ b/Documentation/Concept.rst
@@ -89,98 +89,100 @@ QFQ Keywords (Bodytext)
 
 **All of these parameters are optional.**
 
-+-------------------------+---------------------------------------------------------------------------------+
-| Name                    | Explanation                                                                     |
-+=========================+=================================================================================+
-| form                    | | Formname.                                                                     |
-|                         | | Static: **form = person**                                                     |
-|                         | | By SIP: **form = {{form:SE}}**                                                |
-|                         | | By SQL: **form = {{SELECT c.form FROM Config AS c WHERE c.id={{a:C}} }}**     |
-+-------------------------+---------------------------------------------------------------------------------+
-| r                       | | <record id>. The form will load the record with the specified id.             |
-|                         | | Static: **r = 123**                                                           |
-|                         | | By SQL: **r = {{SELECT ...}}**                                                |
-|                         | | If not specified, the SIP parameter 'r' is used.                              |
-+-------------------------+---------------------------------------------------------------------------------+
-| dbIndex                 | E.g. `dbIndex = {{indexQfq:Y}}` Select a DB index. Only necessary if a          |
-|                         | different than the standard DB should be used.                                  |
-+-------------------------+---------------------------------------------------------------------------------+
-| debugShowBodyText       | If='1' and :ref:`configuration`:*showDebugInfo: yes*, shows a                   |
-|                         | tooltip with bodytext                                                           |
-+-------------------------+---------------------------------------------------------------------------------+
-| sqlLog                  | Overwrites :ref:`configuration`: :ref:`SQL_LOG` . Only affects `Report`,        |
-|                         | not `Form`.                                                                     |
-+-------------------------+---------------------------------------------------------------------------------+
-| sqlLogMode              | Overwrites :ref:`configuration`: :ref:`SQL_LOG_MODE<SQL_LOG_MODE>` .            |
-|                         | Only affects `Report`, not `Form`.                                              |
-+-------------------------+---------------------------------------------------------------------------------+
-| render                  | See :ref:`report-render`. Overwrites :ref:`configuration`: render.              |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.fbeg            | Start token for every field (=column)                                           |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.fend            | End token for every field (=column)                                             |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.fsep            | Separator token between fields (=columns)                                       |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.fskipwrap       | Skip wrapping (via fbeg, fsep, fend) of named columns. Comma separated list of  |
-|                         | column id's (starting at 1). See also the special column name '_noWrap' to      |
-|                         | suppress wrapping.                                                              |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.shead           | Static start token for whole <level>, independent if records are selected       |
-|                         | Shown before `head`.                                                            |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.stail           | Static end token for whole <level>, independent if records are selected.        |
-|                         | Shown after `tail`.                                                             |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.head            | Dynamic start token for whole <level>. Only if at least one record is select.   |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.tail            | Dynamic end token for whole <level>. Only if at least one record is select.     |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.rbeg            | Start token for row.                                                            |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.rbgd            | Alternating (per row) token.                                                    |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.rend            | End token for row. Will be rendered **before** subsequent levels are processed  |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.renr            | End token for row. Will be rendered **after** subsequent levels are processed   |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.rsep            | Seperator token between rows                                                    |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.sql             | SQL Query                                                                       |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.twig            | Twig Template                                                                   |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.althead         | If <level>.sql has no rows selected (empty), these token will be rendered.      |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.altsql          | If <level>.sql has no rows selected (empty) or affected (delete, update, insert)|
-|                         | the <altsql> will be fired. Note: Sub queries of <level> are not fired, even if |
-|                         | <altsql> selects some rows.                                                     |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.content         | | *show* (default): content of current and sub level are directly shown.        |
-|                         | | *hide*: content of current and sub levels are **stored** and not shown.       |
-|                         | | *hideLevel*: content of current and sub levels are **stored** and only sub    |
-|                         | | levels are shown.                                                             |
-|                         | | *store*: content of current and sub levels are **stored** and shown.          |
-|                         | | To retrieve the content: `{{<level>.line.content}}`.                          |
-|                         | | See :ref:`syntax-of-report`                                                   |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.line.count      | Current row index. Will be replaced before the query is fired in case of        |
-|                         | ``<level>`` is an outer/previous level or it will be replaced after a query is  |
-|                         | fired in case ``<level>`` is the current level.                                 |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.line.total      | Total rows (MySQL ``num_rows`` for *SELECT* and *SHOW*, MySQL ``affected_rows`` |
-|                         | for *UPDATE* and *INSERT*.                                                      |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.line.insertId   | Last insert id for *INSERT*.                                                    |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.line.content    | Show content of `<level>` (content have to be stored via <level>.content=....)  |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.line.altCount   | Like 'line.count' but for 'alt' query.                                          |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.line.altTotal   | Like 'line.total' but for 'alt' query.                                          |
-+-------------------------+---------------------------------------------------------------------------------+
-| <level>.line.altInsertId| Like 'line.insertId' but for 'alt' query.                                       |
-+-------------------------+---------------------------------------------------------------------------------+
++--------------------------------+---------------------------------------------------------------------------------+
+| Name                           | Explanation                                                                     |
++================================+=================================================================================+
+| form                           | | Formname.                                                                     |
+|                                | | Static: **form = person**                                                     |
+|                                | | By SIP: **form = {{form:SE}}**                                                |
+|                                | | By SQL: **form = {{SELECT c.form FROM Config AS c WHERE c.id={{a:C}} }}**     |
++--------------------------------+---------------------------------------------------------------------------------+
+| r                              | | <record id>. The form will load the record with the specified id.             |
+|                                | | Static: **r = 123**                                                           |
+|                                | | By SQL: **r = {{SELECT ...}}**                                                |
+|                                | | If not specified, the SIP parameter 'r' is used.                              |
++--------------------------------+---------------------------------------------------------------------------------+
+| dbIndex                        | E.g. `dbIndex = {{indexQfq:Y}}` Select a DB index. Only necessary if a          |
+|                                | different than the standard DB should be used.                                  |
++--------------------------------+---------------------------------------------------------------------------------+
+| debugShowBodyText              | If='1' and :ref:`configuration`:*showDebugInfo: yes*, shows a                   |
+|                                | tooltip with bodytext                                                           |
++--------------------------------+---------------------------------------------------------------------------------+
+| sqlLog                         | Overwrites :ref:`configuration`: :ref:`SQL_LOG` . Only affects `Report`,        |
+|                                | not `Form`.                                                                     |
++--------------------------------+---------------------------------------------------------------------------------+
+| sqlLogMode                     | Overwrites :ref:`configuration`: :ref:`SQL_LOG_MODE<SQL_LOG_MODE>` .            |
+|                                | Only affects `Report`, not `Form`.                                              |
++--------------------------------+---------------------------------------------------------------------------------+
+| render                         | See :ref:`report-render`. Overwrites :ref:`configuration`: render.              |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.fbeg                   | Start token for every field (=column)                                           |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.fend                   | End token for every field (=column)                                             |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.fsep                   | Separator token between fields (=columns)                                       |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.fskipwrap              | Skip wrapping (via fbeg, fsep, fend) of named columns. Comma separated list of  |
+|                                | column id's (starting at 1). See also the :ref:`special-column-names` '_noWrap' |
+|                                | to suppress wrapping.                                                           |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.shead                  | Static start token for whole <level>, independent if records are selected       |
+|                                | Shown before `head`.                                                            |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.stail                  | Static end token for whole <level>, independent if records are selected.        |
+|                                | Shown after `tail`.                                                             |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.head                   | Dynamic start token for whole <level>. Only if at least one record is select.   |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.tail                   | Dynamic end token for whole <level>. Only if at least one record is select.     |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.rbeg                   | Start token for row.                                                            |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.rbgd                   | Alternating (per row) token.                                                    |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.rend                   | End token for row. Will be rendered **before** subsequent levels are processed  |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.renr                   | End token for row. Will be rendered **after** subsequent levels are processed   |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.rsep                   | Seperator token between rows                                                    |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.sql                    | SQL Query                                                                       |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.twig                   | Twig Template                                                                   |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.althead                | If <level>.sql has no rows selected (empty), these token will be rendered.      |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.altsql                 | If <level>.sql has no rows selected (empty) or affected (delete, update, insert)|
+|                                | the <altsql> will be fired. Note: Sub queries of <level> are not fired, even if |
+|                                | <altsql> selects some rows.                                                     |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level>.content                | | *show* (default): content of current and sub level are directly shown.        |
+|                                | | *hide*: content of current and sub levels are **stored** and not shown.       |
+|                                | | *hideLevel*: content of current and sub levels are **stored** and only sub    |
+|                                | | levels are shown.                                                             |
+|                                | | *store*: content of current and sub levels are **stored** and shown.          |
+|                                | | To retrieve the content: `{{<level>.line.content}}`.                          |
+|                                | | See :ref:`syntax-of-report`                                                   |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level|alias>.line.count       | Current row index. Will be replaced before the query is fired in case of        |
+|                                | ``<level>``/``<alias>`` is an outer/previous level or it will be replaced after |
+|                                | a query is fired in case ``<level>``/``<alias>`` is the current level.          |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level|alias>.line.total       | Total rows (MySQL ``num_rows`` for *SELECT* and *SHOW*, MySQL ``affected_rows`` |
+|                                | for *UPDATE* and *INSERT*.                                                      |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level|alias>.line.insertId    | Last insert id for *INSERT*.                                                    |
+| <alias>.line.insertId          |                                                                                 |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level|alias>.line.content     | Show content of `<level>`/`<alias>` (content have to be stored via              |
+|                                | <level>.content=... or <alias>.content=...).                                    |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level|alias>.line.altCount    | Like 'line.count' but for 'alt' query.                                          |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level|alias>.line.altTotal    | Like 'line.total' but for 'alt' query.                                          |
++--------------------------------+---------------------------------------------------------------------------------+
+| <level|alias>.line.altInsertId | Like 'line.insertId' but for 'alt' query.                                       |
++--------------------------------+---------------------------------------------------------------------------------+
 
 .. _`report-render`:
 
diff --git a/Documentation/Report.rst b/Documentation/Report.rst
index e4cf107554758fb7c7d76377d573c7b6858d5d73..9ac07ad5b681bc94767079f34ef71e6206af5903 100644
--- a/Documentation/Report.rst
+++ b/Documentation/Report.rst
@@ -398,8 +398,8 @@ To get the same result, the following is also possible::
                                     '|p:/export',
                                     '|t:Download') AS _pdf
 
-Nesting of levels
-^^^^^^^^^^^^^^^^^
+Nesting of levels: `numeric`
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Levels can be nested. E.g.::
 
@@ -417,6 +417,58 @@ This is equal to::
     10.5.sql = SELECT ...
     10.5.head = ...
 
+Nesting of levels: `alias`
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Levels can be nested without levels. E.g.::
+
+  {
+    sql = SELECT ...
+    {
+        sql = SELECT ...
+        head = ...
+    }
+  }
+
+This is equal to::
+
+  1.sql = SELECT ...
+  1.2.sql = SELECT ...
+  1.2.head = ...
+
+Levels are automatically numbered from top to bottom.
+
+An alias can be used instead of levels. E.g.::
+
+  myAlias {
+    sql = SELECT ...
+    nextAlias {
+        sql = SELECT ...
+        head = ...
+    }
+  }
+
+This is also equal to::
+
+  1.sql = SELECT ...
+  1.2.sql = SELECT ...
+  1.2.head = ...
+
+.. important::
+
+Allowed characters for an alias: [a-zA-Z0-9_-].
+
+.. important::
+
+The first level determines whether report notation `numeric` or `alias` is used. Using an alias or no level triggers
+report notation `alias`. It requires the use of delimiters throughout the report. A combination with the notation
+'10.sql = ...' is not possible.
+
+.. important::
+
+Report notation `alias` does not require that each level be assigned an alias. If an alias is used, it must be on the
+same line as the opening delimiter.
+
 Leading / trailing spaces
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -532,7 +584,20 @@ Example 'level'::
     10.5.20.sql = SELECT '{{10.pId}}'
     10.10.sql = SELECT '{{10.pId}}'
 
+Example 'alias'::
 
+  myAlias {
+    sql = SELECT p.id AS _pId, p.name FROM Person AS p
+    myAlias2 {
+        sql = SELECT adr.city, 'dummy' AS _pId FROM Address AS adr WHERE adr.pId={{10.pId}}
+        myAlias3 {
+            sql = SELECT '{{myAlias.pId}}'
+        }
+    }
+    myAlias4 {
+        sql = SELECT '{{myAlias.pId}}'
+    }
+  }
 Notes to the level:
 
 +-------------+------------------------------------------------------------------------------------------------------------------------+
@@ -546,6 +611,8 @@ Notes to the level:
 +-------------+------------------------------------------------------------------------------------------------------------------------+
 | Child       |The level *30* has one child and child child: *30.5* and *30.5.1*                                                       |
 +-------------+------------------------------------------------------------------------------------------------------------------------+
+| Alias       |A variable that can be assigned to a level and used to retrieve its values.                                             |
++-------------+------------------------------------------------------------------------------------------------------------------------+
 | Example     | *10*, *20*, *30*, *50** are root level and will be completely processed one after each other.                          |
 |             | *30.5* will be executed as many times as *30* has row numbers.                                                         |
 |             | *30.5.1*  will be executed as many times as *30.5* has row numbers.                                                    |
diff --git a/Documentation/Variable.rst b/Documentation/Variable.rst
index 12b6552e24d8e900a60e6e21bf92f154130c028f..423adc417caa87f3d9ed69cced48d99ea7635824 100644
--- a/Documentation/Variable.rst
+++ b/Documentation/Variable.rst
@@ -410,11 +410,11 @@ Example::
 Row column variables
 --------------------
 
-Syntax:  *{{<level>.<column>}}*
+Syntax:  *{{<level>.<column>}}* or *{{<alias>.<column>}}*
 
 Only used in report to access outer columns. See :ref:`access-column-values` and :ref:`syntax-of-report`.
 
-There might be name conflicts between VarName / SQL keywords and <line identifier>. QFQ checks first for *<level>*,
+There might be name conflicts between VarName / SQL keywords and <line identifier>. QFQ checks first for *<level>* and *<alias>*,
 than for *SQL keywords* and than for *VarNames* in stores.
 
 All types might be nested with each other. There is no limit of nesting variables.
diff --git a/extension/Classes/Core/BodytextParser.php b/extension/Classes/Core/BodytextParser.php
index 2b5394e383fdd34607fbd27b20bd20f5e90b30ef..6febadae7de01fa881b22fc3606561f23b93fcdf 100644
--- a/extension/Classes/Core/BodytextParser.php
+++ b/extension/Classes/Core/BodytextParser.php
@@ -49,6 +49,8 @@ class BodytextParser {
                 json_encode([ERROR_MESSAGE_TO_USER => 'Report: Missing close delimiter', ERROR_MESSAGE_TO_DEVELOPER => $bodyText]), ERROR_MISSING_CLOSE_DELIMITER);
         }
 
+        unset($this->reportLinesTemp);
+
         return $bodyText;
     }
 
@@ -64,6 +66,7 @@ class BodytextParser {
 
     private function trimAndRemoveCommentAndEmptyLine($bodytext, &$nestingOpen, &$nestingClose) {
         $data = array();
+        $reportLines = array();
 
         $src = explode(PHP_EOL, $bodytext);
         if ($src === false) {
@@ -72,22 +75,27 @@ class BodytextParser {
 
         $firstLine = trim($src[0]);
 
-        foreach ($src as $row) {
+        foreach ($src as $key => $row) {
             $row = trim($row);
 
             if ($row === '' || $row[0] === '#') {
                 continue;
             }
             $data[] = $row;
+
+            // Increment $key to match line from tt-content record
+            $key++;
+            $reportLines[] = $key;
         }
 
+        $this->reportLinesTemp = $reportLines;
         $this->setNestingToken($firstLine, $nestingOpen, $nestingClose);
 
         return implode(PHP_EOL, $data);
     }
 
     /**
-     * Set the 'nesting token for this tt-conten record. Valid tokens are {}, <>, [], ().
+     * Set the nesting token for this tt-content record. Valid tokens are {}, <>, [], ().
      * If the first line of bodytext is a comment line and the last char of that line is a valid token: set that one.
      * If not: set {} as nesting token.
      *
@@ -170,7 +178,9 @@ class BodytextParser {
      */
     private function joinLine($bodyText, $nestingOpen, $nestingClose) {
         $data = array();
+        $reportLines = $this->reportLinesTemp;
         $bodytextArray = explode(PHP_EOL, $bodyText);
+        $firstToken = '';
 
         $nestingOpenRegexp = $nestingOpen;
         if ($nestingOpen === '(' || $nestingOpen === '[') {
@@ -179,7 +189,7 @@ class BodytextParser {
 
         $full = '';
         $joinDelimiter = ' ';
-        foreach ($bodytextArray as $row) {
+        foreach ($bodytextArray as $key => $row) {
 
             // Line end with '\'?
             if (substr($row, -1) == '\\') {
@@ -192,8 +202,11 @@ class BodytextParser {
             if (($row == $nestingOpen || $row == $nestingClose)
                 || (1 === preg_match('/^\d+(\.\d+)*(\s*' . $nestingOpenRegexp . ')?$/', $row))
                 || (1 === preg_match('/^(\d+\.)*(' . TOKEN_VALID_LIST . ')\s*=/', $row))
-            ) {
 
+                // Report notation 'alias'
+                // E.g. myAlias { ...
+                || (1 === preg_match('/^[\w-]*(\s*' . $nestingOpenRegexp . ')+$/', $row))
+            ) {
                 // if there is already something: save this.
                 if ($full !== '') {
                     $data[] = $full;
@@ -202,9 +215,26 @@ class BodytextParser {
                 // start new line
                 $full = $row;
 
+                // This later determines the notation mode
+                // Possible values for $firstToken: '10', '10.20', '10.sql=...', '10.head=...', 'myAlias {', 'myAlias{'
+                // Values such as 'form={{form:SE}}' are valid but not parsed as a level/alias.
+                if (empty($firstToken) && 1 !== preg_match('/^(' . TOKEN_VALID_LIST . ')\s*=/', $row)) {
+                    $firstToken = (strpos($row, $nestingOpen) !== false) ? trim(substr($row, 0, strpos($row, $nestingOpen))) : $row;
+                }
+
+            // If the open delimiter is missing while using an alias, this is necessary to get the correct error message later on
+            // Starts a new line if the previous line only contained '}'
+            // It prevents that the lines '}' and 'myAlias' will be joined
+            } elseif ($full === $nestingClose) {
+                $data[] = $full;
+
+                // start new line
+                $full = $row;
             } else {
                 // continue row: concat - the space is necessary to join SQL statements correctly: 'SELECT ... FROM ... WHERE ... AND\np.id=...'  - here a 'AND' and 'p.id' need a space.
                 $full .= $joinDelimiter . $row;
+                // remove unused elements
+                unset($reportLines[$key]);
             }
 
             $joinDelimiter = $joinDelimiterNext;
@@ -215,6 +245,29 @@ class BodytextParser {
             $data[] = $full;
         }
 
+        $reportLines = array_values($reportLines);
+
+        // Combines line numbers ($key) from tt-content record with content ($value) from corresponding line: [line => content]
+        // E.g. [0 => 4, 1 => "[", 2 => "sql = SELECT ...", 3 => "[", 4 => "sql = SELECT ...", ...]: line 0 is empty
+        foreach($reportLines as $key => $value) {
+            $reportLines[$value] = $data[$key];
+        }
+
+        // Removes every element that is not an SQL statement: [line => content]
+        // E.g. [2 => "sql = SELECT ...", 4 => "sql = SELECT ...", ...]
+        foreach($reportLines as $key => $value) {
+            if (strpos($value, '=') !== false) {
+                $arr = explode('"', $value,2);
+                if (strpos($arr[0], TOKEN_SQL) === false) {
+                    unset($reportLines[$key]);
+                }
+            } else {
+                unset($reportLines[$key]);
+            }
+        }
+        $this->reportLinesTemp = $reportLines;
+        $this->firstToken = $firstToken;
+
         return implode(PHP_EOL, $data);
     }
 
@@ -237,7 +290,14 @@ class BodytextParser {
             $nestingClose = '\\' . $nestingClose;
         }
 
-        $bodytext = preg_replace('/^((\d+)(\.\d+)*\s*)?(' . $nestingOpen . ')$/m', '$1' . NESTING_TOKEN_OPEN, $bodytext);
+        // Report notation 'numeric'
+        // E.g. 10 { ...
+        // $bodytext = preg_replace('/^((\d+)(\.\d+)*\s*)?(' . $nestingOpen . ')$/m', '$1' . NESTING_TOKEN_OPEN, $bodytext);
+
+        // Report notation 'alias'
+        // E.g. myAlias { ...
+        $bodytext = preg_replace('/^((\s*[\w-]*\s*)|((\s*\d+)(\.\d+)*\s*))?(' . $nestingOpen . ')/m', '$1' . NESTING_TOKEN_OPEN, $bodytext);
+
         $bodytext = preg_replace('/^' . $nestingClose . '$/m', '$1' . NESTING_TOKEN_CLOSE, $bodytext);
 
         return $bodytext;
@@ -277,6 +337,28 @@ class BodytextParser {
         $result = $bodytext;
         $posFirstClose = strpos($result, NESTING_TOKEN_CLOSE);
 
+        // Default: Report notation 'numeric'
+        $notationMode = TOKEN_NOTATION_NUMERIC;
+        $levels = null;
+        $reportLines = $this->reportLinesTemp;
+        $alias = null;
+        $aliases = null;
+        $firstToken = $this->firstToken;
+
+        // No first token or non-numeric first token implies report notation 'alias'
+        // It supports auto numbering of blocks and aliases
+        if (empty($firstToken) || (1 !== preg_match('/^([0-9\._-])+$/', $firstToken) && !strpos($firstToken, '='))) {
+            $notationMode = TOKEN_NOTATION_ALIAS;
+            $aliases = array();
+            $levels = array();
+            $maxLevel = substr_count($bodytext, NESTING_TOKEN_CLOSE);
+
+            // Generate an array containing all levels, e.g. [1,2,3,...]
+            for ($x = 1; $x <= $maxLevel; $x++) {
+                array_push($levels, $x);
+            }
+        }
+
         while ($posFirstClose !== false) {
             $posMatchOpen = strrpos(substr($result, 0, $posFirstClose), NESTING_TOKEN_OPEN);
 
@@ -285,7 +367,6 @@ class BodytextParser {
                 throw new \UserFormException(
                     json_encode([ERROR_MESSAGE_TO_USER => 'Missing open delimiter', ERROR_MESSAGE_TO_DEVELOPER => "Missing open delimiter: $result"]),
                     ERROR_MISSING_OPEN_DELIMITER);
-
             }
 
             $pre = substr($result, 0, $posMatchOpen);
@@ -304,11 +385,57 @@ class BodytextParser {
             $levelStartPos = ($levelStartPos === false) ? 0 : $levelStartPos + 1;  // Skip PHP_EOL
 
             $level = trim(substr($pre, $levelStartPos));
-//            if($level==='') {
-//                $pre=
-//            }
-            // remove 'level' from last line
-            $pre = substr($pre, 0, $levelStartPos);
+
+            // Report notation 'alias'
+            // Count open brackets in front of current level
+            // E.g. current $level = 2, then $index = 1, because there is 1 in front
+            $index = substr_count($pre, NESTING_TOKEN_OPEN);
+
+            // Check for report notation 'alias'
+            if($notationMode === TOKEN_NOTATION_ALIAS) {
+                $aliasLevel = null;
+
+                // $firstToken === $level checks if we are in the 'first loop'
+                // $adjustLength is used later while extracting a substring and has to be zero in the first loop
+                $adjustLength = ($firstToken === $level && strpos($pre, PHP_EOL) === false) ? 0 : 1;
+
+                // If the $level, from which the $alias is extracted, nothing gets saved
+                // Allowed characters: [a-zA-Z0-9\._-]
+                // '.' is only allowed to detect report notation 'numeric'. This throws an error later on.
+                $alias = (1 === preg_match('/^[a-zA-Z0-9\._-]+$/', $level) || $level === '') ? $level : null;
+
+                // If no alias is set, then nothing gets saved
+                if (!empty($alias)) {
+                    // Construct absolute $level of the current $alias
+                    // E.g. 1.2.3.
+                    for ($x = 0; $x <= $index; $x++) {
+                        $aliasLevel .= (isset($levels[$x])) ? $levels[$x] . '.' : null;
+                    }
+
+                    // Trailing '.' gets removed from $level: E.g. 1.2.3
+                    // $level is saved together with $alias: [level => alias]
+                    $aliases[substr($aliasLevel, 0, strlen($aliasLevel) - 1)] = $alias;
+                }
+
+                // Current $level can now be extracted from $levels [1,2,3,...]
+                $level = (isset($levels[$index])) ? $levels[$index] : null;
+
+                // Remove current $level from $levels [1,3,...]
+                // This works because opening brackets get removed from $pre after every level
+                unset($levels[$index]);
+
+                // Reset keys
+                $levels = array_values($levels);
+
+                // Removes alias or level added by user to continue auto numbering scheme
+                // E.g. User input: {\nsql = SELECT ...\n}\nmyAlias{\nsql = SELECT ...\n}
+                // $pre = "1.sql = SELECT ...\nmyAlias" -> $pre = "1.sql = SELECT ...\n"
+                $pre = substr($pre,0, strrpos($pre, PHP_EOL) + $adjustLength);
+            } else {
+
+                // Remove 'level' from last line
+                $pre = substr($pre, 0, $levelStartPos);
+            }
 
             // Split nested content in single rows
             $lines = explode(PHP_EOL, $match);
@@ -326,6 +453,33 @@ class BodytextParser {
 //        $result = str_replace('#&]_#', '}', $result);
 //        $result = Support::decryptDoubleCurlyBraces($result);
 
+        $resultArr = explode(PHP_EOL, $result);
+
+        // $value (previously SQL statement) gets replaced by its level: [line => level]
+        // E.g. [2 => 1, 4 => 1.2, ...]:
+        foreach ($reportLines as $keyLines => $valueLines) {
+            foreach ($resultArr as $keyResult => $valueResult) {
+                if (strpos($valueResult, '=')) {
+                    $arr = explode("=", $valueResult, 2);
+                    if (strpos($arr[0], TOKEN_SQL) !== false) {
+                        $reportLines[$keyLines] = str_replace('.' . TOKEN_SQL , '', trim($arr[0]));
+                    } else {
+                        continue;
+                    }
+                } else {
+                    continue;
+                }
+                unset($resultArr[$keyResult]);
+                break;
+            }
+        }
+
+        // Array is flipped: [level => line]
+        // E.g. [1 => 2, 1.2 => 4, ...]
+        $this->reportLines = array_flip($reportLines);
+
+        $this->aliases = $aliases;
+
         return $result;
     }
 
diff --git a/extension/Classes/Core/Constants.php b/extension/Classes/Core/Constants.php
index 45db92060a4cb19d934f559f00758e9ebc86b1c1..5f4f2e5c5b7321148c89eac2c7ec74ebdd855275 100644
--- a/extension/Classes/Core/Constants.php
+++ b/extension/Classes/Core/Constants.php
@@ -254,6 +254,7 @@ const ERROR_INVALID_SAVE_PDF_FILENAME = 1410;
 const ERROR_TWIG_COLUMN_NOT_UNIQUE = 1411;
 const ERROR_DOUBLE_DEFINITION = 1412;
 const ERROR_INVALID_SAVE_ZIP_FILENAME = 1413;
+const ERROR_NUMERIC_ALIAS = 1414;
 
 // Upload
 const ERROR_UPLOAD = 1500;
@@ -523,6 +524,7 @@ const TYPO3_PAGE_DESCRIPTION = 'pageDescription';
 const TYPO3_PAGE_KEYWORDS = 'pageKeywords';
 const TYPO3_PAGE_NAV_TITLE = 'pageNavTitle';
 const TYPO3_VERSION = 't3Version';
+const TYPO3_TOKEN_REPORT_LINE = 'parsed';
 
 const TYPO3_PAGE_LANGUAGE = SESSION_PAGE_LANGUAGE;
 const TYPO3_PAGE_LANGUAGE_PATH = SESSION_PAGE_LANGUAGE_PATH;
@@ -771,6 +773,7 @@ const SYSTEM_REPORT_COLUMN_VALUE = 'reportColumnValue'; // Value of SQL-column p
 const SYSTEM_REPORT_FULL_LEVEL = 'reportFullLevel'; // Full level of current report row. E.g.: 10.20.1. Used for error reports.
 const SYSTEM_MESSAGE_DEBUG = 'messageDebug';
 const SYSTEM_DOWNLOAD_POPUP = 'hasDownloadPopup'; // Marker which is set to 'true' if there is at least one Download Link rendered
+const SYSTEM_REPORT_LINE = 'reportLine';
 const DOWNLOAD_POPUP_REQUEST = 'true';
 const DOWNLOAD_POPUP_REPLACE_TEXT = '#downloadPopupReplaceText#';
 const DOWNLOAD_POPUP_REPLACE_TITLE = '#downloadPopupReplaceTitle#';
@@ -1766,6 +1769,9 @@ const TOKEN_DB_INDEX = F_DB_INDEX;
 const TOKEN_DB_INDEX_LC = 'dbindex';
 const TOKEN_CONTENT = 'content';
 const TOKEN_REPORT_FILE = 'file';
+const TOKEN_ALIAS = 'alias';
+const TOKEN_NOTATION_NUMERIC = 'numeric';
+const TOKEN_NOTATION_ALIAS = 'alias';
 
 const TOKEN_VALID_LIST = 'sql|function|twig|head|althead|altsql|tail|shead|stail|rbeg|rend|renr|rsep|fbeg|fend|fsep|fskipwrap|rbgd|debug|form|r|debugShowBodyText|dbIndex|sqlLog|sqlLogMode|content|render';
 
@@ -2194,6 +2200,7 @@ const EXCEPTION_REPORT_COLUMN_INDEX = 'Report column index'; // Keyname of SQL-c
 const EXCEPTION_REPORT_COLUMN_NAME = 'Report column name'; // Keyname of SQL-column processed at the moment.
 const EXCEPTION_REPORT_COLUMN_VALUE = 'Report column value'; // Keyname of SQL-column processed at the moment.
 const EXCEPTION_REPORT_FULL_LEVEL = 'Report level key';
+const EXCEPTION_REPORT_LINE = 'Report line';
 
 const EXCEPTION_SIP = 'current sip';
 const EXCEPTION_PAGE_ID = 'Page Id';
diff --git a/extension/Classes/Core/Exception/DbException.php b/extension/Classes/Core/Exception/DbException.php
index 9ee26dec9f50df5b6515a4db06084356f6fe9d63..4eb1d7b8154b1631faada0d0ef4286a04af27fff 100644
--- a/extension/Classes/Core/Exception/DbException.php
+++ b/extension/Classes/Core/Exception/DbException.php
@@ -61,6 +61,7 @@ class DbException extends AbstractException {
         $this->messageArrayDebug[EXCEPTION_SQL_FINAL] = Store::getVar(SYSTEM_SQL_FINAL, STORE_SYSTEM);
         $this->messageArrayDebug[EXCEPTION_SQL_PARAM_ARRAY] = Store::getVar(SYSTEM_SQL_PARAM_ARRAY, STORE_SYSTEM);
         $this->messageArrayDebug[EXCEPTION_REPORT_FULL_LEVEL] = Store::getVar(SYSTEM_REPORT_FULL_LEVEL, STORE_SYSTEM);
+        $this->messageArrayDebug[EXCEPTION_REPORT_LINE] = Store::getVar(SYSTEM_REPORT_LINE, STORE_SYSTEM);
 
         return parent::formatException();
     }
diff --git a/extension/Classes/Core/QuickFormQuery.php b/extension/Classes/Core/QuickFormQuery.php
index 643e13fc8db07b3336cc5597b2aa29a1b2de934e..0c89d7571a11223d7588d6427b9fa8789138f5e0 100644
--- a/extension/Classes/Core/QuickFormQuery.php
+++ b/extension/Classes/Core/QuickFormQuery.php
@@ -172,6 +172,20 @@ class QuickFormQuery {
         $this->store->setVar(TYPO3_TT_CONTENT_UID, $t3data[T3DATA_UID], STORE_TYPO3);
         $this->store->setVar(TYPO3_TT_CONTENT_SUBHEADER, $t3data[T3DATA_SUBHEADER], STORE_TYPO3);
 
+        // Adds line numbers together with level to TYPO3 store
+        // E.g. [parsed.1 => 2, parsed.1.2 => 4, ...]
+        foreach ($btp->reportLines as $key => $value) {
+            $this->store->setVar(TYPO3_TOKEN_REPORT_LINE . '.' . $key, $value, STORE_TYPO3);
+        }
+
+        // Check if aliases were used
+        if (isset($btp->aliases)) {
+            // Adds aliases together with level to TYPO3 store
+            // E.g. [alias.1 => "myAlias", alias.1.2 => "mySecondAlias", ...]
+            foreach ($btp->aliases as $key => $value) {
+                $this->store->setVar(TOKEN_ALIAS. '.' . $key, $value, STORE_TYPO3);
+            }
+        }
 
         $this->dbIndexData = $this->store->getVar(SYSTEM_DB_INDEX_DATA, STORE_SYSTEM);
         $this->dbIndexQfq = $this->store->getVar(SYSTEM_DB_INDEX_QFQ, STORE_SYSTEM);
diff --git a/extension/Classes/Core/Report/Report.php b/extension/Classes/Core/Report/Report.php
index c5dad53c847bcc7ace1a5be6d0b1507dcf12cfe1..332b4c614c99065e6ccb0c6159252c80eef67cca 100644
--- a/extension/Classes/Core/Report/Report.php
+++ b/extension/Classes/Core/Report/Report.php
@@ -323,6 +323,27 @@ class Report {
         if (!empty($this->frArray[$index])) {
             throw new \UserReportException ("Double definition: $index is defined more than once.", ERROR_DOUBLE_DEFINITION);
         }
+
+        $alias = TOKEN_ALIAS . "." . $level;
+        $alias = $this->store->getVar($alias, STORE_TYPO3);
+
+        // Throw exception if alias is numeric
+        // E.g. 10, 10.20
+        if (1 === preg_match('/^([0-9\.])+$/', $alias)) {
+            throw new \UserReportException ("Numeric alias detected: $alias cannot be used in report notation 'alias'", ERROR_NUMERIC_ALIAS);
+        }
+
+        // Throw exception if this alias was already used
+        if (!empty($alias)) {
+
+            // Checks if this alias was already used by a different level
+            if (!empty($this->aliases) && in_array($alias, $this->aliases) && array_search($alias, $this->aliases) != $level) {
+                throw new \UserReportException ("Double definition: $alias is defined more than once.", ERROR_DOUBLE_DEFINITION);
+            } else {
+                $this->aliases[$level] = $alias;
+            }
+        }
+
         // store complete line reformatted in frArray
         $this->frArray[$index] = $value;
 
@@ -575,9 +596,13 @@ class Report {
             // Set debug, if one is specified else keep the parent one.
             $lineDebug = $this->getValueParentDefault(TOKEN_DEBUG, $full_super_level, $fullLevel, $cur_level, 0);
 
+            // Get line number of current SQL statement from TYPO3 store
+            $reportLine = $this->store->getVar(TYPO3_TOKEN_REPORT_LINE . '.' . $fullLevel, STORE_TYPO3);
+
             // Prepare Error reporting
             $this->store->setVar(SYSTEM_SQL_RAW, $this->frArray[$fullLevel . "." . TOKEN_SQL], STORE_SYSTEM);
             $this->store->setVar(SYSTEM_REPORT_FULL_LEVEL, $fullLevel, STORE_SYSTEM);
+            $this->store->setVar(SYSTEM_REPORT_LINE, $reportLine, STORE_SYSTEM);
 
             // Prepare SQL: replace variables. Actual 'line.total' or 'line.count' will recalculated: don't replace them now!
             unset($this->variables->resultArray[$fullLevel . ".line."][LINE_TOTAL]);
diff --git a/extension/Classes/Core/Report/Variables.php b/extension/Classes/Core/Report/Variables.php
index 834614f3fc08d8e3a8ed1fd575ac74a18bbb2b36..8a15f04da39752aab3f8c87529dd249ba013fd55 100644
--- a/extension/Classes/Core/Report/Variables.php
+++ b/extension/Classes/Core/Report/Variables.php
@@ -25,6 +25,7 @@ namespace IMATHUZH\Qfq\Core\Report;
 
 use IMATHUZH\Qfq\Core\Evaluate;
 use IMATHUZH\Qfq\Core\Helper\OnString;
+use IMATHUZH\Qfq\Core\Store\Store;
 use IMATHUZH\Qfq\Core\Store\T3Info;
 
 
@@ -78,7 +79,14 @@ class Variables {
         // Process all {{x[.x].name}}
 //        $str = preg_replace_callback('/{{\s*(([0-9]+.)+[a-zA-Z0-9_.]+)\s*}}/', 'self::replaceVariables', $text);
 //        $str = preg_replace_callback('/{{\s*(([0-9]+.)+[a-zA-Z0-9_.]+)(:.*)*\s*}}/', 'self::replaceVariables', $text);
-        $str = preg_replace_callback('/{{\s*(([0-9]+.)+[a-zA-Z0-9_.]+)(:[a-zA-Z-]*)*\s*}}/', 'self::replaceVariables', $text);
+
+        // Report notation 'numeric'
+        // E.g. {{10.line.count}}, {{10.20.line.count}}
+        // $str = preg_replace_callback('/{{\s*(([0-9]+.)+[a-zA-Z0-9_.]+)(:[a-zA-Z-]*)*\s*}}/', 'self::replaceVariables', $text);
+
+        // Report notation 'alias'
+        // E.g. {{myAlias.line.count}}, {{myAlias10.line.count}}, {{10myAlias.line.count}}
+        $str = preg_replace_callback('/{{\s*(([a-zA-Z0-9_-]*[0-9.]*.)[.][a-zA-Z0-9_.]+)+(:[a-zA-Z-]*)*\s*}}/', 'self::replaceVariables', $text);
 
         // Try the Stores
         return $this->eval->parse($str, null, null, $dummyStack, $dummyStore, $frCmd);
@@ -96,12 +104,41 @@ class Variables {
      */
     public function replaceVariables($matches): string {
 
-        // $matches[0]: {{10.20.<columnname>::u:}}
-        // $matches[1]: 10.20.<columnname>
-        // $matches[2]: 10.20
-        // $matches[3]: ::u:
+        // Report notation 'numeric
+        //  $matches[0]: {{10.20.<columnname>::u}}
+        //  $matches[1]: 10.20.<columnname>
+        //  $matches[2]: 10.20
+        //  $matches[3]: :u
+
+        // Report notation 'alias'
+        //  $matches[0]: {{myAlias.<columnname>::u}}
+        //  $matches[1]: myAlias.<columnname>
+        //  $matches[2]: myAlias
+        //  $matches[3]: :u
         $data = $matches[0];
 
+        // Isolate first token as possible alias
+        $alias = strtok($matches[2], ".");
+
+        // No numeric value implies that an alias was used
+        if (!is_numeric($alias)) {
+            // Get typo3 store
+            // Aliases are saved like [alias.1 => "myAlias", alias.1.2 => "mySecondAlias", ...]
+            $storeT3 = Store::getStore(STORE_TYPO3);
+            // Check for matching value of $alias
+            $match = array_search($alias, $storeT3, true);
+
+            // Replacement only if matching alias was found
+            if (!empty($match)) {
+                // Extract level from key
+                $level = substr($match, strpos($match, '.') + 1);
+
+                $matches[0] = str_replace($alias, $level, $matches[0]);
+                $matches[1] = str_replace($alias, $level, $matches[1]);
+                $matches[2] = $level . '.';
+            }
+        }
+
         // index of last '.'
         $pos = strrpos($matches[1], ".");
         if ($pos !== false) {
@@ -116,6 +153,15 @@ class Variables {
                     $arr = explode(':', $matches[3]);
                     $data = OnString::escape($arr[1] ?? '', $this->resultArray[$fullLevel][$varName], $rcFlagWipe);
                 }
+            // This is for the specific case, that the variable references its own level
+            // E.g. myAlias { \n sql = SELECT '{{myAlias.line.count}}' \n }
+            // Note: This is only used for line.count and line.total, because non-existing variables must stay unchanged
+            // E.g. myAlias { \n sql = SELECT 1 \n } \n { \n sql = SELECT '{{myAlias.varName}}' \n }
+            // '{{myAlias.varName}}' will not be changed to '{{1.varName}}'
+            } elseif($varName === LINE_COUNT || $varName === LINE_TOTAL) {
+                // myAlias needs to be replaced by the level
+                // E.g. {{1.2.line.count}}
+                $data = $matches[0];
             }
         }
 
diff --git a/extension/Tests/Unit/Core/BodytextParserTest.php b/extension/Tests/Unit/Core/BodytextParserTest.php
index b069ba46657ff45d209644b50d5d7ef48c448d62..09487b62e073748079d053840bc378b20a88078c 100644
--- a/extension/Tests/Unit/Core/BodytextParserTest.php
+++ b/extension/Tests/Unit/Core/BodytextParserTest.php
@@ -27,12 +27,40 @@ final class BodytextParserTest extends TestCase {
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Simple row, nothing to remove
+        $given = "{\nsql = SELECT 'Hello World'\n}";
+        $expected = "1.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Simple row, nothing to remove
+        $given = "myAlias {\nsql = SELECT 'Hello World'\n}";
+        $expected = "1.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Several rows, remove all but one
         $given = "\n#some comments\n10.sql = SELECT 'Hello World'\n\n    \n   #more comment";
         $expected = "10.sql = SELECT 'Hello World'";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Several rows, remove all but one
+        $given = "\n#some comments\n{\nsql = SELECT 'Hello World'\n\n    \n   #more comment\n}";
+        $expected = "1.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Several rows, remove all but one
+        $given = "\n#some comments\nmyAlias {\nsql = SELECT 'Hello World'\n\n    \n   #more comment\n}";
+        $expected = "1.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Several rows, all to remove
         $given = "\n#some comments\n\n\n    \n   #more comment";
         $expected = "";
@@ -45,66 +73,220 @@ final class BodytextParserTest extends TestCase {
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Join a line
+        $given = "\n{\nsql = SELECT 'Hello World',\n'more content'\n      WHERE help=1\n}";
+        $expected = "1.sql = SELECT 'Hello World', 'more content' WHERE help=1";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Join a line
+        $given = "\n    myAlias     {\nsql = SELECT 'Hello World',\n'more content'\n      WHERE help=1\n}";
+        $expected = "1.sql = SELECT 'Hello World', 'more content' WHERE help=1";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Join several lines, incl. form
         $given = "\n10.sql = SELECT 'Hello World',\n'more content'\n      WHERE help=1\n 20.head = <table>\n 30.sql     =   SELECT\n col1,\n col2, \n col3\n  # Query stops here\nform = Person\n";
         $expected = "10.sql = SELECT 'Hello World', 'more content' WHERE help=1\n20.head = <table>\n30.sql     =   SELECT col1, col2, col3\nform = Person";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Join several lines, incl. form
+        $given = "\n{\nsql = SELECT 'Hello World',\n'more content'\n      WHERE help=1\n}\n{\nhead = <table>\n}\n{\nsql     =   SELECT\n col1,\n col2, \n col3\n  # Query stops here\n}\nform = Person\n";
+        $expected = "1.sql = SELECT 'Hello World', 'more content' WHERE help=1\n2.head = <table>\n3.sql     =   SELECT col1, col2, col3\nform = Person";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Join several lines, incl. form
+        $given = "\nmyAlias {\nsql = SELECT 'Hello World',\n'more content'\n      WHERE help=1\n}\n   mySecondAlias  {\nhead = <table>\n}\nmyThirdAlias  {\nsql     =   SELECT\n col1,\n col2, \n col3\n  # Query stops here\n}\nform = Person\n";
+        $expected = "1.sql = SELECT 'Hello World', 'more content' WHERE help=1\n2.head = <table>\n3.sql     =   SELECT col1, col2, col3\nform = Person";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Nested expression: one.
         $given = "10{\nsql = SELECT 'Hello World'\n}\n";
         $expected = "10.sql = SELECT 'Hello World'";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Nested expression: one.
+        $given = "{\nsql = SELECT 'Hello World'\n}\n";
+        $expected = "1.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Nested expression: one.
+        $given = "myAlias {\nsql = SELECT 'Hello World'\n}\n";
+        $expected = "1.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Nested expression: one. No LF at the end
         $given = "10{\nsql = SELECT 'Hello World'\n}";
         $expected = "10.sql = SELECT 'Hello World'";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Nested expression: one. No LF at the end
+        $given = "{\nsql = SELECT 'Hello World'\n}";
+        $expected = "1.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Nested expression: one. No LF at the end
+        $given = "myAlias {\nsql = SELECT 'Hello World'\n}";
+        $expected = "1.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Nested expression, one, added some white spaces
         $given = "\n\n10 { \n \n   sql    =    SELECT 'Hello World'     \n\n    }\n\n";
         $expected = "10.sql    =    SELECT 'Hello World'";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Nested expression, one, added some white spaces
+        $given = "\n\n { \n \n   sql    =    SELECT 'Hello World'     \n\n    }\n\n";
+        $expected = "1.sql    =    SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Nested expression, one, added some white spaces
+        $given = "\n\n myAlias  { \n \n   sql    =    SELECT 'Hello World'     \n\n    }\n\n";
+        $expected = "1.sql    =    SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Nested expression: multiple, simple
         $given = "10.sql = SELECT 'Hello World'\n20 {\nsql='Hello world2'\n}\n30 {\nsql='Hello world3'\n}\n";
         $expected = "10.sql = SELECT 'Hello World'\n20.sql='Hello world2'\n30.sql='Hello world3'";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Nested expression: multiple, simple
+        $given = "{\nsql = SELECT 'Hello World'\n}\n{\nsql='Hello world2'\n}\n {\nsql='Hello world3'\n}\n";
+        $expected = "1.sql = SELECT 'Hello World'\n2.sql='Hello world2'\n3.sql='Hello world3'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Nested expression: multiple, simple
+        $given = "myAlias {\nsql = SELECT 'Hello World'\n}\nmyAlias10{\nsql='Hello world2'\n}\n 10myAlias{\nsql='Hello world3'\n}\n";
+        $expected = "1.sql = SELECT 'Hello World'\n2.sql='Hello world2'\n3.sql='Hello world3'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Nested expression: complex
         $given = "10.sql = SELECT 'Hello World'\n20 {\nsql='Hello world2'\n30 { \n sql=SELECT 'Hello World3'\n40 { \n sql = SELECT 'Hello World4'\n  }  \n  } \n  }  ";
         $expected = "10.sql = SELECT 'Hello World'\n20.sql='Hello world2'\n20.30.sql=SELECT 'Hello World3'\n20.30.40.sql = SELECT 'Hello World4'";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Nested expression: complex
+        $given = "{\nsql = SELECT 'Hello World'\n}\n {\nsql='Hello world2'\n { \n sql=SELECT 'Hello World3'\n { \n sql = SELECT 'Hello World4'\n  }  \n  } \n  }  ";
+        $expected = "1.sql = SELECT 'Hello World'\n2.sql='Hello world2'\n2.3.sql=SELECT 'Hello World3'\n2.3.4.sql = SELECT 'Hello World4'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Nested expression: complex
+        $given = "myAlias{\nsql = SELECT 'Hello World'\n}\n myAlias2{\nsql='Hello world2'\n myAlias3{ \n sql=SELECT 'Hello World3'\n myAlias4{ \n sql = SELECT 'Hello World4'\n  }  \n  } \n  }  ";
+        $expected = "1.sql = SELECT 'Hello World'\n2.sql='Hello world2'\n2.3.sql=SELECT 'Hello World3'\n2.3.4.sql = SELECT 'Hello World4'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // form=...., {{ }}
         $given = "10.sql = SELECT 'Hello World'\nform = {{form:S}}\n20.sql = SELECT 'Hello World2'\n30 {\nsql=SELECT 'Hello World'\n}\n   form=Person\n";
         $expected = "10.sql = SELECT 'Hello World'\nform = {{form:S}}\n20.sql = SELECT 'Hello World2'\n30.sql=SELECT 'Hello World'\nform=Person";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // form=...., {{ }}
+        $given = "{\nsql = SELECT 'Hello World'\n}\nform = {{form:S}}\n{\nsql = SELECT 'Hello World2'\n}\n {\nsql=SELECT 'Hello World'\n}\n   form=Person\n";
+        $expected = "1.sql = SELECT 'Hello World'\nform = {{form:S}}\n2.sql = SELECT 'Hello World2'\n3.sql=SELECT 'Hello World'\nform=Person";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // form=...., {{ }}
+        $given = "myAlias{\nsql = SELECT 'Hello World'\n}\nform = {{form:S}}\nmyAlias2 {\nsql = SELECT 'Hello World2'\n}\n myAlias3{\nsql=SELECT 'Hello World'\n}\n   form=Person\n";
+        $expected = "1.sql = SELECT 'Hello World'\nform = {{form:S}}\n2.sql = SELECT 'Hello World2'\n3.sql=SELECT 'Hello World'\nform=Person";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Nested: open bracket alone
         $given = "10.sql = SELECT 'Hello World'\n20\n{\nhead=test\n}\n30.sql = SELECT 'Hello World'\n";
         $expected = "10.sql = SELECT 'Hello World'\n20.head=test\n30.sql = SELECT 'Hello World'";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Nested: open bracket alone
+        $given = "{\nsql = SELECT 'Hello World'\n}\n\n{\nhead=test\n}\n{\nsql = SELECT 'Hello World'\n}";
+        $expected = "1.sql = SELECT 'Hello World'\n2.head=test\n3.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Nested: open bracket alone
+        $given = "myAlias{\nsql = SELECT 'Hello World'\n}\n\nmySecondAlias{\nhead=test\n}\nmyThirdAlias{\nsql = SELECT 'Hello World'\n}";
+        $expected = "1.sql = SELECT 'Hello World'\n2.head=test\n3.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Single open bracket inside a string.
         $given = "10.sql = SELECT 'Hello { World'";
         $expected = "10.sql = SELECT 'Hello { World'";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Single open bracket inside a string.
+        $given = "{\nsql = SELECT 'Hello { World'\n}";
+        $expected = "1.sql = SELECT 'Hello { World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Single open bracket inside a string.
+        $given = "myAlias{\nsql = SELECT 'Hello { World'\n}";
+        $expected = "1.sql = SELECT 'Hello { World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Complex test
         $given = "10.sql = SELECT '[\*]{7} [0-9]{5}<br>'\n20 {\n   10 {\n      5 {\n         sql = SELECT 'hello world<br>'\n      }\n   }\n}\n20.10.5.head = Terific\n20.sql = SELECT 20, '<br>'\n20.10.sql = SELECT  '20.10<br>'";
         $expected = "10.sql = SELECT '[\*]{7} [0-9]{5}<br>'\n20.10.5.sql = SELECT 'hello world<br>'\n20.10.5.head = Terific\n20.sql = SELECT 20, '<br>'\n20.10.sql = SELECT  '20.10<br>'";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Complex test
+        $given = "{\nsql = SELECT '[\*]{7} [0-9]{5}<br>'\n}\n{\n   {\n       {\n         sql = SELECT 'hello world<br>'\n  head = Terrific   \n}\n   }\n}\n{\nsql = SELECT 5, '<br>'\n}\n{\nsql = SELECT  '6<br>'\n}";
+        $expected = "1.sql = SELECT '[\*]{7} [0-9]{5}<br>'\n2.3.4.sql = SELECT 'hello world<br>'\n2.3.4.head = Terrific\n5.sql = SELECT 5, '<br>'\n6.sql = SELECT  '6<br>'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Complex test
+        $given = "myAliasOne{\nsql = SELECT '[\*]{7} [0-9]{5}<br>'\n}\nmyAliasTwo{\n   myAliasThree{\n       myAliasFour{\n         sql = SELECT 'hello world<br>'\n  head = Terrific   \n}\n   }\n}\nmyAliasFive  {\nsql = SELECT 5, '<br>'\n}\nmyLastAlias{\nsql = SELECT  '6<br>'\n}";
+        $expected = "1.sql = SELECT '[\*]{7} [0-9]{5}<br>'\n2.3.4.sql = SELECT 'hello world<br>'\n2.3.4.head = Terrific\n5.sql = SELECT 5, '<br>'\n6.sql = SELECT  '6<br>'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
     }
 
     public function testNestingToken() {
@@ -116,48 +298,160 @@ final class BodytextParserTest extends TestCase {
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Nested expression: one level curly
+        $given = "{ \n     sql = SELECT 'Hello World' \n , 'next line', \n \n 'end' \n} \n";
+        $expected = "1.sql = SELECT 'Hello World' , 'next line', 'end'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Nested expression: one level curly
+        $given = "myAlias{ \n     sql = SELECT 'Hello World' \n , 'next line', \n \n 'end' \n} \n";
+        $expected = "1.sql = SELECT 'Hello World' , 'next line', 'end'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Nested expression: one level angle
         $given = "#<\n10 < \n     sql = SELECT 'Hello World'\n>\n";
         $expected = "10.sql = SELECT 'Hello World'";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Nested expression: one level angle
+        $given = "#<\n < \n     sql = SELECT 'Hello World'\n>\n";
+        $expected = "1.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Nested expression: one level angle
+        $given = "#<\n myAlias< \n     sql = SELECT 'Hello World'\n>\n";
+        $expected = "1.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Nested expression: one level angle and single curly
         $given = "#<\n10 < \n  head = data { \n '1','2','3' \n }\n>\n";
         $expected = "10.head = data { '1','2','3' }";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Nested expression: one level angle and single curly
+        $given = "#<\n < \n  head = data { \n '1','2','3' \n }\n>\n";
+        $expected = "1.head = data { '1','2','3' }";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Nested expression: one level angle and single curly
+        $given = "#<\n myAlias< \n  head = data { \n '1','2','3' \n }\n>\n";
+        $expected = "1.head = data { '1','2','3' }";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Nested expression: one level angle and single curly
         $given = "  #   < \n 10 < \n  sql = SELECT 'Hello World' \n>\n";
         $expected = "10.sql = SELECT 'Hello World'";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Nested expression: one level angle and single curly
+        $given = "  #   < \n  < \n  sql = SELECT 'Hello World' \n>\n";
+        $expected = "1.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Nested expression: one level angle and single curly
+        $given = "  #   myAlias1< \n  myAlias2< \n  sql = SELECT 'Hello World' \n>\n";
+        $expected = "1.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Nested expression: one level round bracket
         $given = "  #   ( \n 10 ( \n  sql = SELECT 'Hello World' \n)\n";
         $expected = "10.sql = SELECT 'Hello World'";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Nested expression: one level round bracket
+        $given = "  #   ( \n  ( \n  sql = SELECT 'Hello World' \n)\n";
+        $expected = "1.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Nested expression: one level round bracket
+        $given = "  #   ( \n  myAlias( \n  sql = SELECT 'Hello World' \n)\n";
+        $expected = "1.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Nested expression: one level square bracket
         $given = "  #   [ \n 10 [ \n  sql = SELECT 'Hello World' \n]\n";
         $expected = "10.sql = SELECT 'Hello World'";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Nested expression: one level square bracket
+        $given = "  #   [ \n  [ \n  sql = SELECT 'Hello World' \n]\n";
+        $expected = "1.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Nested expression: one level square bracket
+        $given = "  #   [ \n  myAlias[ \n  sql = SELECT 'Hello World' \n]\n";
+        $expected = "1.sql = SELECT 'Hello World'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Nested expression: one level angle - garbage
         $given = "  #   < \n 10 { \n  sql = SELECT 'Hello World' \n}\n";
         $expected = "10 {\nsql = SELECT 'Hello World' }";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Nested expression: one level angle - garbage
+        $given = "  #   < \n  { \n  sql = SELECT 'Hello World' \n}\n";
+        $expected = "{\nsql = SELECT 'Hello World' }";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Nested expression: one level angle - garbage
+        $given = "  #   < \n  myAlias{ \n  sql = SELECT 'Hello World' \n}\n";
+        $expected = "myAlias{\nsql = SELECT 'Hello World' }";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         // Nested expression: '</script>' is allowed here - with bad implemented parsing, it would detect a nesting token end, which is not the meant.
         $given = "  #   < \n 10 < \n  sql = SELECT 'Hello World' \n head = <script> \n>\n20.tail=</script>\n\n\n30.sql=SELECT 'something'";
         $expected = "10.sql = SELECT 'Hello World'\n10.head = <script>\n20.tail=</script>\n30.sql=SELECT 'something'";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // Nested expression: '</script>' is allowed here - with bad implemented parsing, it would detect a nesting token end, which is not the meant.
+        $given = "  #   < \n  < \n  sql = SELECT 'Hello World' \n head = <script> \n>\n<\ntail=</script>\n>\n<\nsql=SELECT 'something'\n>";
+        $expected = "1.sql = SELECT 'Hello World'\n1.head = <script>\n2.tail=</script>\n3.sql=SELECT 'something'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Nested expression: '</script>' is allowed here - with bad implemented parsing, it would detect a nesting token end, which is not the meant.
+        $given = "  #   < \n  myAlias < \n  sql = SELECT 'Hello World' \n head = <script> \n>\n myAlias2 <\ntail=</script>\n>\nmyAlias3<\nsql=SELECT 'something'\n>";
+        $expected = "1.sql = SELECT 'Hello World'\n1.head = <script>\n2.tail=</script>\n3.sql=SELECT 'something'";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
         $open = '<';
         $close = '>';
         // muliple nesting, unnested rows  inbetween
@@ -211,6 +505,125 @@ EOF;
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
 
+        // Report notation 'alias'
+        // muliple nesting, unnested rows  inbetween
+        $given = <<<EOF
+                # $open
+                
+                $open
+                    head = <h1>
+                $close
+                $open
+                    sql = SELECT ...
+                $close
+                $open
+                  $open
+                    sql = SELECT 3.4
+                    head = <script>
+                    tail = </script>
+                    $open
+                      head = <div>
+                    $close
+                  $close
+                  $open
+                    sql = SELECT 3.6
+                  $close
+                  $open
+                    sql = SELECT 3.7
+                  $close
+                  $open
+                    $open
+                        tail = }
+                        }
+                        (:
+                        }
+                        ]
+                        sql = SELECT 3.8.9
+                        head = {
+                          {
+                          )
+                          {
+                          ;
+                          [
+                    $close
+                    $open
+                      sql = SELECT 3.8.10
+                    $close
+                    $open
+                        sql = SELECT 3.8.11
+                    $close
+                  $close
+                  $open
+                    head = <table>
+                  $close
+                $close
+                $open
+                  sql = SELECT 13
+                $close
+EOF;
+        $expected = "1.head = <h1>\n2.sql = SELECT ...\n3.4.sql = SELECT 3.4\n3.4.head = <script>\n3.4.tail = </script>\n3.4.5.head = <div>\n3.6.sql = SELECT 3.6\n3.7.sql = SELECT 3.7\n3.8.9.tail = } } (: } ]\n3.8.9.sql = SELECT 3.8.9\n3.8.9.head = { { ) { ; [\n3.8.10.sql = SELECT 3.8.10\n3.8.11.sql = SELECT 3.8.11\n3.12.head = <table>\n13.sql = SELECT 13";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // muliple nesting, unnested rows  inbetween
+        $given = <<<EOF
+                # $open
+                
+                myAlias1 $open
+                    head = <h1>
+                $close
+                myAlias2 $open
+                    sql = SELECT ...
+                $close
+                myAlias3 $open
+                  myAlias4 $open
+                    sql = SELECT 3.4
+                    head = <script>
+                    tail = </script>
+                    myAlias4 $open
+                      head = <div>
+                    $close
+                  $close
+                  myAlias5 $open
+                    sql = SELECT 3.6
+                  $close
+                  myAlias6 $open
+                    sql = SELECT 3.7
+                  $close
+                  myAlias7 $open
+                    myAlias8 $open
+                        tail = }
+                        }
+                        (:
+                        }
+                        ]
+                        sql = SELECT 3.8.9
+                        head = {
+                          {
+                          )
+                          {
+                          ;
+                          [
+                    $close
+                    myAlias9 $open
+                      sql = SELECT 3.8.10
+                    $close
+                    myAlias10$open
+                        sql = SELECT 3.8.11
+                    $close
+                  $close
+                  myAlias11$open
+                    head = <table>
+                  $close
+                $close
+                myAlias12$open
+                  sql = SELECT 13
+                $close
+EOF;
+        $expected = "1.head = <h1>\n2.sql = SELECT ...\n3.4.sql = SELECT 3.4\n3.4.head = <script>\n3.4.tail = </script>\n3.4.5.head = <div>\n3.6.sql = SELECT 3.6\n3.7.sql = SELECT 3.7\n3.8.9.tail = } } (: } ]\n3.8.9.sql = SELECT 3.8.9\n3.8.9.head = { { ) { ; [\n3.8.10.sql = SELECT 3.8.10\n3.8.11.sql = SELECT 3.8.11\n3.12.head = <table>\n13.sql = SELECT 13";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
     }
 
     public function testVariousNestingToken() {
@@ -232,6 +645,30 @@ EOF;
             $result = $btp->process($given);
             $this->assertEquals($expected, $result);
 
+            // Report notation 'alias'
+            // level open
+            $given = <<<EOF
+                # $open
+                 $open
+                  sql = SELECT 'Hello World'
+                $close
+EOF;
+            $expected = "1.sql = SELECT 'Hello World'";
+            $result = $btp->process($given);
+            $this->assertEquals($expected, $result);
+
+            // Report notation 'alias' with alias
+            // level open
+            $given = <<<EOF
+                # $open
+                 myAlias $open
+                  sql = SELECT 'Hello World'
+                $close
+EOF;
+            $expected = "1.sql = SELECT 'Hello World'";
+            $result = $btp->process($given);
+            $this->assertEquals($expected, $result);
+
             // level \n alone
             $given = <<<EOF
                 # $open
@@ -244,6 +681,32 @@ EOF;
             $result = $btp->process($given);
             $this->assertEquals($expected, $result);
 
+            // Report notation 'alias'
+            // level \n alone
+            $given = <<<EOF
+                # $open
+                
+                $open
+                  sql = SELECT 'Hello World'
+                $close
+EOF;
+            $expected = "1.sql = SELECT 'Hello World'";
+            $result = $btp->process($given);
+            $this->assertEquals($expected, $result);
+
+            // Report notation 'alias' with alias
+            // level \n alone
+            $given = <<<EOF
+                # $open
+                
+                myAlias$open
+                  sql = SELECT 'Hello World'
+                $close
+EOF;
+            $expected = "1.sql = SELECT 'Hello World'";
+            $result = $btp->process($given);
+            $this->assertEquals($expected, $result);
+
             // various linebreaks
             $given = <<<EOF
                 # $open
@@ -259,6 +722,38 @@ EOF;
             $result = $btp->process($given);
             $this->assertEquals($expected, $result);
 
+            // Report notation 'alias'
+            // various linebreaks
+            $given = <<<EOF
+                # $open
+
+                  $open
+
+                  sql = SELECT 'Hello World'
+
+                $close
+
+EOF;
+            $expected = "1.sql = SELECT 'Hello World'";
+            $result = $btp->process($given);
+            $this->assertEquals($expected, $result);
+
+            // Report notation 'alias' with alias
+            // various linebreaks
+            $given = <<<EOF
+                # $open
+
+                  myAlias $open
+
+                  sql = SELECT 'Hello World'
+
+                $close
+
+EOF;
+            $expected = "1.sql = SELECT 'Hello World'";
+            $result = $btp->process($given);
+            $this->assertEquals($expected, $result);
+
             // multi line
             $given = <<<EOF
                 # $open
@@ -277,6 +772,42 @@ EOF;
             $result = $btp->process($given);
             $this->assertEquals($expected, $result);
 
+            // Report notation 'alias'
+            // multi line
+            $given = <<<EOF
+                # $open
+                  $open
+                  sql = SELECT 'Hello World'
+                        FROM Person
+
+                        ORDER BY id
+
+                        LIMIT 4
+                   head = <div>
+                $close
+EOF;
+            $expected = "1.sql = SELECT 'Hello World' FROM Person ORDER BY id LIMIT 4\n1.head = <div>";
+            $result = $btp->process($given);
+            $this->assertEquals($expected, $result);
+
+            // Report notation 'alias' with alias
+            // multi line
+            $given = <<<EOF
+                # $open
+                  myAlias $open
+                  sql = SELECT 'Hello World'
+                        FROM Person
+
+                        ORDER BY id
+
+                        LIMIT 4
+                   head = <div>
+                $close
+EOF;
+            $expected = "1.sql = SELECT 'Hello World' FROM Person ORDER BY id LIMIT 4\n1.head = <div>";
+            $result = $btp->process($given);
+            $this->assertEquals($expected, $result);
+
             // mulitple nesting
             $given = <<<EOF
                 # $open
@@ -300,6 +831,58 @@ EOF;
             $result = $btp->process($given);
             $this->assertEquals($expected, $result);
 
+            // Report notation 'alias'
+            // mulitple nesting
+            $given = <<<EOF
+                # $open
+                $open
+                  head = <h1>
+                $close
+                  $open
+                  sql = SELECT 'Hello World'
+                   $open
+                    sql = SELECT 'Hi'
+                    head = <script>
+                    tail = </script>
+                     $open
+                        head = <div>
+                    $close
+
+                  $close
+
+                $close
+
+EOF;
+            $expected = "1.head = <h1>\n2.sql = SELECT 'Hello World'\n2.3.sql = SELECT 'Hi'\n2.3.head = <script>\n2.3.tail = </script>\n2.3.4.head = <div>";
+            $result = $btp->process($given);
+            $this->assertEquals($expected, $result);
+
+            // Report notation 'alias' with alias
+            // mulitple nesting
+            $given = <<<EOF
+                # $open
+                myAlias$open
+                  head = <h1>
+                $close
+                  myAlias2$open
+                  sql = SELECT 'Hello World'
+                   myAlias3$open
+                    sql = SELECT 'Hi'
+                    head = <script>
+                    tail = </script>
+                     myAlias4$open
+                        head = <div>
+                    $close
+
+                  $close
+
+                $close
+
+EOF;
+            $expected = "1.head = <h1>\n2.sql = SELECT 'Hello World'\n2.3.sql = SELECT 'Hi'\n2.3.head = <script>\n2.3.tail = </script>\n2.3.4.head = <div>";
+            $result = $btp->process($given);
+            $this->assertEquals($expected, $result);
+
             // muliple nesting, unnested rows  inbetween
             $given = <<<EOF
                 # $open
@@ -325,6 +908,66 @@ EOF;
             $result = $btp->process($given);
             $this->assertEquals($expected, $result);
 
+            // Report notation 'alias'
+            // muliple nesting, unnested rows  inbetween
+            $given = <<<EOF
+                # $open
+                $open
+                  head = <h1>
+                $close
+                $open
+                  sql = SELECT 'Hello World'
+                  $open
+                    sql = SELECT 'Hi'
+                    head = <script>
+                    tail = </script>
+                    $open
+                      head = <div>
+                    $close
+                  $close
+                  $open
+                    sql = SELECT 'After'
+                  $close
+                $close
+                $open
+                  sql = SELECT ...
+                $close
+
+EOF;
+            $expected = "1.head = <h1>\n2.sql = SELECT 'Hello World'\n2.3.sql = SELECT 'Hi'\n2.3.head = <script>\n2.3.tail = </script>\n2.3.4.head = <div>\n2.5.sql = SELECT 'After'\n6.sql = SELECT ...";
+            $result = $btp->process($given);
+            $this->assertEquals($expected, $result);
+
+            // Report notation 'alias' with alias
+            // muliple nesting, unnested rows  inbetween
+            $given = <<<EOF
+                # $open
+                myAlias$open
+                  head = <h1>
+                $close
+                mySecondAlias$open
+                  sql = SELECT 'Hello World'
+                  myThirdAlias$open
+                    sql = SELECT 'Hi'
+                    head = <script>
+                    tail = </script>
+                    myFourthAlias$open
+                      head = <div>
+                    $close
+                  $close
+                  myFifthAlias$open
+                    sql = SELECT 'After'
+                  $close
+                $close
+                mySixthAlias$open
+                  sql = SELECT ...
+                $close
+
+EOF;
+            $expected = "1.head = <h1>\n2.sql = SELECT 'Hello World'\n2.3.sql = SELECT 'Hi'\n2.3.head = <script>\n2.3.tail = </script>\n2.3.4.head = <div>\n2.5.sql = SELECT 'After'\n6.sql = SELECT ...";
+            $result = $btp->process($given);
+            $this->assertEquals($expected, $result);
+
         }
 
     }
@@ -347,6 +990,40 @@ EOF;
         $expected = "10.sql = SELECT 'Hello World', 'p:id=1&grId=2\n20.sql = SELECT ''";
         $result = $btp->process($given);
         $this->assertEquals($expected, $result);
+
+        // Report notation 'alias'
+        // Simple row, nothing to remove
+        $given = "{\nsql = SELECT 'Hello World', 'p:id=1&\\\ngrId=2\n}";
+        $expected = "1.sql = SELECT 'Hello World', 'p:id=1&grId=2";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        $given = "{\nsql = SELECT 'Hello World', 'p:id=1&  \\\n  grId=2  \n}";
+        $expected = "1.sql = SELECT 'Hello World', 'p:id=1&grId=2";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        $given = "{\nsql = SELECT 'Hello World', 'p:id=1&  \\\n  grId=2  \\\n }\n{\nsql = SELECT ''\n}";
+        $expected = "1.sql = SELECT 'Hello World', 'p:id=1&grId=2\n2.sql = SELECT ''";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Simple row, nothing to remove
+        $given = "myAlias{\nsql = SELECT 'Hello World', 'p:id=1&\\\ngrId=2\n}";
+        $expected = "1.sql = SELECT 'Hello World', 'p:id=1&grId=2";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        $given = "myAlias{\nsql = SELECT 'Hello World', 'p:id=1&  \\\n  grId=2  \n}";
+        $expected = "1.sql = SELECT 'Hello World', 'p:id=1&grId=2";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
+
+        $given = "myAlias{\nsql = SELECT 'Hello World', 'p:id=1&  \\\n  grId=2  \\\n }\n{\nsql = SELECT ''\n}";
+        $expected = "1.sql = SELECT 'Hello World', 'p:id=1&grId=2\n2.sql = SELECT ''";
+        $result = $btp->process($given);
+        $this->assertEquals($expected, $result);
     }
 
     /**
@@ -360,6 +1037,14 @@ EOF;
         // Nested: unmatched close bracket
         $btp->process("10.sql = SELECT 'Hello World'\n } \n30.sql = SELECT 'Hello World'\n");
 
+        // Report notation 'alias'
+        // Nested: unmatched close bracket
+        $btp->process("sql = SELECT 'Hello World'\n } \n{\nsql = SELECT 'Hello World'\n}");
+
+        // Report notation 'alias' with alias
+        // Nested: unmatched close bracket
+        $btp->process("sql = SELECT 'Hello World'\n } \nmyAlias{\nsql = SELECT 'Hello World'\n}");
+
     }
 
     /**
@@ -372,6 +1057,237 @@ EOF;
         // Nested: unmatched open bracket
         $btp->process("10.sql = SELECT 'Hello World'\n20 { \n30.sql = SELECT 'Hello World'\n");
 
+        // Report notation 'alias'
+        // Nested: unmatched open bracket
+        $btp->process("{\nsql = SELECT 'Hello World'\n}\n { \n30.sql = SELECT 'Hello World'\n");
+
+        // Report notation 'alias' with alias
+        // Nested: unmatched open bracket
+        $btp->process("myAlias{\nsql = SELECT 'Hello World'\n}\n myAlias2{ \n30.sql = SELECT 'Hello World'\n");
+
     }
 
-}
+    /**
+     *
+     */
+    public function testReportLines() {
+        $btp = new BodytextParser();
+
+        // Simple statement
+        $given = "10.sql = SELECT 'Hello World'";
+        $expected = [10 => 1];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Simple statement, nested
+        $given = "10 {\nsql = SELECT 'Hello World'\n}";
+        $expected = [10 => 2];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias'
+        // Simple statement, nested
+        $given = "{\nsql = SELECT 'Hello World'\n}";
+        $expected = [1 => 2];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Simple statement, nested
+        $given = "myAlias{\nsql = SELECT 'Hello World'\n}";
+        $expected = [1 => 2];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Simple statement, multiple unnecessary lines
+        $given = "\n#some comments\n10.sql = SELECT 'Hello World'\n\n    \n   #more comment";
+        $expected = [10 => 3];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Simple statement, multiple unnecessary lines, nested
+        $given = "\n#some comments\n10\n{\nsql = SELECT 'Hello World'\n\n}\n    \n   #more comment";
+        $expected = [10 => 5];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias'
+        // Simple statement, multiple unnecessary lines, nested
+        $given = "\n#some comments\n\n{\nsql = SELECT 'Hello World'\n\n}\n    \n   #more comment";
+        $expected = [1 => 5];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Simple statement, multiple unnecessary lines, nested
+        $given = "\n#some comments\n\nmyAlias{\nsql = SELECT 'Hello World'\n\n}\n    \n   #more comment";
+        $expected = [1 => 5];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // No statement
+        $given = "\n#some comments\n\n\n    \n   #more comment";
+        $expected = [];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Simple statement on multiple lines
+        $given = "\n10.sql = SELECT 'Hello World',\n'more content'\n      WHERE help=1";
+        $expected = [10 => 2];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Simple statement on multiple lines, nested
+        $given = "\n10 {\nsql = SELECT 'Hello World',\n'more content'\n      WHERE help=1\n}";
+        $expected = [10 => 3];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias'
+        // Simple statement on multiple lines, nested
+        $given = "\n {\nsql = SELECT 'Hello World',\n'more content'\n      WHERE help=1\n}";
+        $expected = [1 => 3];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Simple statement on multiple lines, nested
+        $given = "\n myAlias{\nsql = SELECT 'Hello World',\n'more content'\n      WHERE help=1\n}";
+        $expected = [1 => 3];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Simple statements
+        $given = "10.sql = SELECT 'Hello World'\n20.sql = SELECT 'Hello World'\n30.sql = SELECT 'Hello World'";
+        $expected = [10 => 1, 20 => 2, 30 => 3];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Simple statements, nested
+        $given = "10 {\nsql = SELECT 'Hello World'\n}\n20 {\nsql = SELECT 'Hello World'\n}\n30 {\nsql = SELECT 'Hello World'\n}";
+        $expected = [10 => 2, 20 => 5, 30 => 8];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias'
+        // Simple statements, nested
+        $given = "{\nsql = SELECT 'Hello World'\n}\n{\nsql = SELECT 'Hello World'\n}\n{\nsql = SELECT 'Hello World'\n}";
+        $expected = [1 => 2, 2 => 5, 3 => 8];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Simple statements, nested
+        $given = "myAlias{\nsql = SELECT 'Hello World'\n}\nmyAlias2{\nsql = SELECT 'Hello World'\n}\nmyAlias3{\nsql = SELECT 'Hello World'\n}";
+        $expected = [1 => 2, 2 => 5, 3 => 8];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Simple statements, multiple unnecessary lines
+        $given = "\n#some comments\n10.sql = SELECT 'Hello World'\n\n    \n   #more comment \n 20.sql = SELECT 'Hello World'\n #more comment\n\n\n 30.sql=SELECT 'Hello World'";
+        $expected = [10 => 3, 20 => 7, 30 => 11];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Simple statements, multiple unnecessary lines, nested
+        $given = "\n#some comments\n10\n{\nsql = SELECT 'Hello World'\n\n}\n    \n   #more comment\n\n 20 {\nsql = SELECT 'Hello World'\n\n}\n #more comment \n\n\n 30 {\nsql = SELECT 'Hello World'\n\n}";
+        $expected = [10 => 5, 20 => 12, 30 => 19];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias'
+        // Simple statements, multiple unnecessary lines, nested
+        $given = "\n#some comments\n\n{\nsql = SELECT 'Hello World'\n\n}\n    \n   #more comment\n\n  {\nsql = SELECT 'Hello World'\n\n}\n #more comment \n\n\n  {\nsql = SELECT 'Hello World'\n\n}";
+        $expected = [1 => 5, 2 => 12, 3 => 19];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Simple statements, multiple unnecessary lines, nested
+        $given = "\n#some comments\n\nmyAlias{\nsql = SELECT 'Hello World'\n\n}\n    \n   #more comment\n\n  myAlias2{\nsql = SELECT 'Hello World'\n\n}\n #more comment \n\n\n  myAlias3{\nsql = SELECT 'Hello World'\n\n}";
+        $expected = [1 => 5, 2 => 12, 3 => 19];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Simple statements on multiple lines
+        $given = "\n10.sql = SELECT 'Hello World',\n'more content'\n      WHERE help=1\n\n 20.sql = SELECT 'Hello World', \n 'some more content'";
+        $expected = [10 => 2, 20 => 6];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Simple statements on multiple lines, nested
+        $given = "\n10 {\nsql = SELECT 'Hello World',\n'more content'\n      WHERE help=1\n}\n\n20\n {\nsql = SELECT 'Hello World', \n 'some more content'\n}";
+        $expected = [10 => 3, 20 => 10];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias'
+        // Simple statements on multiple lines, nested
+        $given = "\n {\nsql = SELECT 'Hello World',\n'more content'\n      WHERE help=1\n}\n\n{\nsql = SELECT 'Hello World', \n 'some more content'\n}";
+        $expected = [1 => 3, 2 => 9];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Simple statements on multiple lines, nested
+        $given = "\n myAlias{\nsql = SELECT 'Hello World',\n'more content'\n      WHERE help=1\n}\n\nmyAlias2{\nsql = SELECT 'Hello World', \n 'some more content'\n}";
+        $expected = [1 => 3, 2 => 9];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Complex statements
+        $given = "10.sql = SELECT 'Hello World'\n20.sql='Hello world2'\n20.30.sql=SELECT 'Hello World3'\n20.30.40.sql = SELECT 'Hello World4'";
+        $expected = [10 => 1, 20 => 2, '20.30' => 3, '20.30.40' => 4];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Complex statements, nested
+        $given = "10.sql = SELECT 'Hello World'\n20 {\nsql='Hello world2'\n30 { \n sql=SELECT 'Hello World3'\n40 { \n sql = SELECT 'Hello World4'\n  }  \n  } \n  }  ";
+        $expected = [10 => 1, 20 => 3, '20.30' => 5, '20.30.40' => 7];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias'
+        // Complex statements: complex
+        $given = "{\nsql = SELECT 'Hello World'\n}\n {\nsql='Hello world2'\n { \n sql=SELECT 'Hello World3'\n { \n sql = SELECT 'Hello World4'\n  }  \n  } \n  }  ";
+        $expected = [1 => 2, 2 => 5, '2.3' => 7, '2.3.4' => 9];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+
+        // Report notation 'alias' with alias
+        // Complex statements: complex
+        $given = "myAlias{\nsql = SELECT 'Hello World'\n}\n myAlias2{\nsql='Hello world2'\n myAlias3{ \n sql=SELECT 'Hello World3'\n myAlias4{ \n sql = SELECT 'Hello World4'\n  }  \n  } \n  }  ";
+        $expected = [1 => 2, 2 => 5, '2.3' => 7, '2.3.4' => 9];
+        $btp->process($given);
+        $result = $btp->reportLines;
+        $this->assertEquals($expected, $result);
+    }
+}
\ No newline at end of file
diff --git a/extension/Tests/Unit/Core/Report/ReportTest.php b/extension/Tests/Unit/Core/Report/ReportTest.php
index 789b04a23d134f5480adf434c6ab768b05d85644..b8135a028bc918d113e21ada43283591505233c9 100644
--- a/extension/Tests/Unit/Core/Report/ReportTest.php
+++ b/extension/Tests/Unit/Core/Report/ReportTest.php
@@ -1384,6 +1384,9 @@ EOF;
      */
     public function testReportPageWrapper() {
 
+        // Report notation 'alias' with alias
+        $this->store->setVar(TOKEN_ALIAS . '.1', 'myAlias', STORE_TYPO3);
+
         $line = <<<EOF
 10.sql = SELECT firstname FROM Person ORDER BY id LIMIT 2
 10.head = <table>
@@ -1403,6 +1406,32 @@ EOF;
 10.10.tail = Dynamic tail
 10.10.althead = No record found
 10.10.altsql = SELECT 'alt sql fired'
+EOF;
+
+        $result = $this->report->process($line);
+        $expect = "<table><tr><td>John</td><br>Static headDynamic headnestedDynamic tailStatic tail</tr>--<tr><td>Jane</td><br>Static headNo record foundalt sql firedStatic tail</tr></table>";
+        $this->assertEquals($expect, $result);
+
+        // Report notation 'alias' with alias
+        $line = <<<EOF
+1.sql = SELECT firstname FROM Person ORDER BY id LIMIT 2
+1.head = <table>
+1.tail = </table>
+1.rbeg = <tr>
+1.rend = <br>
+1.renr = </tr>
+1.fbeg = <td>
+1.fend = </td>
+1.rsep = --
+1.fsep = ++
+
+1.2.sql = SELECT 'nested' FROM (SELECT '') AS fake WHERE '{{myAlias.line.count}}'='1'
+1.2.shead = Static head
+1.2.stail = Static tail
+1.2.head = Dynamic head
+1.2.tail = Dynamic tail
+1.2.althead = No record found
+1.2.altsql = SELECT 'alt sql fired'
 EOF;
 
         $result = $this->report->process($line);
@@ -1425,6 +1454,9 @@ EOF;
      */
     public function testReportContent() {
 
+        // Report notation 'alias' with alias
+        $this->store->setVar(TOKEN_ALIAS . '.1', 'myAlias', STORE_TYPO3);
+
         $line = <<<EOF
 10.sql = SELECT 'Hello'
 20.sql = SELECT 'World'
@@ -1434,6 +1466,16 @@ EOF;
         $expect = "HelloWorld{{10.line.content}}";
         $this->assertEquals($expect, $result);
 
+        // Report notation 'alias' with alias
+        $line = <<<EOF
+1.sql = SELECT 'Hello'
+2.sql = SELECT 'World'
+2.tail = {{myAlias.line.content}}
+EOF;
+        $result = $this->report->process($line);
+        $expect = "HelloWorld{{myAlias.line.content}}";
+        $this->assertEquals($expect, $result);
+
         $line = <<<EOF
 10.sql = SELECT 'Hello'
 10.content = hide
@@ -1444,6 +1486,17 @@ EOF;
         $expect = "WorldHello";
         $this->assertEquals($expect, $result);
 
+        // Report notation 'alias' with alias
+        $line = <<<EOF
+1.sql = SELECT 'Hello'
+1.content = hide
+2.sql = SELECT 'World'
+2.tail = {{myAlias.line.content}} 
+EOF;
+        $result = $this->report->process($line);
+        $expect = "WorldHello";
+        $this->assertEquals($expect, $result);
+
         $line = <<<EOF
 10.sql = SELECT 'Hello'
 10.content = show
@@ -1454,6 +1507,17 @@ EOF;
         $expect = "HelloWorldHello";
         $this->assertEquals($expect, $result);
 
+        // Report notation 'alias' with alias
+        $line = <<<EOF
+1.sql = SELECT 'Hello'
+1.content = show
+2.sql = SELECT 'World'
+2.tail = {{myAlias.line.content}} 
+EOF;
+        $result = $this->report->process($line);
+        $expect = "HelloWorldHello";
+        $this->assertEquals($expect, $result);
+
         // Check that current row can be reused in head, tail, rbeg, rend, renr
         $line = <<<EOF
 10.sql = SELECT 'Hello'
@@ -1468,11 +1532,37 @@ EOF;
         $expect = "HelloHelloHelloHelloHelloHello";
         $this->assertEquals($expect, $result);
 
+        // Report notation 'alias' with alias
+        // Check that current row can be reused in head, tail, rbeg, rend, renr
+        $line = <<<EOF
+1.sql = SELECT 'Hello'
+1.content = show
+1.head = {{myAlias.line.content}}
+1.tail = {{myAlias.line.content}}
+1.rbeg = {{myAlias.line.content}}
+1.rend = {{myAlias.line.content}}
+1.renr = {{myAlias.line.content}}
+EOF;
+        $result = $this->report->process($line);
+        $expect = "HelloHelloHelloHelloHelloHello";
+        $this->assertEquals($expect, $result);
+
         // Check single tick escape
         $line = <<<EOF
 10.sql = SELECT "Hel'lo"
 10.content = hide
 20.sql = SELECT '--{{10.line.content::s}}--', "--{{10.line.content}}--", "--{{10.line.content::s}}--"
+EOF;
+        $result = $this->report->process($line);
+        $expect = "--Hel'lo----Hel'lo----Hel'lo--";
+        $this->assertEquals($expect, $result);
+
+        // Report notation 'alias' with alias
+        // Check single tick escape
+        $line = <<<EOF
+1.sql = SELECT "Hel'lo"
+1.content = hide
+2.sql = SELECT '--{{myAlias.line.content::s}}--', "--{{myAlias.line.content}}--", "--{{myAlias.line.content::s}}--"
 EOF;
         $result = $this->report->process($line);
         $expect = "--Hel'lo----Hel'lo----Hel'lo--";
@@ -1563,15 +1653,27 @@ EOF;
      */
     public function testReportVariables() {
 
+        // Report notation 'alias' with alias
+        $this->store->setVar(TOKEN_ALIAS . '.1', 'myAlias', STORE_TYPO3);
+        $this->store->setVar(TOKEN_ALIAS . '.1.2', 'myAlias2', STORE_TYPO3);
+
         $result = $this->report->process("10.sql = SELECT 'normal ', 'hidden' AS _hidden, 'text ' FROM Person ORDER BY id LIMIT 1");
         $this->assertEquals("normal text ", $result);
 
         $result = $this->report->process("10.sql = SELECT 'normal ', 'hidden' AS _hidden, 'text ' FROM Person ORDER BY id LIMIT 1\n10.10.sql = SELECT '{{10.hidden}}'");
         $this->assertEquals("normal text hidden", $result);
 
+        // Report notation 'alias' with alias
+        $result = $this->report->process("1.sql = SELECT 'normal ', 'hidden' AS _hidden, 'text ' FROM Person ORDER BY id LIMIT 1\n1.2.sql = SELECT '{{myAlias.hidden}}'");
+        $this->assertEquals("normal text hidden", $result);
+
         $result = $this->report->process("10.sql = SELECT 'normal ', 'hidden' AS _hidden, 'text ' FROM Person ORDER BY id LIMIT 1\n10.10.sql = SELECT '{{10.unknown}}'");
         $this->assertEquals("normal text {{10.unknown}}", $result);
 
+        // Report notation 'alias' with alias
+        $result = $this->report->process("1.sql = SELECT 'normal ', 'hidden' AS _hidden, 'text ' FROM Person ORDER BY id LIMIT 1\n1.2.sql = SELECT '{{myAlias.unknown}}'");
+        $this->assertEquals("normal text {{myAlias.unknown}}", $result);
+
         $result = $this->report->process("10.sql = SELECT 'normal ', 'hidden' AS _hidden, 'text ' FROM Person ORDER BY id LIMIT 1\n10.10.sql = SELECT '{{fake}}'");
         $this->assertEquals("normal text {{fake}}", $result);
 
@@ -1588,12 +1690,24 @@ EOF;
         $result = $this->report->process("10.sql = SELECT 'normal ', 'hidden' AS _hidden, 'text ' FROM Person ORDER BY id\n10.10.sql = SELECT '{{fake:V}}-{{10.line.count}}-{{10.line.total}}-{{10.line.insertId}} '");
         $this->assertEquals("normal text hello world -1-2-0 normal text hello world -2-2-0 ", $result);
 
+        // Report notation 'alias' with alias
+        $result = $this->report->process("1.sql = SELECT 'normal ', 'hidden' AS _hidden, 'text ' FROM Person ORDER BY id\n1.2.sql = SELECT '{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}} '");
+        $this->assertEquals("normal text hello world -1-2-0 normal text hello world -2-2-0 ", $result);
+
         $result = $this->report->process("10.sql = SELECT 'normal ', 'hidden' AS _hidden, 'text ' FROM Person ORDER BY id\n10.10.sql = SELECT '{{fake:V}}-{{10.line.count}}-{{10.line.total}} '");
         $this->assertEquals("normal text hello world -1-2 normal text hello world -2-2 ", $result);
 
+        // Report notation 'alias' with alias
+        $result = $this->report->process("1.sql = SELECT 'normal ', 'hidden' AS _hidden, 'text ' FROM Person ORDER BY id\n1.2.sql = SELECT '{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}} '");
+        $this->assertEquals("normal text hello world -1-2 normal text hello world -2-2 ", $result);
+
         $result = $this->report->process("10.sql = SELECT 'normal ', 'hidden' AS _hidden, 'text ' FROM Person ORDER BY id\n10.10.sql = SELECT '{{fake:V}}-{{10.line.count}}-{{10.line.total}}-{{10.10.line.count}}-{{10.10.line.total}} '");
         $this->assertEquals("normal text hello world -1-2-1-1 normal text hello world -2-2-1-1 ", $result);
 
+        // Report notation 'alias' with alias
+        $result = $this->report->process("1.sql = SELECT 'normal ', 'hidden' AS _hidden, 'text ' FROM Person ORDER BY id\n1.2.sql = SELECT '{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias2.line.count}}-{{myAlias2.line.total}} '");
+        $this->assertEquals("normal text hello world -1-2-1-1 normal text hello world -2-2-1-1 ", $result);
+
         $result = $this->report->process("10.sql = SELECT 'normal ', 'hidden' AS _hidden, 'text ' FROM Person ORDER BY id\n10.10.sql = SELECT '{{fake:V:::not found}} '");
         $this->assertEquals("normal text hello world  normal text hello world  ", $result);
 
@@ -1643,6 +1757,26 @@ EOF;
         $expect = "h:hello world-1-2-0,rb:hello world-1-2-0,-fb:hello world-1-2-0,Doe-fe:hello world-1-2-0,fs:hello world-1-2-0,-fb:hello world-1-2-0,John-fe:hello world-1-2-0,re:hello world-1-2-0,rr:hello world-1-2-0,rs:hello world-1-2-0,rb:hello world-2-2-0,-fb:hello world-2-2-0,Smith-fe:hello world-2-2-0,fs:hello world-2-2-0,-fb:hello world-2-2-0,Jane-fe:hello world-2-2-0,re:hello world-2-2-0,rr:hello world-2-2-0,t:hello world-2-2-0,";
         $this->assertEquals($expect, $result);
 
+        // Report notation 'alias' with alias
+        $line = <<<EOF
+1.sql = SELECT name, firstname FROM Person ORDER BY id LIMIT 2
+1.head = h:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+1.tail = t:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+1.rbeg = rb:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+1.rend = re:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+1.renr = rr:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+1.fbeg = -fb:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+1.fend = -fe:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+1.rsep = rs:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+1.fsep = fs:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+EOF;
+
+        $this->store->setVar('fake', 'hello world', STORE_VAR);
+        $this->store->setVar(TOKEN_ALIAS . '.1', 'myAlias', STORE_TYPO3);
+        $result = $this->report->process($line);
+        $expect = "h:hello world-1-2-0,rb:hello world-1-2-0,-fb:hello world-1-2-0,Doe-fe:hello world-1-2-0,fs:hello world-1-2-0,-fb:hello world-1-2-0,John-fe:hello world-1-2-0,re:hello world-1-2-0,rr:hello world-1-2-0,rs:hello world-1-2-0,rb:hello world-2-2-0,-fb:hello world-2-2-0,Smith-fe:hello world-2-2-0,fs:hello world-2-2-0,-fb:hello world-2-2-0,Jane-fe:hello world-2-2-0,re:hello world-2-2-0,rr:hello world-2-2-0,t:hello world-2-2-0,";
+        $this->assertEquals($expect, $result);
+
         $line = <<<EOF
 10.sql = SELECT name, firstname FROM Person ORDER BY id LIMIT 2
 10.10.sql = SELECT ' blue '
@@ -1662,6 +1796,26 @@ EOF;
         $expect = "DoeJohnh:hello world-1-2-0,rb:hello world-1-2-0,-fb:hello world-1-2-0, blue -fe:hello world-1-2-0,re:hello world-1-2-0,rr:hello world-1-2-0,t:hello world-1-2-0,SmithJaneh:hello world-2-2-0,rb:hello world-2-2-0,-fb:hello world-2-2-0, blue -fe:hello world-2-2-0,re:hello world-2-2-0,rr:hello world-2-2-0,t:hello world-2-2-0,";
         $this->assertEquals($expect, $result);
 
+        // Report notation 'alias' with alias
+        $line = <<<EOF
+1.sql = SELECT name, firstname FROM Person ORDER BY id LIMIT 2
+1.2.sql = SELECT ' blue '
+1.2.head = h:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+1.2.tail = t:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+1.2.rbeg = rb:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+1.2.rend = re:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+1.2.renr = rr:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+1.2.fbeg = -fb:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+1.2.fend = -fe:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+1.2.rsep = rs:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+1.2.fsep = fs:{{fake:V}}-{{myAlias.line.count}}-{{myAlias.line.total}}-{{myAlias.line.insertId}},
+EOF;
+
+        $this->store->setVar('fake', 'hello world', STORE_VAR);
+        $this->store->setVar(TOKEN_ALIAS . '.1', 'myAlias', STORE_TYPO3);
+        $result = $this->report->process($line);
+        $expect = "DoeJohnh:hello world-1-2-0,rb:hello world-1-2-0,-fb:hello world-1-2-0, blue -fe:hello world-1-2-0,re:hello world-1-2-0,rr:hello world-1-2-0,t:hello world-1-2-0,SmithJaneh:hello world-2-2-0,rb:hello world-2-2-0,-fb:hello world-2-2-0, blue -fe:hello world-2-2-0,re:hello world-2-2-0,rr:hello world-2-2-0,t:hello world-2-2-0,";
+        $this->assertEquals($expect, $result);
     }