diff --git a/doc/CODING.md b/doc/CODING.md
index c532510757c0b0bc87c1b6489cde2ddde729d2c6..ebba160ce9d07bbfb2c5d2add6d51eed373862ee 100644
--- a/doc/CODING.md
+++ b/doc/CODING.md
@@ -30,17 +30,23 @@ LOAD
   * (Report)
     * Process all <number>.[<number.>].sql statements
 
-* Access code variables:     
+* Access variables:     
   * active/valid formname: [$this->store->setVar(SYSTEM_FORM, $formName, STORE_SYSTEM);]
   * SIP: [$this->store->getVar('form', STORE_SIP)]
   * All parameters from active SIP:  [$this->store->getStore(STORE_SIP)]
-  * Check Contstants.php for known Store members: 
+  * Check Contstants.php for known Store *members*.
   
 * In QuickFormQuery.php the whole Form will be copied to `$this->formSpec` and depending on further processing, the 
-  elements are available in `$this->feNative` and `$this->feAction`.
-  * The Form specificaton (table form) will be evaluated direct after loading.
-  * The FormElement specification will be evaluated later on in BuildForm*.php
-
+  elements are available in `$this->feSpecNative` and `$this->feSpecAction`.
+  * The Form specificaton (table form) will be evaluated direct after loading (no `dynamicUpdate`).
+  * The FormElement specification will be evaluated later in BuildForm*.php:
+    * $formSpec, and root elements of $feSpecAction & $feSpecNative will be read in QuickFormQuery.php.
+    * AbstractBuildForm.php/BuildFormBootstrap.php receives a copy during instantiating of that class.
+    * Processing of FormElements in  AbstractBuildForm.php/BuildFormBootstrap.php typically do not change values, 
+      especially there is no evaluation, in $feSpecAction & $feSpecNative. 
+  * *Dynamic Update*: remember, an update(=Form load) is a complete new rendering of the form in that moment. All 
+    values/elements/notes/debug are fresh with the latest form content.  
+  
 * If a form is called without a SIP (form.permitNew='always'), than a SIP is created on the fly (as a 
   parameter in the form).
 * Uniq SIP for mutliple tabs with r=0  
@@ -59,6 +65,13 @@ LOAD
     AbstractBuildForm.php: process() > prepareT3VarsForSave() > Store.php: copyT3VarsToSip();
   * *Form save*:  FillStoreForm.php: process() > Store: fillTypo3StoreFromSip()   
 
+* Store: STORE_ADDITIONAL_FORM_ELEMENTS
+  * HTML 'hidden' elements, inside of a checkbox or radio input definition, might disturb Bootstrap CSS classes. 
+  * Therefore HTML elements like 'hidden' can be collected in STORE_ADDITIONAL_FORM_ELEMENTS.
+  * When the form will be composed of all single parts, the STORE_ADDITIONAL_FORM_ELEMENTS content will be arranged before
+    the regular INPUT Elements.
+  
+  
 * Formular zusammenbauen
   * QuickFormQuery: doForm > loadFormSpecification  - laedt den Form Record alle Form Elemente die nicht genested sind: 
     native, pill, fieldset, templateGroup >> $his->formNative.
diff --git a/extension/Documentation/AdministratorManual/Index.rst b/extension/Documentation/AdministratorManual/Index.rst
index 47d1ce3d45ede5efebcc15194f99082d583fe669..e6384cffcc56ee9ded663c41b1e328ba31cf9dad 100644
--- a/extension/Documentation/AdministratorManual/Index.rst
+++ b/extension/Documentation/AdministratorManual/Index.rst
@@ -14,6 +14,9 @@ Administrator Manual
 Preparation
 -----------
 
+Report & Form
+^^^^^^^^^^^^^
+
 The QFQ extension needs in PHP 5.x the PHP MySQL native driver. The following functions are used and are only available with the
 native driver (see also: http://dev.mysql.com/downloads/connector/php-mysqlnd/):
 
@@ -34,6 +37,34 @@ Preparation steps for Ubuntu 16.04::
 
 	sudo apt install php7.0-intl
 
+Print page via wkhtmltopdf
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Different browser prints the same page in different variations. To prevent this, QFQ implements a small PHP wrapper `print.php`
+which uses http://wkhtmltopdf.org/ (webkit based) to convert HTML to PDF. The converter is not included in QFQ and has
+to be manually installed.
+
+Hint: The Ubuntu package `wkhtmltopdf` needs a running Xserver - this does not work on a headless webserver. Best is to
+install the QT version from the named website above.
+
+In config.qfq.ini specify the:
+* installed `wkhtmltopdf` binary,
+* the site base URL.
+
+Provide a `print this page`-link (replace {current pageId})::
+
+	<a href="typo3conf/ext/qfq/qfq/api/print.php?id={current pageId}">Print this page</a>
+
+Any parameter specified after `print.php` will be delivered to `wkhtmltopdf` as part of the URL.
+
+Typoscript code to implement a print link on every page::
+
+	10 = TEXT
+	10 {
+		wrap = <a href="typo3conf/ext/qfq/qfq/api/print.php?id=|&type=2"><span class="glyphicon glyphicon-print" aria-hidden="true"></span> Printview</a>
+		data = page:uid
+	}
+
 Setup
 -----
 
@@ -162,7 +193,10 @@ config.qfq.ini
 +-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
 | FORM_BUTTON_ON_CHANGE_CLASS | FORM_BUTTON_ON_CHANGE_CLASS=alert-info btn-info | Color for save button after modification                           |
 +-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
-
+| BASE_URL_PRINT              | BASE_URL_PRINT=http://example.com       | URL where wkhtmltopdf will fetch the HTML (no parameter, those comes later)|
++-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
+| WKHTMLTOPDF                 | WKHTMLTOPDF=/usr/bin/wkhtmltopdf        | Binary where to find wkhtmltopdf                                           |
++-----------------------------+-----------------------------------------+----------------------------------------------------------------------------+
 
 
 Example: *typo3conf/config.qfq.ini*
@@ -190,6 +224,8 @@ Example: *typo3conf/config.qfq.ini*
 	;FORM_BS_LABEL_COLUMNS = 3
 	;FORM_BS_INPUT_COLUMNS = 6
 	;FORM_BS_NOTE_COLUMNS = 3
+	BASE_URL_PRINT=http://example.com
+	WKHTMLTOPDF=/usr/bin/wkhtmltopdf
 
 Documentation
 -------------
diff --git a/extension/Documentation/UsersManual/Index.rst b/extension/Documentation/UsersManual/Index.rst
index c85937386ce0cb82506813c6d4157e3f8b19587e..c766c13cc20f66f87c51796f347376676cd09840 100644
--- a/extension/Documentation/UsersManual/Index.rst
+++ b/extension/Documentation/UsersManual/Index.rst
@@ -234,7 +234,7 @@ Only variables that are known in a specified store can be substituted.
  +=====+========================================================================================+============================================================================+
  | F   | :ref:`STORE_FORM`: data not saved in database yet.                                     | All native *FormElements*. Recent values from the Browser.                 |
  +-----+----------------------------------------------------------------------------------------+----------------------------------------------------------------------------+
- | S   | :ref:`STORE_SIP`: Client parameter 's' will indicate the current SIP, which will be    | sip, r (record_id), form                                                   |
+ | S   | :ref:`STORE_SIP`: Client parameter 's' will indicate the current SIP, which will be    | sip, r (recordId), form                                                    |
  |     | loaded from the SESSION repo to the SIP-Store.                                         |                                                                            |
  +-----+----------------------------------------------------------------------------------------+----------------------------------------------------------------------------+
  | R   | :ref:`STORE_RECORD`: Record - the current record loaded in the form                    | All columns of the current record from the current table                   |
@@ -291,7 +291,7 @@ Store: *FORM* - F
  +---------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
  | Name                            | Explanation                                                                                                                                |
  +=================================+============================================================================================================================================+
- | <FormElement name>              | Name of native *FormElement*. To get, exactly and only, the specified *FormElement* (for 'p_id'): *{{p_id:F}}*                             |
+ | <FormElement name>              | Name of native *FormElement*. To get, exactly and only, the specified *FormElement* (for 'pId'): *{{pId:F}}*                             |
  +---------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------+
 
 .. _STORE_SIP:
@@ -333,7 +333,7 @@ Store: *RECORD* - R
  +------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
  | Name                   | Explanation                                                                                                                                      |
  +========================+==================================================================================================================================================+
- | <column name>          | Name of a column of the primary table (as defined in the current form). To get, exactly and only, the specified form *FormElement*: *{{p_id:R}}* |
+ | <column name>          | Name of a column of the primary table (as defined in the current form). To get, exactly and only, the specified form *FormElement*: *{{pId:R}}* |
  +------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
 
 .. _STORE_BEFORE:
@@ -350,7 +350,7 @@ This store is handy to compare new and old values of a form.
  +------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
  | Name                   | Explanation                                                                                                                                      |
  +========================+==================================================================================================================================================+
- | <column name>          | Name of a column of the primary table (as defined in the current form). To get, exactly and only, the specified form *FormElement*: *{{p_id:R}}* |
+ | <column name>          | Name of a column of the primary table (as defined in the current form). To get, exactly and only, the specified form *FormElement*: *{{pId:R}}* |
  +------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------+
 
 .. _STORE_CLIENT:
@@ -522,7 +522,7 @@ SQL Statement
 
   {{SELECT id, name FROM Person}}
   {{SELECT id, name, IF({{feUser}}=0,'Yes','No')  FROM Vorlesung WHERE sem_id={{keySemId:Y}} }}
-  {{SELECT id, city FROM Address AS adr WHERE adr.p_id={{SELECT id FROM Account AS acc WHERE acc.name={{feUser}} }} }}
+  {{SELECT id, city FROM Address AS adr WHERE adr.pId={{SELECT id FROM Account AS acc WHERE acc.name={{feUser}} }} }}
 
 * Special case for SELECT input fields. To deliver a result array specify an '!' before the SELECT: ::
 
@@ -834,7 +834,7 @@ Fields:
 |checkType      | enum('min|max', 'pattern',  |                                                                                                   |
 |               | 'number', 'email')          |                                                                                                   |
 +---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
-|checkPattern   | 'regexp'                    |If $check_type=='pattern': pattern to match                                                        |
+|checkPattern   | 'regexp'                    |If $checkType=='pattern': pattern to match                                                        |
 +---------------+-----------------------------+---------------------------------------------------------------------------------------------------+
 |onChange       | string                      |List of *FormElement*-names of current form, separated by ', ', If one of the named *FormElements* |
 |               |                             | change, reload own data / status / mode                                                           |
@@ -1561,20 +1561,20 @@ sqlBefore / sqlInsert / sqlUpdate / sqlDelete / sqlAfter
 Example
 '''''''
 
-Situation 1: master.x_id=slave.id (1:1)
+Situation 1: master.xId=slave.id (1:1)
 
- * Name the action element 'x_id': than {{slaveId}} will be automatically set to the value of 'master.x_id'
+ * Name the action element 'xId': than {{slaveId}} will be automatically set to the value of 'master.xId'
 
    * {{slaveId}} == 0 ? 'sqlInsert' will be fired.
    * {{slaveId}} != 0 ? 'sqlUpdate' will be fired.
 
- * In case of fireing 'sqlInsert', the 'slave.id' of the new created record are copied to master.x_id (the database will
+ * In case of fireing 'sqlInsert', the 'slave.id' of the new created record are copied to master.xId (the database will
      be updated automatically).
 
  * If the automatic update of the master record is not suitable, the action element should have no name or a name
      which does not exist as a column of the master record. Define  `slaveId={{SELECT id ...}}`
 
-Situation 2: master.id=slave.x_id (1:n)
+Situation 2: master.id=slave.xId (1:n)
 
  * Name the action element different to any columnname of the master record (or no name).
  * Determine the slaveId: `slaveId={{SELECT id FROM slave WHERE slave.xxx={{...}} LIMIT 1}}`
@@ -1716,10 +1716,10 @@ To display a report on any given TYPO3 page, create a content element of type 'Q
 A simple example
 ^^^^^^^^^^^^^^^^
 
-Assume that the database has a table person with columns first_name and last_name. To create a simple list of all persons, we can do the following:
+Assume that the database has a table person with columns firstName and lastName. To create a simple list of all persons, we can do the following:
 ::
 
-    10.sql = SELECT id AS person_id, CONCAT(first_name, " ", last_name, " ") AS name FROM person
+    10.sql = SELECT id AS pId, CONCAT(firstName, " ", lastName, " ") AS name FROM person
 
 10 Stands for a *root level* of the report (see section `Structure`_). 10.sql defines a SQL query for this specific level. When the query is executed it will return a result having one single column name containing first and last name
 separated by a space character.
@@ -1739,7 +1739,7 @@ However, we can modify (wrap) the output by setting the values of various keys f
 
 ::
 
-    10.sql = SELECT id AS person_id, CONCAT(first_name, " ", last_name, " ") AS name FROM person
+    10.sql = SELECT id AS personId, CONCAT(firstName, " ", lastName, " ") AS name FROM person
     10.sep = <br />
 
 HTML output:
@@ -1817,10 +1817,10 @@ See the example below:
 
 ::
 
-    10.sql = SELECT id AS _person_id, CONCAT(first_name, " ", last_name, " ") AS name FROM person
+    10.sql = SELECT id AS _pId, CONCAT(firstName, " ", lastName, " ") AS name FROM person
     10.rsep = <br />
 
-    10.10.sql = SELECT CONCAT(postal_code, " ", city) FROM address WHERE p_id = {{10.person_id}}
+    10.10.sql = SELECT CONCAT(postal_code, " ", city) FROM address WHERE pId = {{10.pId}}
     10.10.rbeg = (
     10.10.rend = )
 
@@ -1934,7 +1934,7 @@ Be careful to:
 Access to upper column values
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Columns of the upper level result can be accessed via variables, eg. {{10.person_id}} will be replaced by the value in the person_id column.
+Columns of the upper level result can be accessed via variables, eg. {{10.pId}} will be replaced by the value in the pId column.
 
 +-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 |**Levels**   |A report is divided into levels. Example 1 has 3 levels **10**, **20.25**, **20.25.10**                                                                                                                                      |
@@ -1965,10 +1965,10 @@ Report Example 1:
     10.sql = SELECT CURDATE()
 
     # Show all students from the person table
-    20.sql = SELECT p.id AS p_id, p.first_name, " - ", p.last_name FROM person AS p WHERE p.typ LIKE "student"
+    20.sql = SELECT p.id AS pId, p.firstName, " - ", p.lastName FROM person AS p WHERE p.typ LIKE "student"
 
     # Show all the marks from the current student ordered chronological
-    20.25.sql = SELECT e.mark FROM exam AS e WHERE e.p_id={{20.p_id}} ORDER BY e.date
+    20.25.sql = SELECT e.mark FROM exam AS e WHERE e.pId={{20.pId}} ORDER BY e.date
 
     # This query will never be fired, cause there is no direct parent called 20.30.
     20.30.10.sql = SELECT 'never fired'
@@ -2857,7 +2857,7 @@ Accessing the database
 ::
 
 
-    10.sql = SELECT p.first_name FROM exp_person AS p
+    10.sql = SELECT p.firstName FROM exp_person AS p
 
 ..
 
@@ -2879,7 +2879,7 @@ Accessing the database
 ::
 
 
-    10.sql = SELECT p.first_name, p.last_name FROM exp_person AS p
+    10.sql = SELECT p.firstName, p.lastName FROM exp_person AS p
 
 ..
 
@@ -2913,7 +2913,7 @@ Two columns
 
 
     # Add the formating information as a coloum
-    10.sql = SELECT p.first_name, " " , p.last_name, "'<br /'>" FROM exp_person AS p
+    10.sql = SELECT p.firstName, " " , p.lastName, "'<br /'>" FROM exp_person AS p
 
 ..
 
@@ -3014,29 +3014,29 @@ Two queries: nested with variables ::
     10.rend = <br />
 
     # inner query
-    10.10.sql = SELECT a.street FROM exp_address AS a WHERE a.pid='{{10.id}}'
+    10.10.sql = SELECT a.street FROM exp_address AS a WHERE a.pId='{{10.id}}'
     10.10.rend = <br />
 
 * For every record of '10', all assigned records of 10.10 will be printed.
 
 Two queries: nested with hidden variables in a table ::
 
-    10.sql = SELECT p.id AS _p_id, p.name FROM exp_person AS p
+    10.sql = SELECT p.id AS _pId, p.name FROM exp_person AS p
     10.rend = <br />
 
     # inner query
-    10.10.sql = SELECT a.street FROM exp_address AS a WHERE a.p_id='{{10.p_id}}'
+    10.10.sql = SELECT a.street FROM exp_address AS a WHERE a.pId='{{10.pId}}'
     10.10.rend = <br />
 
 Same as above, but written in the nested notation ::
 
   10 {
-    sql = SELECT p.id AS _p_id, p.name FROM exp_person AS p
+    sql = SELECT p.id AS _pId, p.name FROM exp_person AS p
     rend = <br />
 
     10 {
     # inner query
-      sql = SELECT a.street FROM exp_address AS a WHERE a.p_id='{{10.p_id}}'
+      sql = SELECT a.street FROM exp_address AS a WHERE a.pId='{{10.pId}}'
       rend = <br />
     }
   }
diff --git a/extension/RELEASE.txt b/extension/RELEASE.txt
index 4c829aa2551cc3e58e18f48be499677df7d434a2..5e252a995fd1ce3b6ab21ed9bcc9182a4c573cd6 100644
--- a/extension/RELEASE.txt
+++ b/extension/RELEASE.txt
@@ -12,6 +12,15 @@ Changes
        'pattern','allbut','all') NOT NULL DEFAULT 'alnumx'
 
 
+Features
+--------
+
+ * print.php
+
+   * Install `wkhtmltopdf` on the webserver (http://wkhtmltopdf.org/).
+   * In config.qfq.ini setup BASE_URL_PRINT, WKHTMLTOPDF.
+
+
 Bug Fixes
 ---------
 
diff --git a/extension/config.qfq.example.ini b/extension/config.qfq.example.ini
index 56ad6f37e6317563b8a703be05d8c0284beb98e3..9d1e9415a877cdb459b874b77f66914651cf49ea 100644
--- a/extension/config.qfq.example.ini
+++ b/extension/config.qfq.example.ini
@@ -41,3 +41,7 @@ DATE_FORMAT = yyyy-mm-dd
 ;FORM_BS_LABEL_COLUMNS = 3
 ;FORM_BS_INPUT_COLUMNS = 6
 ;FORM_BS_NOTE_COLUMNS = 3
+
+; Configure URL where `wkhtmltopdf` fetches pages and produces PDFs
+BASE_URL_PRINT = http://example.com/
+WKHTMLTOPDF = /opt/wkhtmltox/bin/wkhtmltopdf
diff --git a/extension/qfq/api/load.php b/extension/qfq/api/load.php
index c1ed3c1ba4559db9373e501ba3a26276429945bd..fcc474ec8b725e574484d8f13a3a5679ca2a3f3d 100644
--- a/extension/qfq/api/load.php
+++ b/extension/qfq/api/load.php
@@ -65,6 +65,8 @@ try {
     $answer[API_STATUS] = API_ANSWER_STATUS_SUCCESS;
     $answer[API_MESSAGE] = 'load: success';
     $answer[API_FORM_UPDATE] = $data;
+    $answer[API_ELEMENT_UPDATE] = $data[API_ELEMENT_UPDATE];
+    unset($data[API_ELEMENT_UPDATE]);
 
 } catch (qfq\UserFormException $e) {
     $answer[API_MESSAGE] = $e->formatMessage();
diff --git a/extension/qfq/api/print.php b/extension/qfq/api/print.php
new file mode 100644
index 0000000000000000000000000000000000000000..080a9c58d6fc9cb692335ce3daabc09770f87a2b
--- /dev/null
+++ b/extension/qfq/api/print.php
@@ -0,0 +1,137 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: ep
+ * Date: 12/23/15
+ * Time: 6:17 PM
+ */
+
+
+namespace qfq;
+
+use qfq;
+
+require_once(__DIR__ . '/../qfq/store/Config.php');
+require_once(__DIR__ . '/../qfq/Constants.php');
+require_once(__DIR__ . '/../qfq/helper/KeyValueStringParser.php');
+
+const PAGEID = 'id';
+const PARAM_GET = 'paramGet';
+const URL_PRINT = 'urlPrint';
+
+/**
+ * Create a temporary file.
+ *
+ * @return string
+ */
+function createEmptyFile() {
+    return tempnam(sys_get_temp_dir(), "webkitPrintPdf");
+}
+
+/**
+ * Set HTML Header to initiate PDF download.
+ *
+ * @param $filename
+ */
+function setHeader($filename) {
+
+    header("Content-Disposition: inline; filename=\"$filename\"");
+    header("Content-Type: application/pdf");
+    header("Content-Transfer-Encoding: binary");
+}
+
+/**
+ * Read QFQ config. Only SYSTEM_BASE_URL_PRINT and SYSTEM_WKHTMLTOPDF will be used.
+ * Check and get all clean _GET Parameter. Build a URL based on SYSTEM_BASE_URL_PRINT and the delivered URL params.
+ *
+ * @return array
+ * @throws UserFormException
+ * @throws \exception
+ */
+function init() {
+    $cfg = new Config();
+
+    $config = $cfg->readConfig('');
+    $param = readCleanGetParam();
+
+    if (!isset($config[SYSTEM_BASE_URL_PRINT]) || $config[SYSTEM_BASE_URL_PRINT] == '') {
+        throw new \exception(CONFIG_INI . ' - Missing ' . SYSTEM_BASE_URL_PRINT);
+    }
+
+    if (!isset($config[SYSTEM_WKHTMLTOPDF]) || $config[SYSTEM_WKHTMLTOPDF] == '') {
+        throw new \exception(CONFIG_INI . ' - Missing ' . SYSTEM_WKHTMLTOPDF);
+    }
+
+    if (!is_executable($config[SYSTEM_WKHTMLTOPDF])) {
+        throw new \exception(CONFIG_INI . ' - ' . SYSTEM_WKHTMLTOPDF . '=' . $config[SYSTEM_WKHTMLTOPDF] . ' - not found or not executable.');
+    }
+
+    if (!isset($param[PAGEID]) || $param[PAGEID] == '') {
+        throw new \exception("Missing GET Parameter '" . PAGEID . "'.");
+    }
+
+    $setup = array();
+    $setup[URL_PRINT] = $config[SYSTEM_BASE_URL_PRINT] . '/?' . KeyValueStringParser::unparse($param, '=', '&');
+    $setup[PAGEID] = $param[PAGEID];
+    $setup[SYSTEM_WKHTMLTOPDF] = $config[SYSTEM_WKHTMLTOPDF];
+
+    return $setup;
+}
+
+;
+
+/**
+ * Return an array with GET params who are clean - they do not violate $pattern.
+ *
+ * @return array
+ */
+function readCleanGetParam() {
+
+    $param = array();
+    $pattern = '^[\-_\.,;:\/a-zA-Z0-9]*$'; // ':alnum:' does not work here in FF
+
+    foreach ($_GET as $key => $value) {
+        if (preg_match("/$pattern/", $value) === 1) {
+            $param[$key] = $value;
+        }
+    }
+
+    return $param;
+}
+
+/**
+ * @param array $setup
+ * @throws \exception
+ */
+function page2pdf($setup) {
+
+    $rc = 0;
+    $file = createEmptyFile();
+
+    $cmd = $setup[SYSTEM_WKHTMLTOPDF] . " '" . $setup[URL_PRINT] . "' " . $file . " > $file.log 2>&1";
+
+    $line = system($cmd, $rc);
+
+    if ($rc == 0) {
+        setHeader('print.' . $setup[PAGEID] . '.pdf');
+        @readfile($file);
+        @unlink($file);
+        @unlink($file . '.log');
+        exit; // Do an extremely hard exit here to make sure there are no more additional bytes sent (makes the delivered PDF unusable).
+    } else {
+        throw new \exception("Error [RC=$rc] $line: $cmd");
+    }
+}
+
+
+/**
+ * Main
+ */
+try {
+    $setup = init();
+
+    page2pdf($setup);
+
+} catch (\Exception $e) {
+    echo "Exception: " . $e->getMessage();
+}
diff --git a/extension/qfq/qfq/AbstractBuildForm.php b/extension/qfq/qfq/AbstractBuildForm.php
index d1272a7bbe0e83a8bee8e91150ac88bc2508ce97..686236080eb4ed116b55fc3b02673a81c95674bd 100644
--- a/extension/qfq/qfq/AbstractBuildForm.php
+++ b/extension/qfq/qfq/AbstractBuildForm.php
@@ -23,7 +23,6 @@ require_once(__DIR__ . '/../qfq/helper/Support.php');
 require_once(__DIR__ . '/../qfq/helper/OnArray.php');
 require_once(__DIR__ . '/../qfq/report/Link.php');
 
-
 /**
  * Class AbstractBuildForm
  * @package qfq
@@ -186,10 +185,11 @@ abstract class AbstractBuildForm {
             $htmlTail = $this->tail();
             $htmlSubrecords = $this->doSubrecords();
         }
+        $htmlHidden = $this->buildAdditionalFormElements();
 
         $htmlSip = $this->buildHiddenSip($json);
 
-        return ($mode === FORM_LOAD) ? $htmlHead . $htmlElements . $htmlSip . $htmlT3vars . $htmlTail . $htmlSubrecords : $json;
+        return ($mode === FORM_LOAD) ? $htmlHead . $htmlHidden . $htmlElements . $htmlSip . $htmlT3vars . $htmlTail . $htmlSubrecords : $json;
     }
 
     /**
@@ -330,7 +330,7 @@ abstract class AbstractBuildForm {
     abstract public function getProcessFilter();
 
     /**
-     * Process all FormElements: build corresponding HTML code. Collect and return all HTML code & JSON.
+     * Process all FormElements: Collect and return all HTML code & JSON.
      *
      * @param $recordId
      * @param string $filter FORM_ELEMENTS_NATIVE | FORM_ELEMENTS_SUBRECORD | FORM_ELEMENTS_NATIVE_SUBRECORD
@@ -351,7 +351,7 @@ abstract class AbstractBuildForm {
         $html = '';
         $flagOutput = false;
 
-        // The following 'FormElement.parameter' will never be used during load (fe.type='upload').
+        // The following 'FormElement.parameter' will never be used during load (fe.type='upload'). FE_PARAMETER has been already expanded.
         $skip = [FE_SQL_UPDATE, FE_SQL_INSERT, FE_SQL_DELETE, FE_SQL_AFTER, FE_SQL_BEFORE, FE_PARAMETER];
 
         // get current data record
@@ -420,6 +420,7 @@ abstract class AbstractBuildForm {
             $buildElementFunctionName = 'build' . $this->buildElementFunctionName[$formElement[FE_TYPE]];
 
             $jsonElement = array();
+            $elementExtra = '';
             // Render pure element
             $elementHtml = $this->$buildElementFunctionName($formElement, $htmlFormElementName, $value, $jsonElement, $mode);
 
@@ -539,6 +540,20 @@ abstract class AbstractBuildForm {
 
     abstract public function doSubrecords();
 
+    /**
+     * Get all elements from STORE_ADDITIONAL_FORM_ELEMENTS and return them as a string.
+     *
+     * @return string
+     * @throws CodeException
+     * @throws \qfq\UserFormException
+     */
+    private function buildAdditionalFormElements() {
+
+        $data = $this->store->getStore(STORE_ADDITIONAL_FORM_ELEMENTS);
+
+        return is_array($data) ? implode('', $data) : '';
+    }
+
     /**
      * Create a hidden sip, based on latest STORE_SIP Values. Return complete HTML 'hidden' element.
      *
@@ -560,26 +575,38 @@ abstract class AbstractBuildForm {
 
         $sipValue = $sip->queryStringToSip($queryString, RETURN_SIP);
 
-        $json[] = $this->getJsonElementUpdate(CLIENT_SIP, $sipValue, FE_MODE_SHOW);
+        $json[] = $this->getFormElementForJson(CLIENT_SIP, $sipValue, [FE_MODE => FE_MODE_SHOW]);
 
         return $this->buildNativeHidden(CLIENT_SIP, $sipValue);
     }
 
     /**
-     * Create an array with standard elements and add 'form-element', 'value'.
+     * Create an array with standard elements for 'mode' (hidden, disabled, required) and add 'form-element', 'value'.
+     * 'Generic Element Update': add via API_ELEMENT_UPDATE 'label' and 'note'.
+     * All collected data as array - will be later converted to JSON.
      *
-     * @param $htmlFormElementName
+     * @param string $htmlFormElementName
      * @param string|array $value
-     * @param string $feMode disabled|readonly|''
+     * @param array $formElement
      * @return array
      */
-    private function getJsonElementUpdate($htmlFormElementName, $value, $feMode) {
+    private function getFormElementForJson($htmlFormElementName, $value, array $formElement) {
 
-        $json = $this->getJsonFeMode($feMode);
+        $json = $this->getJsonFeMode($formElement[FE_MODE]);
 
         $json['form-element'] = $htmlFormElementName;
         $json['value'] = $value;
 
+        if (isset($formElement[FE_LABEL])) {
+            $key = $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_LABEL;
+            $json[API_ELEMENT_UPDATE][$key][API_ELEMENT_CONTENT] = $this->buildLabel($htmlFormElementName, $formElement[FE_LABEL]);
+        }
+
+        if (isset($formElement[FE_NOTE])) {
+            $key = $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_NOTE;
+            $json[API_ELEMENT_UPDATE][$key][API_ELEMENT_CONTENT] = $formElement[FE_NOTE];
+        }
+
         return $json;
     }
 
@@ -629,6 +656,22 @@ abstract class AbstractBuildForm {
         }
     }
 
+    /**
+     * Builds a label, typically for an html-'<input>'-element.
+     *
+     * @param string $htmlFormElementName
+     * @param string $label
+     * @return string
+     */
+    public function buildLabel($htmlFormElementName, $label) {
+        $attributes = Support::doAttribute('for', $htmlFormElementName);
+        $attributes .= Support::doAttribute('class', 'control-label');
+
+        $html = Support::wrapTag("<label $attributes>", $label);
+
+        return $html;
+    }
+
     /**
      * Takes the current SIP ('form' and additional parameter), set SIP_RECORD_ID=0 and create a new 'NewRecordUrl'.
      *
@@ -664,22 +707,6 @@ abstract class AbstractBuildForm {
 
     abstract public function buildRowSubrecord(array $formElement, $elementHtml);
 
-    /**
-     * Builds a label, typically for an html-'<input>'-element.
-     *
-     * @param string $htmlFormElementName
-     * @param string $label
-     * @return string
-     */
-    public function buildLabel($htmlFormElementName, $label) {
-        $attributes = Support::doAttribute('for', $htmlFormElementName);
-        $attributes .= Support::doAttribute('class', 'control-label');
-
-        $html = Support::wrapTag("<label $attributes>", $label);
-
-        return $html;
-    }
-
     /**
      * Builds HTML 'input' element.
      * Format: <input name="$htmlFormElementName" <type="email|input|password|url" [autocomplete="autocomplete"] [autofocus="autofocus"]
@@ -741,7 +768,7 @@ abstract class AbstractBuildForm {
 
         $attribute .= $this->getAttributeFeMode($formElement[FE_MODE]);
 
-        $json = $this->getJsonElementUpdate($htmlFormElementName, $value, $formElement[FE_MODE]);
+        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
 
         return "$htmlTag $attribute>$textarea" . $this->getHelpBlock();
 
@@ -1234,7 +1261,9 @@ abstract class AbstractBuildForm {
         $attribute .= $this->getAttributeList($formElement, ['autofocus']);
         $attribute .= $this->getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
 
-        $html = $this->buildNativeHidden($htmlFormElementName, $formElement['unchecked']);
+        $htmlHidden = $this->buildNativeHidden($htmlFormElementName, $formElement['unchecked']);
+        $this->store->setVar($htmlFormElementName, $htmlHidden, STORE_ADDITIONAL_FORM_ELEMENTS, false);
+        $html = '';
 
         $htmlElement = '<input ' . $attribute . '>';
         if (isset($formElement['label2'])) {
@@ -1247,7 +1276,7 @@ abstract class AbstractBuildForm {
             $htmlElement, true);
         $html = Support::wrapTag('<div class="btn-group" data-toggle="buttons">', $html);
 
-        $json = $this->getJsonElementUpdate($htmlFormElementName, $valueJson, $formElement[FE_MODE]);
+        $json = $this->getFormElementForJson($htmlFormElementName, $valueJson, $formElement);
 
         return $html;
     }
@@ -1286,7 +1315,9 @@ abstract class AbstractBuildForm {
         $attribute .= $this->getAttributeList($formElement, ['autofocus']);
         $attribute .= $this->getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
 
-        $html = $this->buildNativeHidden($htmlFormElementName, $formElement['unchecked']);
+        $htmlHidden = $this->buildNativeHidden($htmlFormElementName, $formElement['unchecked']);
+        $this->store->setVar($htmlFormElementName, $htmlHidden, STORE_ADDITIONAL_FORM_ELEMENTS, false);
+        $html = '';
 
         $html .= '<input ' . $attribute . '>';
         if (isset($formElement['label2'])) {
@@ -1296,7 +1327,7 @@ abstract class AbstractBuildForm {
         $html = Support::wrapTag("<label>", $html, true);
         $html = Support::wrapTag("<div class='checkbox'>", $html, true);
 
-        $json = $this->getJsonElementUpdate($htmlFormElementName, $valueJson, $formElement[FE_MODE]);
+        $json = $this->getFormElementForJson($htmlFormElementName, $valueJson, $formElement);
 
         return $html;
     }
@@ -1351,7 +1382,11 @@ abstract class AbstractBuildForm {
         $attributeBase .= Support::doAttribute('data-load', ($formElement[FE_DYNAMIC_UPDATE] === 'yes') ? 'data-load' : '');
         $attributeBase .= $this->getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
 
-        $html = $this->buildNativeHidden(HelperFormElement::prependFormElementNameCheckBoxMulti($htmlFormElementName, 'h'), '');
+        $key = HelperFormElement::prependFormElementNameCheckBoxMulti($htmlFormElementName, 'h');
+        $htmlHidden = $this->buildNativeHidden($key, '');
+        $this->store->setVar($htmlFormElementName, $htmlHidden, STORE_ADDITIONAL_FORM_ELEMENTS, false);
+
+        $html = '';
 
         $attribute = $attributeBase;
         if (isset($formElement['autofocus'])) {
@@ -1382,7 +1417,7 @@ abstract class AbstractBuildForm {
             $html .= Support::wrapTag("<label class='btn " . $formElement[FE_BUTTON_CLASS] . "$classActive'>",
                 $htmlElement, true);
 
-            $json[] = $this->getJsonElementUpdate($htmlFormElementNameUniq, $jsonValue, $formElement[FE_MODE]);
+            $json[] = $this->getFormElementForJson($htmlFormElementNameUniq, $jsonValue, $formElement);
 
             // Init for the next checkbox
             $attribute = $attributeBase;
@@ -1417,7 +1452,11 @@ abstract class AbstractBuildForm {
         $attributeBase .= Support::doAttribute('data-load', ($formElement[FE_DYNAMIC_UPDATE] === 'yes') ? 'data-load' : '');
         $attributeBase .= $this->getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
 
-        $html = $this->buildNativeHidden(HelperFormElement::prependFormElementNameCheckBoxMulti($htmlFormElementName, 'h'), '');
+        $key = HelperFormElement::prependFormElementNameCheckBoxMulti($htmlFormElementName, 'h');
+        $htmlHidden = $this->buildNativeHidden($key, '');
+        $this->store->setVar($htmlFormElementName, $htmlHidden, STORE_ADDITIONAL_FORM_ELEMENTS, false);
+
+        $html = '';
 
         $orientation = ($formElement[FE_MAX_LENGTH] > 1) ? ALIGN_HORIZONTAL : ALIGN_VERTICAL;
         $checkboxClass = ($orientation === ALIGN_HORIZONTAL) ? 'checkbox-inline' : 'checkbox';
@@ -1470,7 +1509,7 @@ abstract class AbstractBuildForm {
             }
 
             $html .= $htmlElement . $br;
-            $json[] = $this->getJsonElementUpdate($htmlFormElementNameUniq, $jsonValue, $formElement[FE_MODE]);
+            $json[] = $this->getFormElementForJson($htmlFormElementNameUniq, $jsonValue, $formElement);
 
         }
 
@@ -1582,8 +1621,10 @@ abstract class AbstractBuildForm {
             $attribute .= Support::doAttribute('autofocus', $formElement['autofocus']);
         }
 
-        $html = $this->buildNativeHidden($htmlFormElementName, $value);
+        $htmlHidden = $this->buildNativeHidden($htmlFormElementName, $value);
+        $this->store->setVar($htmlFormElementName, $htmlHidden, STORE_ADDITIONAL_FORM_ELEMENTS, false);
 
+        $html = '';
         for ($ii = 0; $ii < count($itemValue); $ii++) {
             $classActive = '';
 
@@ -1607,7 +1648,7 @@ abstract class AbstractBuildForm {
 
         $html = Support::wrapTag('<div class="btn-group" data-toggle="buttons">', $html);
 
-        $json = $this->getJsonElementUpdate($htmlFormElementName, $value, $formElement[FE_MODE]);
+        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
 
         return $html;
     }
@@ -1660,6 +1701,7 @@ abstract class AbstractBuildForm {
             $attribute .= Support::doAttribute('autofocus', $formElement['autofocus']);
         }
 
+
         $html = $this->buildNativeHidden($htmlFormElementName, $value);
 
         for ($ii = 0; $ii < count($itemValue); $ii++) {
@@ -1699,7 +1741,7 @@ abstract class AbstractBuildForm {
             $attribute = $attributeBase;
         }
 
-        $json = $this->getJsonElementUpdate($htmlFormElementName, $value, $formElement[FE_MODE]);
+        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
 
         return $html;
     }
@@ -1760,7 +1802,7 @@ abstract class AbstractBuildForm {
             $option .= '>' . $itemValue[$ii] . '</option>';
         }
 
-        $json = $this->getJsonElementUpdate($htmlFormElementName, $jsonValues, $formElement[FE_MODE]);
+        $json = $this->getFormElementForJson($htmlFormElementName, $jsonValues, $formElement);
 
         return '<select ' . $attribute . '>' . $option . '</select>' . $this->getHelpBlock();
     }
@@ -2226,7 +2268,7 @@ abstract class AbstractBuildForm {
 
 //        <button type="button" class="file-delete" data-sip="571d1fc9e6974"><span class="glyphicon glyphicon-trash"></span></button>
 
-        $json = $this->getJsonElementUpdate($htmlFormElementName, $value, $formElement[FE_MODE]);
+        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
 
         return $htmlTextDelete . $htmlInputFile . $hiddenSipUpload;
     }
@@ -2329,7 +2371,7 @@ abstract class AbstractBuildForm {
 
         $attribute .= $this->getAttributeFeMode($formElement[FE_MODE]);
 
-        $json = $this->getJsonElementUpdate($htmlFormElementName, $value, $formElement[FE_MODE]);
+        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
 
         return "<input $attribute>" . $this->getHelpBlock();
 
@@ -2461,7 +2503,7 @@ abstract class AbstractBuildForm {
         $attribute .= $this->getAttributeFeMode($formElement[FE_MODE]);
         $attribute .= $this->getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
 
-        $json = $this->getJsonElementUpdate($htmlFormElementName, $value, $formElement[FE_MODE]);
+        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
 
         $element = Support::wrapTag("<textarea $attribute>", htmlentities($value), false);
 
@@ -2642,7 +2684,7 @@ abstract class AbstractBuildForm {
         // restore parent processed FE's
         $this->feSpecNative = $tmpStore;
 
-        $json = $this->getJsonElementUpdate($htmlFormElementName, $value, $formElement[FE_MODE]);
+        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
 
         return $html;
     }
diff --git a/extension/qfq/qfq/BuildFormBootstrap.php b/extension/qfq/qfq/BuildFormBootstrap.php
index fcd0467d3e74558515be35c36d0bd460da71c5d0..5455a18122c23073166cc619bc9d2139f62afcbe 100644
--- a/extension/qfq/qfq/BuildFormBootstrap.php
+++ b/extension/qfq/qfq/BuildFormBootstrap.php
@@ -79,7 +79,7 @@ class BuildFormBootstrap extends AbstractBuildForm {
         $this->wrap[WRAP_SETUP_LABEL][WRAP_SETUP_END] = "</div>";
         $this->wrap[WRAP_SETUP_INPUT][WRAP_SETUP_START] = "<div class='col-md-$input'>";
         $this->wrap[WRAP_SETUP_INPUT][WRAP_SETUP_END] = "</div>";
-        $this->wrap[WRAP_SETUP_NOTE][WRAP_SETUP_START] = "<div class='col-md-$note'>";
+        $this->wrap[WRAP_SETUP_NOTE][WRAP_SETUP_START] = "<div class='col-md-$note qfq-note'>";
         $this->wrap[WRAP_SETUP_NOTE][WRAP_SETUP_END] = "</div>";
 
     }
@@ -321,8 +321,8 @@ class BuildFormBootstrap extends AbstractBuildForm {
      * @return string
      */
     public function tail() {
+
         $html = '';
-//        $html .= $this->buildNewSip();
         $deleteUrl = '';
 
         $formId = $this->getFormId();
@@ -416,6 +416,7 @@ EOF;
         $html = '';
         $htmlLabel = '';
 
+        // Label
         if ($formElement[FE_BS_LABEL_COLUMNS] > 0) {
             $htmlLabel = $this->buildLabel($htmlFormElementName, $formElement[FE_LABEL]);
         }
@@ -423,10 +424,13 @@ EOF;
         $html .= $this->customWrap($formElement, $htmlLabel, FE_WRAP_LABEL, $formElement[FE_BS_LABEL_COLUMNS],
             [$this->wrap[WRAP_SETUP_LABEL][WRAP_SETUP_START], $this->wrap[WRAP_SETUP_LABEL][WRAP_SETUP_END]], $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_LABEL);
 
+        // Input
         $html .= $this->customWrap($formElement, $htmlElement, FE_WRAP_INPUT, $formElement[FE_BS_INPUT_COLUMNS],
             [$this->wrap[WRAP_SETUP_INPUT][WRAP_SETUP_START], $this->wrap[WRAP_SETUP_INPUT][WRAP_SETUP_END]], $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_INPUT);
 
-        $note = Support::wrapTag("<div class='qfq-note'>", $formElement[FE_NOTE], true);
+        // Note
+//        $note = Support::wrapTag("<div class='qfq-note'>", $formElement[FE_NOTE], true);
+        $note = $formElement[FE_NOTE];
         $html .= $this->customWrap($formElement, $note, FE_WRAP_NOTE, $formElement[FE_BS_NOTE_COLUMNS],
             [$this->wrap[WRAP_SETUP_NOTE][WRAP_SETUP_START], $this->wrap[WRAP_SETUP_NOTE][WRAP_SETUP_END]], $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_NOTE);
 
diff --git a/extension/qfq/qfq/Constants.php b/extension/qfq/qfq/Constants.php
index ac4df036e16bb4e4d294e67d676587fc7b189e5c..727f712eacb8b833e7464ae119f29c5110c690ee 100644
--- a/extension/qfq/qfq/Constants.php
+++ b/extension/qfq/qfq/Constants.php
@@ -238,8 +238,10 @@ const STORE_ZERO = "0"; // value: 0, might helpfull if variable is empty but use
 const STORE_EMPTY = "E"; // value: '', might helpfull if variable is not defined and should result in an empty string instead of {{...}} (cause not replaced)
 const STORE_SYSTEM = "Y"; // various system values like db connection credentials
 const STORE_EXTRA = 'X'; // Persistent Store: contains arrays! Not Usefull for user. Used by system.
+const STORE_ADDITIONAL_FORM_ELEMENTS = 'A'; // Internal Store to collect FormElements. Typically for 'hidden' elements of radio and checkbox. Helps render those elements at the end of the whole form rendering.
 
 const STORE_USE_DEFAULT = "FSRVD";
+
 //
 // Store: Definitions / Members
 //
@@ -320,6 +322,9 @@ const SYSTEM_FORM_BS_NOTE_COLUMNS = 'FORM_BS_NOTE_COLUMNS';
 
 const SYSTEM_FORM_BUTTON_ON_CHANGE_CLASS = 'FORM_BUTTON_ON_CHANGE_CLASS';
 
+const SYSTEM_BASE_URL_PRINT = 'BASE_URL_PRINT';
+const SYSTEM_WKHTMLTOPDF = 'WKHTMLTOPDF';
+
 // computed automatically during runtime
 const SYSTEM_PATH_EXT = 'EXT_PATH';
 const SYSTEM_SITE_PATH = 'SITE_PATH';
@@ -419,6 +424,8 @@ const API_FIELD_NAME = 'field-name';
 const API_FIELD_MESSAGE = 'field-message';
 const API_FORM_UPDATE = 'form-update';
 const API_ELEMENT_UPDATE = 'element-update';
+const API_ELEMENT_ATTRIBUTE = 'attr';
+const API_ELEMENT_CONTENT = 'content';
 
 const API_JSON_HIDDEN = 'hidden';
 const API_JSON_DISABLED = 'disabled';
diff --git a/extension/qfq/qfq/QuickFormQuery.php b/extension/qfq/qfq/QuickFormQuery.php
index a29eb279e42b13e49bac910b739157a51106976d..92d406d7b083e832b948c1f2dd711bfc67381198 100644
--- a/extension/qfq/qfq/QuickFormQuery.php
+++ b/extension/qfq/qfq/QuickFormQuery.php
@@ -117,7 +117,6 @@ class QuickFormQuery {
      * @param bool $phpUnit
      * @throws CodeException
      * @throws UserFormException
-     * @internal param string $bodytext
      */
     public function __construct(array $t3data = array(), $phpUnit = false) {
 
@@ -344,6 +343,9 @@ class QuickFormQuery {
                 throw new CodeException("This statement should never be reached", ERROR_CODE_SHOULD_NOT_HAPPEN);
         }
 
+        if (is_array($data)) {
+            $data = $this->groupElementUpdateEntries($data);
+        }
         return $data;
     }
 
@@ -697,6 +699,30 @@ class QuickFormQuery {
 
     }
 
+    /**
+     * Searches the whole array $dataArray on the second level for API_ELEMENT_UPDATE.
+     * All found elements collect under $collect[API_ELEMENT_UPDATE]... . Leave the rest unchanged.
+     *
+     * @param array $dataArray
+     * @return array to build JSON
+     */
+    private function groupElementUpdateEntries(array $dataArray) {
+        $collect = array();
+
+        foreach ($dataArray as $data) {
+
+            if (isset($data[API_ELEMENT_UPDATE])) {
+                foreach ($data[API_ELEMENT_UPDATE] as $key => $item) {
+                    $collect[API_ELEMENT_UPDATE][$key] = $item;
+                }
+                unset($data[API_ELEMENT_UPDATE]);
+            }
+            $collect[] = $data;
+        }
+
+        return $collect;
+    }
+
     /**
      * Process the SQL Queries from bodytext. Return the output.
      *
diff --git a/extension/qfq/qfq/store/Config.php b/extension/qfq/qfq/store/Config.php
new file mode 100644
index 0000000000000000000000000000000000000000..fe646b5ebbc39cb0d2d9370da61e9aa758b14fb2
--- /dev/null
+++ b/extension/qfq/qfq/store/Config.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: crose
+ * Date: 3/6/17
+ * Time: 8:47 PM
+ */
+
+namespace qfq;
+
+use qfq;
+
+require_once(__DIR__ . '/../../qfq/Constants.php');
+
+class Config {
+
+    /**
+     * Read config.qfq.ini.
+     *
+     * @throws CodeException
+     * @throws qfq\UserFormException
+     */
+
+    public function readConfig($fileConfigIni = '') {
+
+        if ($fileConfigIni == '') {
+            // Production Path to CONFIG_INI
+            $fileConfigIni = __DIR__ . '/../../../../../' . CONFIG_INI;
+            if (!file_exists($fileConfigIni)) {
+                // PHPUnit Path to CONFIG_INI
+                $fileConfigIni = __DIR__ . '/../../../' . CONFIG_INI;
+            }
+        }
+
+        try {
+            $config = parse_ini_file($fileConfigIni, false);
+
+        } catch (\Exception $e) {
+            throw new qfq\UserFormException ("Error read file " . $fileConfigIni . ": " . $e->getMessage(), ERROR_IO_READ_FILE);
+        }
+
+        $config = self::renameConfigElements($config);
+
+        return $config;
+    }
+
+    /**
+     * Rename Elements defined in config.qfq.ini to more appropriate in user interaction.
+     * E.g.: in config.qfq.ini everything is in upper case and word space is '_'. In Form.parameter it's lowercase and camel hook.
+     *
+     * @param array $config
+     * @return array
+     */
+    private static function renameConfigElements(array $config) {
+
+        // oldname > newname
+        $setting = [
+            [SYSTEM_FORM_BS_LABEL_COLUMNS, F_BS_LABEL_COLUMNS],
+            [SYSTEM_FORM_BS_INPUT_COLUMNS, F_BS_INPUT_COLUMNS],
+            [SYSTEM_FORM_BS_NOTE_COLUMNS, F_BS_NOTE_COLUMNS],
+            [SYSTEM_FORM_DATA_PATTERN_ERROR, F_FE_DATA_PATTERN_ERROR],
+            [SYSTEM_FORM_DATA_REQUIRED_ERROR, F_FE_DATA_REQUIRED_ERROR],
+            [SYSTEM_FORM_DATA_MATCH_ERROR, F_FE_DATA_MATCH_ERROR],
+            [SYSTEM_FORM_DATA_ERROR, F_FE_DATA_ERROR],
+            [SYSTEM_CSS_CLASS_QFQ_FORM, F_CLASS],
+            [SYSTEM_CSS_CLASS_QFQ_FORM_PILL, F_CLASS_PILL],
+            [SYSTEM_CSS_CLASS_QFQ_FORM_BODY, F_CLASS_BODY],
+            [SYSTEM_FORM_BUTTON_ON_CHANGE_CLASS, F_BUTTON_ON_CHANGE_CLASS],
+        ];
+
+        foreach ($setting as $row) {
+            $oldName = $row[0];
+            $newName = $row[1];
+
+            if (isset($config[$oldName])) {
+                $config[$newName] = $config[$oldName];
+                if ($oldName != $newName) {
+                    unset($config[$oldName]);
+                }
+            }
+        }
+
+        return $config;
+    }
+
+}
\ No newline at end of file
diff --git a/extension/qfq/qfq/store/Store.php b/extension/qfq/qfq/store/Store.php
index 9a4ebfbc2d368eb6d86ac4c1ee0e2931b81de2af..ea95f84f3f5b0faa6ae2310a6bf11d83540f3beb 100644
--- a/extension/qfq/qfq/store/Store.php
+++ b/extension/qfq/qfq/store/Store.php
@@ -19,6 +19,7 @@ require_once(__DIR__ . '/../../qfq/Constants.php');
 require_once(__DIR__ . '/../../qfq/store/Sip.php');
 //require_once(__DIR__ . '/../../qfq/store/Session.php');
 require_once(__DIR__ . '/../../qfq/Database.php');
+require_once(__DIR__ . '/../../qfq/store/Config.php');
 
 /*
  * Stores:
@@ -163,7 +164,8 @@ class Store {
             STORE_ZERO => false,
             STORE_EMPTY => false,
             STORE_SYSTEM => false,
-            STORE_EXTRA => false
+            STORE_EXTRA => false,
+            STORE_ADDITIONAL_FORM_ELEMENTS => false
         ];
 
         self::fillSystemStore($fileConfigIni);
@@ -181,23 +183,8 @@ class Store {
      */
     private static function fillSystemStore($fileConfigIni = '') {
 
-        if ($fileConfigIni == '') {
-            // Production Path to CONFIG_INI
-            $fileConfigIni = __DIR__ . '/../../../../../' . CONFIG_INI;
-            if (!file_exists($fileConfigIni)) {
-                // PHPUnit Path to CONFIG_INI
-                $fileConfigIni = __DIR__ . '/../../../' . CONFIG_INI;
-            }
-        }
-
-        try {
-            $config = parse_ini_file($fileConfigIni, false);
-
-        } catch (\Exception $e) {
-            throw new qfq\UserFormException ("Error read file " . $fileConfigIni . ": " . $e->getMessage(), ERROR_IO_READ_FILE);
-        }
-
-        $config = self::renameConfigElements($config);
+        $cfg = new Config();
+        $config = $cfg->readConfig($fileConfigIni);
 
         // Defaults
         Support::setIfNotSet($config, SYSTEM_DATE_FORMAT, 'yyyy-mm-dd');
@@ -218,45 +205,6 @@ class Store {
         self::setStore($config, STORE_SYSTEM, true);
     }
 
-    /**
-     * Rename Elements defined in config.qfq.ini to more appropriate in user interaction.
-     * E.g.: in config.qfq.ini everything is in upper case and word space is '_'. In Form.parameter it's lowercase and camel hook.
-     *
-     * @param array $config
-     * @return array
-     */
-    private static function renameConfigElements(array $config) {
-
-        // oldname > newname
-        $setting = [
-            [SYSTEM_FORM_BS_LABEL_COLUMNS, F_BS_LABEL_COLUMNS],
-            [SYSTEM_FORM_BS_INPUT_COLUMNS, F_BS_INPUT_COLUMNS],
-            [SYSTEM_FORM_BS_NOTE_COLUMNS, F_BS_NOTE_COLUMNS],
-            [SYSTEM_FORM_DATA_PATTERN_ERROR, F_FE_DATA_PATTERN_ERROR],
-            [SYSTEM_FORM_DATA_REQUIRED_ERROR, F_FE_DATA_REQUIRED_ERROR],
-            [SYSTEM_FORM_DATA_MATCH_ERROR, F_FE_DATA_MATCH_ERROR],
-            [SYSTEM_FORM_DATA_ERROR, F_FE_DATA_ERROR],
-            [SYSTEM_CSS_CLASS_QFQ_FORM, F_CLASS],
-            [SYSTEM_CSS_CLASS_QFQ_FORM_PILL, F_CLASS_PILL],
-            [SYSTEM_CSS_CLASS_QFQ_FORM_BODY, F_CLASS_BODY],
-            [SYSTEM_FORM_BUTTON_ON_CHANGE_CLASS, F_BUTTON_ON_CHANGE_CLASS],
-        ];
-
-        foreach ($setting as $row) {
-            $oldName = $row[0];
-            $newName = $row[1];
-
-            if (isset($config[$oldName])) {
-                $config[$newName] = $config[$oldName];
-                if ($oldName != $newName) {
-                    unset($config[$oldName]);
-                }
-            }
-        }
-
-        return $config;
-    }
-
     /**
      * QFQ might be called via Typo3 (index.php) or directly via AJAX (directory: api). The
      * @param array $config
diff --git a/extension/qfq/tests/phpunit/BuildFormPlainTest.php b/extension/qfq/tests/phpunit/BuildFormPlainTest.php
index f7cd55a6d3e8787f307bb30d5765646ee0874285..2546d02f120e43f0802fb743a3e7699e334b2bae 100644
--- a/extension/qfq/tests/phpunit/BuildFormPlainTest.php
+++ b/extension/qfq/tests/phpunit/BuildFormPlainTest.php
@@ -80,34 +80,36 @@ class BuildFormPlainTest extends AbstractDatabaseTest {
 
         $build = new \qfq\BuildFormPlain($form, array(), [$formElement]);
 
+        $label['123-l'][API_ELEMENT_CONTENT] = '<label for="name:1" class="control-label" >Name</label>';
+
         $result = $build->buildInput($formElement, 'name:1', '', $json);
         $this->assertEquals('<input id="123" name="name:1" class="form-control" type="input" maxlength="255" value="" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result);
-        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => ''], $json);
+        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', API_ELEMENT_UPDATE => $label], $json);
 
         // CheckType
         $formElement['checkType'] = SANITIZE_ALLOW_MIN_MAX;
         $formElement['checkPattern'] = '1|10';
         $result = $build->buildInput($formElement, 'name:1', '', $json);
         $this->assertEquals('<input id="123" name="name:1" class="form-control" type="input" maxlength="255" value="" min="1" max="10" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result);
-        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false], $json);
+        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json);
 
         $formElement['checkType'] = SANITIZE_ALLOW_PATTERN;
         $formElement['checkPattern'] = '^[a-z]*$';
         $result = $build->buildInput($formElement, 'name:1', '', $json);
         $this->assertEquals('<input id="123" name="name:1" class="form-control" type="input" maxlength="255" value="" pattern="^[a-z]*$" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result);
-        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false], $json);
+        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json);
 
         $formElement['checkType'] = SANITIZE_ALLOW_DIGIT;
         $formElement['checkPattern'] = '';
         $result = $build->buildInput($formElement, 'name:1', '', $json);
         $this->assertEquals('<input id="123" name="name:1" class="form-control" type="input" maxlength="255" value="" pattern="^[\d]*$" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result);
-        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false], $json);
+        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json);
 
         $formElement['checkType'] = SANITIZE_ALLOW_EMAIL;
         $formElement['checkPattern'] = '';
         $result = $build->buildInput($formElement, 'name:1', '', $json);
         $this->assertEquals('<input id="123" name="name:1" class="form-control" type="input" maxlength="255" value="" pattern="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result);
-        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false], $json);
+        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json);
 
         $formElement['checkType'] = '';
         $formElement['checkPattern'] = '';
@@ -118,13 +120,13 @@ class BuildFormPlainTest extends AbstractDatabaseTest {
         $formElement['maxLength'] = 40;
         $result = $build->buildInput($formElement, 'name:1', '', $json);
         $this->assertEquals('<input id="123" name="name:1" class="form-control" type="input" size="40" maxlength="40" value="" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result);
-        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false], $json);
+        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json);
 
         // maxlength bigger than physical spec:
         $formElement['maxLength'] = 1000;
         $result = $build->buildInput($formElement, 'name:1', '', $json);
         $this->assertEquals('<input id="123" name="name:1" class="form-control" type="input" size="40" maxlength="255" value="" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result);
-        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false], $json);
+        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => '', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json);
 
         // no size, no maxlength and column not in primary table
         $formElement2 = $formElement;
@@ -157,18 +159,18 @@ class BuildFormPlainTest extends AbstractDatabaseTest {
         $formElement['placeholder'] = 'Please type a name';
         $result = $build->buildInput($formElement, 'name:1', 'Hello World', $json);
         $this->assertEquals('<input id="123" name="name:1" class="form-control" type="input" size="40" maxlength="255" value="Hello World" placeholder="Please type a name" title="Nice Tooltip" data-hidden="no" data-disabled="no" data-required="no" ><div class="help-block with-errors hidden"></div>', $result);
-        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => 'Hello World', 'disabled' => false], $json);
+        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => 'Hello World', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json);
 
         // textarea
         $formElement['size'] = '40,10';
         $result = $build->buildInput($formElement, 'name:1', 'Hello World', $json);
         $this->assertEquals('<textarea id="123" name="name:1" class="form-control" cols="40" rows="10" placeholder="Please type a name" title="Nice Tooltip" data-hidden="no" data-disabled="no" data-required="no" >Hello World</textarea><div class="help-block with-errors hidden"></div>', $result);
-        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => 'Hello World', 'disabled' => false], $json);
+        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => 'Hello World', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json);
 
         $formElement['size'] = ' 40     , 10 ';
         $result = $build->buildInput($formElement, 'name:1', 'Hello World', $json);
         $this->assertEquals('<textarea id="123" name="name:1" class="form-control" cols="40" rows="10" placeholder="Please type a name" title="Nice Tooltip" data-hidden="no" data-disabled="no" data-required="no" >Hello World</textarea><div class="help-block with-errors hidden"></div>', $result);
-        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => 'Hello World', 'disabled' => false], $json);
+        $this->assertEquals([FE_MODE_HIDDEN => '', 'disabled' => false, FE_MODE_REQUIRED => '', 'form-element' => 'name:1', 'value' => 'Hello World', 'disabled' => false, API_ELEMENT_UPDATE => $label], $json);
     }
 
     /**
@@ -493,6 +495,7 @@ class BuildFormPlainTest extends AbstractDatabaseTest {
 
         parent::setUp();
 
+        $this->store->unsetStore(STORE_ADDITIONAL_FORM_ELEMENTS);
         $this->executeSQLFile(__DIR__ . '/fixtures/Generic.sql', true);
 
         // Defaults
diff --git a/extension/qfq/tests/phpunit/FillStoreFormTest.php b/extension/qfq/tests/phpunit/FillStoreFormTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d9a471bbbfef20c374742f76a5ebd07ea8b09abe
--- /dev/null
+++ b/extension/qfq/tests/phpunit/FillStoreFormTest.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: crose
+ * Date: 1/2/16
+ * Time: 11:10 PM
+ */
+
+namespace qfq;
+
+require_once(__DIR__ . '/../../qfq/store/FillStoreForm.php');
+
+//require_once(__DIR__ . '/../../qfq/exceptions/CodeException.php');
+
+
+class FillStoreFormTest extends \PHPUnit_Framework_TestCase {
+
+    /**
+     * @throws CodeException
+     * @throws UserFormException
+     */
+    public function testFake() {
+
+        # Violates SANITIZE class: SANITIZE string is always an empty string.
+        # Access are cached: use new variables for every test.
+
+        # Check ''
+//        $this->assertEquals('', Sanitize::sanitize('', SANITIZE_ALLOW_ALNUMX), "SANITIZE_ALNUMX fails");
+        $this->assertEquals('', '');
+
+    }
+//
+//    /**
+//     * @expectedException \qfq\UserFormException
+//     */
+//    public function testSanitizeExceptionMinMaxMissingMin() {
+//        Sanitize::sanitize(56, SANITIZE_ALLOW_MIN_MAX, '|45');
+//    }
+//
+
+}