diff --git a/extension/Classes/Core/AbstractBuildForm.php b/extension/Classes/Core/AbstractBuildForm.php
index fdedb2f22915a0f59a5c95a00d07906983fe8460..111f3af107284bd410780463e542a7b1725dcefa 100644
--- a/extension/Classes/Core/AbstractBuildForm.php
+++ b/extension/Classes/Core/AbstractBuildForm.php
@@ -1037,22 +1037,10 @@ abstract class AbstractBuildForm {
 
         $t3VarsSip = $this->store->copyT3VarsToSip();
 
-        return $this->buildNativeHidden(CLIENT_TYPO3VARS, $t3VarsSip);
+        return HelperFormElement::buildNativeHidden(CLIENT_TYPO3VARS, $t3VarsSip);
 
     }
 
-    /**
-     * Builds a real HTML hidden form element. Useful for checkboxes, Multiple-Select and Radios.
-     *
-     * @param        $htmlFormElementName
-     * @param string $value
-     *
-     * @return string
-     */
-    public function buildNativeHidden($htmlFormElementName, $value) {
-        return '<input type="hidden" name="' . $htmlFormElementName . '" value="' . htmlentities($value) . '">';
-    }
-
     /**
      *
      */
@@ -1101,7 +1089,7 @@ abstract class AbstractBuildForm {
 
         $json[] = $this->getFormElementForJson(CLIENT_SIP, $sipValue, [FE_MODE => FE_MODE_SHOW]);
 
-        return $this->buildNativeHidden(CLIENT_SIP, $sipValue);
+        return HelperFormElement::buildNativeHidden(CLIENT_SIP, $sipValue);
     }
 
     /**
@@ -1123,7 +1111,7 @@ abstract class AbstractBuildForm {
     private function getFormElementForJson($htmlFormElementName, $value, array $formElement, $optionIdx = 0, $optionClass = '') {
         $addClassRequired = array();
 
-        $json = $this->getJsonFeMode($formElement[FE_MODE]); // disabled, required
+        $json = HelperFormElement::getJsonFeMode($formElement[FE_MODE]); // disabled, required
 
         $json[API_FORM_UPDATE_FORM_ELEMENT] = $htmlFormElementName;
 
@@ -1155,7 +1143,7 @@ abstract class AbstractBuildForm {
         // Label
         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], $addClassRequired[FE_LABEL] ?? '');
+            $json[API_ELEMENT_UPDATE][$key][API_ELEMENT_CONTENT] = HelperFormElement::buildLabel($htmlFormElementName, $formElement[FE_LABEL], $addClassRequired[FE_LABEL] ?? '');
         }
 
         // Note
@@ -1194,7 +1182,7 @@ abstract class AbstractBuildForm {
 
                     // Update label class (i.e.: 'qfq-disabled') of Checkbox/Radio (i.e. readonly on/off).
                     if (isset($formElement[FE_TMP_CLASS_OPTION])) {
-                        $optionsLabelId = $this->getCheckboxRadioOptionId($formElement[FE_HTML_ID], $optionIdx, HTML_ID_EXTENSION_LABEL);
+                        $optionsLabelId = HelperFormElement::getCheckboxRadioOptionId($formElement[FE_HTML_ID], $optionIdx, HTML_ID_EXTENSION_LABEL);
                         $json[API_ELEMENT_UPDATE][$optionsLabelId][API_ELEMENT_ATTRIBUTE]['class'] = $formElement[FE_TMP_CLASS_OPTION];
                     }
                 }
@@ -1244,41 +1232,6 @@ abstract class AbstractBuildForm {
         return $json;
     }
 
-    /**
-     * Set corresponding JSON attributes readonly/required/disabled, based on $formElement[FE_MODE].
-     *
-     * @param string $feMode
-     *
-     * @return array
-     * @throws \UserFormException
-     */
-    private function getJsonFeMode($feMode) {
-
-        HelperFormElement::getFeMode($feMode, $dummy, $disabled, $required);
-
-        return [API_FORM_UPDATE_DISABLED => ($disabled === 'yes'), API_FORM_UPDATE_REQUIRED => ($required === 'yes')];
-    }
-
-
-    /**
-     * Builds a label, typically for an html-'<input>'-element.
-     *
-     * @param string $htmlFormElementName
-     * @param string $label
-     * @param string $addClass
-     *
-     * @return string
-     * @throws \CodeException
-     */
-    public function buildLabel($htmlFormElementName, $label, $addClass = '') {
-        $attributes = Support::doAttribute('for', $htmlFormElementName);
-        $attributes .= Support::doAttribute('class', ['control-label', $addClass]);
-
-        $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'.
      *
@@ -1516,7 +1469,7 @@ abstract class AbstractBuildForm {
             }
         }
 
-        $input .= $this->getHelpBlock() . $elementCharacterCount;
+        $input .= HelperFormElement::getHelpBlock() . $elementCharacterCount;
 
         if (isset($formElement[FE_INPUT_EXTRA_BUTTON_INFO])) {
             $input .= $formElement[FE_INPUT_EXTRA_BUTTON_INFO];
@@ -1631,16 +1584,6 @@ abstract class AbstractBuildForm {
         return $sql;
     }
 
-
-    /**
-     * Build HelpBlock
-     *
-     * @return string
-     */
-    private function getHelpBlock() {
-        return '<div class="help-block with-errors hidden"></div>';
-    }
-
     /**
      * Builds HTML 'checkbox' element.
      *
@@ -1708,406 +1651,6 @@ abstract class AbstractBuildForm {
 
     }
 
-    /**
-     * Build a Checkbox based on two values. Either in HTML plain layout or with Bootstrap Button class.
-     *
-     * @param array $formElement
-     * @param string $htmlFormElementName
-     * @param string $attribute
-     * @param string $value
-     * @param array $json
-     * @param string $mode FORM_LOAD | FORM_UPDATE | FORM_SAVE
-     *
-     * @return string
-     * @throws \CodeException
-     * @throws \UserFormException
-     */
-    public function buildCheckboxSingle(array $formElement, $htmlFormElementName, $attribute, $value, array &$json, $mode = FORM_LOAD) {
-
-        if (isset($formElement[FE_BUTTON_CLASS])) {
-
-            if ($formElement[FE_BUTTON_CLASS] == '') {
-                $formElement[FE_BUTTON_CLASS] = 'btn-default';
-            }
-
-            if ($formElement[FE_MODE] == FE_MODE_READONLY) {
-                $formElement[FE_BUTTON_CLASS] .= ' disabled';
-            }
-
-            return $this->constructCheckboxSingleButton($formElement, $htmlFormElementName, $attribute, $value, $json);
-        } else {
-            return $this->constructCheckboxSinglePlain($formElement, $htmlFormElementName, $attribute, $value, $json);
-        }
-    }
-
-    /**
-     * Build a Checkbox based on two values with Bootstrap Button class.
-     *
-     * <div class="btn-group" data-toggle="buttons">
-     *    <input type="hidden" name="$htmlFormElementName" value="$valueUnChecked">
-     *    <label class="btn btn-primary active">
-     *       <input type="checkbox" autocomplete="off" name="$htmlFormElementName" value="$valueChecked"checked>
-     *       Checkbox 1 (pre-checked)
-     *    </label>
-     * </div>
-     *
-     * @param array $formElement
-     * @param string $htmlFormElementName
-     * @param string $attribute
-     * @param string $value
-     * @param array $json
-     *
-     * @return string
-     * @throws \CodeException
-     * @throws \UserFormException
-     */
-    public function constructCheckboxSingleButton(array $formElement, $htmlFormElementName, $attribute, $value, array &$json) {
-        $html = '';
-        $valueJson = false;
-
-        $attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
-        $attribute .= Support::doAttribute('name', $htmlFormElementName);
-        $attribute .= Support::doAttribute('value', $formElement[FE_CHECKBOX_CHECKED], false);
-        $attribute .= Support::doAttribute('data-load', ($formElement[FE_DYNAMIC_UPDATE] === 'yes') ? 'data-load' : '');
-        $attribute .= Support::doAttribute(FE_INPUT_AUTOCOMPLETE, 'off');
-        $attribute .= Support::doAttribute(ATTRIBUTE_DATA_REFERENCE, $formElement[FE_DATA_REFERENCE]);
-
-        $classActive = '';
-        if ($formElement[FE_CHECKBOX_CHECKED] === $value) {
-            $attribute .= Support::doAttribute('checked', 'checked');
-            $valueJson = true;
-            $classActive = ' active';
-        }
-
-        $attribute .= HelperFormElement::getAttributeList($formElement, ['autofocus']);
-        $attribute .= HelperFormElement::getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
-
-        $htmlHidden = $this->buildNativeHidden($htmlFormElementName, $formElement[FE_CHECKBOX_UNCHECKED]);
-        $this->store->setVar($htmlFormElementName, $htmlHidden, STORE_ADDITIONAL_FORM_ELEMENTS, false);
-        $html = '';
-
-        $htmlElement = '<input ' . $attribute . '>';
-        if (isset($formElement['label2'])) {
-            $htmlElement .= $formElement['label2'];
-        } else {
-            $htmlElement .= $formElement['checked'];
-        }
-
-        $labelAttribute = Support::doAttribute('title', $formElement[FE_TOOLTIP]);
-        $labelAttribute .= Support::doAttribute('class', 'btn ' . $formElement[FE_BUTTON_CLASS] . $classActive);
-        $html .= Support::wrapTag("<label $labelAttribute>", $htmlElement, true);
-        $html = Support::wrapTag('<div class="btn-group" data-toggle="buttons">', $html);
-
-        $json = $this->getFormElementForJson($htmlFormElementName, $valueJson, $formElement);
-
-        return $html;
-    }
-
-    /**
-     * Build a single HTML plain checkbox based on two values.
-     * Create a 'hidden' input field and a 'checkbox' input field - both with the same HTML 'name'.
-     * HTML does not submit an unchecked checkbox. Then only the 'hidden' input field is submitted.
-     *
-     * Format: <input type="hidden" name="$htmlFormElementName" value="$valueUnChecked">
-     *         <input name="$htmlFormElementName" type="radio" [autofocus="autofocus"]
-     *            [required="required"] [disabled="disabled"] value="<value>" [checked="checked"] >
-     *
-     * @param array $formElement
-     * @param string $htmlFormElementName
-     * @param string $attribute
-     * @param string $value
-     * @param array $json
-     *
-     * @return string
-     * @throws \CodeException
-     * @throws \UserFormException
-     */
-    public function constructCheckboxSinglePlain(array $formElement, $htmlFormElementName, $attribute, $value, array &$json) {
-        $html = '';
-        $valueJson = false;
-
-        $attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
-        $attribute .= Support::doAttribute('name', $htmlFormElementName);
-        $attribute .= Support::doAttribute('value', $formElement[FE_CHECKBOX_CHECKED], false);
-        $attribute .= Support::doAttribute('data-load', ($formElement[FE_DYNAMIC_UPDATE] === 'yes') ? 'data-load' : '');
-        $attribute .= Support::doAttribute(ATTRIBUTE_DATA_REFERENCE, $formElement[FE_DATA_REFERENCE]);
-
-        if ($formElement[FE_CHECKBOX_CHECKED] === $value) {
-            $attribute .= Support::doAttribute('checked', 'checked');
-            $valueJson = $value;
-        }
-
-        $attribute .= HelperFormElement::getAttributeList($formElement, ['autofocus']);
-        $attribute .= HelperFormElement::getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
-
-        $htmlHidden = $this->buildNativeHidden($htmlFormElementName, $formElement[FE_CHECKBOX_UNCHECKED]);
-        $this->store->setVar($htmlFormElementName, $htmlHidden, STORE_ADDITIONAL_FORM_ELEMENTS, false);
-        $html = '';
-
-        $html .= '<input ' . $attribute . '>';
-        if (isset($formElement['label2'])) {
-            $html .= Support::wrapTag("<span style='font-weight: 400;'>", $formElement['label2']);
-        }
-
-        $labelAttribute = Support::doAttribute('title', $formElement[FE_TOOLTIP]);
-
-        $class = 'checkbox';
-        if ($formElement[FE_MODE] == FE_MODE_READONLY) {
-            $class .= ' qfq-disabled'; // necessary for own style checkboxes to display them 'disabled'
-        }
-
-        $html = Support::wrapTag("<label class='$class' $labelAttribute>", $html, true);
-//        $html = Support::wrapTag("<div class='checkbox'>", $html, true);
-
-        $json = $this->getFormElementForJson($htmlFormElementName, $valueJson, $formElement);
-
-        return $html;
-    }
-
-    /**
-     * Build a Checkbox based on two values. Either in HTML plain layout or with Bootstrap Button class.
-     *
-     * @param array $formElement
-     * @param string $htmlFormElementName
-     * @param $attributeBase
-     * @param string $value
-     * @param array $itemKey
-     * @param array $itemValue
-     * @param array $json
-     * @return string
-     * @throws \CodeException
-     * @throws \UserFormException
-     */
-    public function buildCheckboxMulti(array $formElement, $htmlFormElementName, $attributeBase, $value, array $itemKey, array $itemValue, array &$json) {
-
-        if (isset($formElement[FE_BUTTON_CLASS])) {
-
-            if ($formElement[FE_BUTTON_CLASS] == '') {
-                $formElement[FE_BUTTON_CLASS] = 'btn-default';
-            }
-
-            if ($formElement[FE_MODE] == FE_MODE_READONLY) {
-                $formElement[FE_BUTTON_CLASS] .= ' disabled';
-            }
-
-            return $this->constructCheckboxMultiButton($formElement, $htmlFormElementName, $attributeBase, $value, $itemKey, $itemValue, $json);
-        } else {
-            return $this->constructCheckboxMultiPlain($formElement, $htmlFormElementName, $attributeBase, $value, $itemKey, $itemValue, $json);
-        }
-    }
-
-    /**
-     * @param array $formElement
-     * @param string $htmlFormElementName
-     * @param string $htmlHidden
-     * @throws \CodeException
-     * @throws \UserFormException
-     */
-    private function fillStoreAdditionalFormElementsCheckboxHidden(array $formElement, $htmlFormElementName, $htmlHidden) {
-
-        if (isset($formElement[NAME_TG_COPIES]) && $formElement[NAME_TG_COPIES] > 0) {
-            for ($ii = 1; $ii <= $formElement[NAME_TG_COPIES]; $ii++) {
-                $key = str_replace('%d', $ii, $htmlFormElementName);
-                $value = str_replace('%d', $ii, $htmlHidden);
-                $this->store->setVar($key, $value, STORE_ADDITIONAL_FORM_ELEMENTS, true);
-            }
-        } else {
-            $this->store->setVar($htmlFormElementName, $htmlHidden, STORE_ADDITIONAL_FORM_ELEMENTS, false);
-        }
-    }
-
-    /**
-     * Build as many Checkboxes as items.
-     *
-     * Layout: The Bootstrap Layout needs very special setup, the checkboxes are wrapped differently with <div
-     * class=checkbox> depending of if they aligned horizontal or vertical.
-     *
-     * @param array $formElement
-     * @param string $htmlFormElementName
-     * @param string $attributeBase
-     * @param string $value
-     * @param array $itemKey
-     * @param array $itemValue
-     * @param array $json
-     *
-     * @return string
-     * @throws \CodeException
-     * @throws \UserFormException
-     */
-    public function constructCheckboxMultiButton(array $formElement, $htmlFormElementName, $attributeBase, $value, array $itemKey, array $itemValue, array &$json) {
-        $json = array();
-
-        // Defines which of the checkboxes will be checked.
-        $values = explode(',', $value);
-
-        $attributeBase .= Support::doAttribute('data-load', ($formElement[FE_DYNAMIC_UPDATE] === 'yes') ? 'data-load' : '');
-        $attributeBase .= HelperFormElement::getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
-
-        $key = HelperFormElement::prependFormElementNameCheckBoxMulti($htmlFormElementName, 'h', true);
-        $htmlHidden = $this->buildNativeHidden($key, '');
-        $this->fillStoreAdditionalFormElementsCheckboxHidden($formElement, $htmlFormElementName, $htmlHidden);
-
-        $html = '';
-
-        $attribute = $attributeBase;
-        if (isset($formElement[FE_AUTOFOCUS])) {
-            $attribute .= Support::doAttribute('autofocus', $formElement[FE_AUTOFOCUS]);
-        }
-
-        for ($ii = 0, $jj = 1; $ii < count($itemKey); $ii++, $jj++) {
-            $jsonValue = false;
-            $classActive = '';
-            $htmlFormElementNameUniq = HelperFormElement::prependFormElementNameCheckBoxMulti($htmlFormElementName, $ii, true);
-            $attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID] . '-' . $ii);
-            $attribute .= Support::doAttribute('name', $htmlFormElementNameUniq);
-            $attribute .= Support::doAttribute(ATTRIBUTE_DATA_REFERENCE, $formElement[FE_DATA_REFERENCE] . '-' . $ii);
-
-
-            $attribute .= Support::doAttribute('value', $itemKey[$ii], false);
-
-            // Check if the given key is found in field.
-            if (false !== array_search($itemKey[$ii], $values)) {
-                $attribute .= Support::doAttribute('checked', 'checked');
-                $jsonValue = true;
-                $classActive = ' active';
-            }
-
-            // '&nbsp;' - This is necessary to correctly align an empty input.
-            $value = ($itemValue[$ii] === '') ? '&nbsp;' : $itemValue[$ii];
-
-            $htmlElement = '<input ' . $attribute . '>' . $value;
-
-            $html .= Support::wrapTag("<label class='btn " . $formElement[FE_BUTTON_CLASS] . "$classActive'>",
-                $htmlElement, true);
-
-            $json[] = $this->getFormElementForJson($htmlFormElementNameUniq, $jsonValue, $formElement);
-
-            // Init for the next checkbox
-            $attribute = $attributeBase;
-        }
-
-        $html = Support::wrapTag('<div class="btn-group" data-toggle="buttons">', $html);
-
-        return $html;
-    }
-
-    /**
-     * Build as many Checkboxes as items.
-     *
-     * Layout: The Bootstrap Layout needs very special setup, the checkboxes are wrapped differently with <div
-     * class=checkbox> depending of if they aligned horizontal or vertical.
-     *
-     * @param array $formElement
-     * @param string $htmlFormElementName
-     * @param string $attributeBase
-     * @param string $value
-     * @param array $itemKey
-     * @param array $itemValue
-     * @param array $json
-     *
-     * @return string
-     * @throws \CodeException
-     * @throws \UserFormException
-     */
-    public function constructCheckboxMultiPlain(array $formElement, $htmlFormElementName, $attributeBase, $value, array $itemKey, array $itemValue, array &$json) {
-        $json = array();
-
-        // Defines which of the checkboxes will be checked.
-        $values = explode(',', $value);
-
-        $attributeBase .= Support::doAttribute('data-load', ($formElement[FE_DYNAMIC_UPDATE] === 'yes') ? 'data-load' : '');
-        $attributeBase .= HelperFormElement::getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
-
-        // 'font-weight: 400;': class 'checkbox' forces bold for the label - this is not ok.
-        $attributeBaseLabel = Support::doAttribute('style', 'min-width: ' . $formElement[F_FE_MIN_WIDTH] . 'px; font-weight: 400;');
-
-//        $key = HelperFormElement::prependFormElementNameCheckBoxMulti($htmlFormElementName, 'h');
-//        $htmlHidden = $this->buildNativeHidden($key, '');
-//        $this->fillStoreAdditionalFormElementsCheckboxHidden($formElement, $htmlFormElementName, $htmlHidden);
-
-        $html = '';
-
-        $orientation = ($formElement[FE_MAX_LENGTH] > 1) ? ALIGN_HORIZONTAL : ALIGN_VERTICAL;
-        $checkboxClass = ($orientation === ALIGN_HORIZONTAL) ? 'checkbox-inline' : 'checkbox';
-        if ($formElement[FE_MODE] == FE_MODE_READONLY) {
-            $checkboxClass .= ' qfq-disabled'; // necessary for own style checkboxes to display them 'disabled'
-        }
-        // Used in getFormElementForJson() for dynamic update.
-        $formElement[FE_TMP_CLASS_OPTION] = $checkboxClass;
-
-        $br = '';
-
-        $flagFirst = true;
-        for ($ii = 0, $jj = 1; $ii < count($itemKey); $ii++, $jj++) {
-            $jsonValue = false;
-            $attribute = $attributeBase;
-            $htmlFormElementNameUniq = HelperFormElement::prependFormElementNameCheckBoxMulti($htmlFormElementName, $ii, true);
-            $checkboxId = $this->getCheckboxRadioOptionId($formElement[FE_HTML_ID], $ii);
-            $attribute .= Support::doAttribute('id', $checkboxId);
-            $attribute .= Support::doAttribute('name', $htmlFormElementNameUniq);
-            $attribute .= Support::doAttribute(ATTRIBUTE_DATA_REFERENCE, $formElement[FE_DATA_REFERENCE] . '-' . $ii);
-
-            // Do this only the first round.
-            if ($flagFirst) {
-                $flagFirst = false;
-                if (isset($formElement[FE_AUTOFOCUS]))
-                    $attribute .= Support::doAttribute('autofocus', $formElement[FE_AUTOFOCUS]);
-            }
-
-            $attribute .= Support::doAttribute('value', $itemKey[$ii], false);
-
-            // Check if the given key is found in field.
-            if (false !== array_search($itemKey[$ii], $values)) {
-                $attribute .= Support::doAttribute('checked', 'checked');
-                $jsonValue = true;
-            }
-
-            // '&nbsp;' - This is necessary to correctly align an empty input.
-            $value = ($itemValue[$ii] === '') ? '&nbsp;' : $itemValue[$ii];
-
-            $htmlElement = '<input ' . $attribute . '>' . $value;
-
-            // With ALIGN_HORIZONTAL: the label causes some trouble: skip it
-//            if (($orientation === ALIGN_VERTICAL)) {
-//                $htmlElement = Support::wrapTag('<label>', $htmlElement);
-//            }
-
-            $checkboxLabelId = $this->getCheckboxRadioOptionId($formElement[FE_HTML_ID], $ii, HTML_ID_EXTENSION_LABEL);
-            $htmlElement = Support::wrapTag("<label class='$checkboxClass' $attributeBaseLabel id='$checkboxLabelId'>", $htmlElement, true);
-
-            // control orientation
-            if ($formElement[FE_MAX_LENGTH] > 1) {
-
-                if ($jj == $formElement[FE_MAX_LENGTH]) {
-                    $jj = 0;
-                    $br = '<br>';
-                } else {
-                    $br = '';
-                }
-            }
-
-            $html .= $htmlElement . $br;
-            $json[] = $this->getFormElementForJson($htmlFormElementNameUniq, $jsonValue, $formElement, $ii, $checkboxClass);
-
-        }
-
-        return $html;
-    }
-
-    /**
-     * Construct HTML ID for checkbox/radio option elements.
-     * Optional add $type.
-     * Example: $base='173-21612-1-0', $index='0', $type='l' >> '173-21612-1-0-0-l'
-     *
-     * @param $base
-     * @param $index
-     * @param string $type -  ';' for label
-     * @return string
-     */
-    private function getCheckboxRadioOptionId($base, $index, $type = '') {
-        return $base . '-' . $index . $type;
-    }
-
     /**
      * Submit extra (hidden) values by SIP.
      *
@@ -2167,7 +1710,7 @@ abstract class AbstractBuildForm {
 
         $formElement = HelperFormElement::prepareExtraButton($formElement, false);
 
-        return $html . $formElement[FE_TMP_EXTRA_BUTTON_HTML] . $this->getHelpBlock() . $formElement[FE_INPUT_EXTRA_BUTTON_INFO];
+        return $html . $formElement[FE_TMP_EXTRA_BUTTON_HTML] . HelperFormElement::getHelpBlock() . $formElement[FE_INPUT_EXTRA_BUTTON_INFO];
 
     }
 
@@ -2281,6 +1824,7 @@ abstract class AbstractBuildForm {
      * @return string
      * @throws \CodeException
      * @throws \UserFormException
+     * @throws \UserReportException
      */
     private function constructRadioPlain(array $formElement, $htmlFormElementName, $value, array &$json, $mode = FORM_LOAD) {
         $attributeBase = '';
@@ -2326,7 +1870,7 @@ abstract class AbstractBuildForm {
         for ($ii = 0; $ii < count($itemValue); $ii++) {
             $jj++;
 
-            $optionId = $this->getCheckboxRadioOptionId($formElement[FE_HTML_ID], $ii);
+            $optionId = HelperFormElement::getCheckboxRadioOptionId($formElement[FE_HTML_ID], $ii);
             $attribute .= Support::doAttribute('id', $optionId);
             $attribute .= Support::doAttribute('value', $itemKey[$ii], false); // Always set value, even to '' - #3832
             $attribute .= Support::doAttribute(ATTRIBUTE_DATA_REFERENCE, $formElement[FE_DATA_REFERENCE] . '-' . $ii);
@@ -2358,7 +1902,7 @@ abstract class AbstractBuildForm {
             $wrapAttribute = Support::doAttribute('title', $formElement[FE_TOOLTIP]);
             $wrapAttribute .= Support::doAttribute('class', $radioClass);
 
-            $radioLabelId = $this->getCheckboxRadioOptionId($formElement[FE_HTML_ID], $ii, HTML_ID_EXTENSION_LABEL);
+            $radioLabelId = HelperFormElement::getCheckboxRadioOptionId($formElement[FE_HTML_ID], $ii, HTML_ID_EXTENSION_LABEL);
             $htmlElement = Support::wrapTag("<label $wrapAttribute $attributeBaseLabel id='$radioLabelId'>", $htmlElement) . $br;
 
             $html .= $htmlElement;
@@ -2366,7 +1910,7 @@ abstract class AbstractBuildForm {
             $attribute = $attributeBase;
 
             // Update label class (i.e.: 'qfq-disabled') of Checkbox/Radio (i.e. readonly on/off).
-            $optionLabelId = $this->getCheckboxRadioOptionId($formElement[FE_HTML_ID], $ii, HTML_ID_EXTENSION_LABEL);
+            $optionLabelId = HelperFormElement::getCheckboxRadioOptionId($formElement[FE_HTML_ID], $ii, HTML_ID_EXTENSION_LABEL);
             $jsonTmp[API_ELEMENT_UPDATE][$optionLabelId][API_ELEMENT_ATTRIBUTE]['class'] = $formElement[FE_TMP_CLASS_OPTION];
 
             $jsonTmp[API_ELEMENT_UPDATE][$optionId][API_ELEMENT_ATTRIBUTE]['required'] = ($formElement[FE_MODE] == FE_MODE_REQUIRED) ? 'required' : 'false';
@@ -2462,7 +2006,7 @@ abstract class AbstractBuildForm {
         } else {
             $html = '<select ' . $attribute . '>' . $option . '</select>';
         }
-        $html = $html . $this->getHelpBlock() . $formElement[FE_TMP_EXTRA_BUTTON_HTML];
+        $html = $html . HelperFormElement::getHelpBlock() . $formElement[FE_TMP_EXTRA_BUTTON_HTML];
         return $html . $formElement[FE_INPUT_EXTRA_BUTTON_INFO];
     }
 
@@ -3083,7 +2627,7 @@ abstract class AbstractBuildForm {
 
         $sipUpload = $this->sip->queryStringToSip(OnArray::toString($arr), RETURN_SIP);
 
-        $hiddenSipUpload = $this->buildNativeHidden($htmlFormElementName, $sipUpload);
+        $hiddenSipUpload = HelperFormElement::buildNativeHidden($htmlFormElementName, $sipUpload);
 
         $attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
         $attribute .= Support::doAttribute('name', $htmlFormElementName);
@@ -3116,7 +2660,7 @@ abstract class AbstractBuildForm {
         $attribute .= HelperFormElement::getAttributeFeMode($formElement[FE_MODE]);
         $attribute .= Support::doAttribute('class', $uploadClass, true);
 
-//        $htmlInputFile = '<input ' . $attribute . '>' . $this->getHelpBlock();
+//        $htmlInputFile = '<input ' . $attribute . '>' . HelperFormElement::getHelpBlock();
 
         // <input type="file"> with BS3: https://stackoverflow.com/questions/11235206/twitter-bootstrap-form-file-element-upload-button/25053973#25053973
         $attribute .= Support::doAttribute('style', "display:none;");
@@ -3253,7 +2797,7 @@ abstract class AbstractBuildForm {
 
         $htmlInput = Support::wrapTag('<input ' . $attributeInput . ' >', '', false);
 
-        $html = $htmlAnnotate . $htmlInput . $this->getHelpBlock();
+        $html = $htmlAnnotate . $htmlInput . HelperFormElement::getHelpBlock();
 
 //        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
 
@@ -3316,7 +2860,7 @@ abstract class AbstractBuildForm {
 
         $htmlInput = Support::wrapTag('<input ' . $attributeInput . ' >', '', false);
 
-        $html = $htmlFabric . $htmlInput . $this->getHelpBlock();
+        $html = $htmlFabric . $htmlInput . HelperFormElement::getHelpBlock();
 
 //        $json = $this->getFormElementForJson($htmlFormElementName, $value, $formElement);
 
@@ -3389,7 +2933,7 @@ abstract class AbstractBuildForm {
         $attributeImage = Support::doAttribute('id', $htmlFabricImageId);
         $htmlImage = Support::wrapTag('<img ' . $attributeImage . '>', '', false);
 
-        $html = $htmlFabric . $this->getHelpBlock() . $htmlInput . $htmlImage;
+        $html = $htmlFabric . HelperFormElement::getHelpBlock() . $htmlInput . $htmlImage;
 
 //        $tmpUrlParam[DOWNLOAD_MODE] = $this->getDownloadModeNCheck($vars);
 //        $tmpUrlParam[DOWNLOAD_EXPORT_FILENAME] = $vars[NAME_DOWNLOAD];
@@ -3528,7 +3072,7 @@ abstract class AbstractBuildForm {
 
         $attribute .= HelperFormElement::getAttributeFeMode($formElement[FE_MODE]);
 
-        $input = "<input $attribute>" . $this->getHelpBlock() . $formElement[FE_TMP_EXTRA_BUTTON_HTML];
+        $input = "<input $attribute>" . HelperFormElement::getHelpBlock() . $formElement[FE_TMP_EXTRA_BUTTON_HTML];
 
         if ($formElement[FE_TMP_EXTRA_BUTTON_HTML] !== '') {
             $input = Support::wrapTag('<div class="input-group">', $input);
@@ -3622,7 +3166,7 @@ abstract class AbstractBuildForm {
 
         $element = Support::wrapTag("<div $attribute>", '', false);
 
-        return $element . $this->getHelpBlock();
+        return $element . HelperFormElement::getHelpBlock();
     }
 
     /**
@@ -3672,7 +3216,7 @@ abstract class AbstractBuildForm {
         $html = Support::wrapTag("<textarea $attribute>", htmlentities($value), false);
         $formElement = HelperFormElement::prepareExtraButton($formElement, false);
 
-        return $html . $this->getHelpBlock() . $formElement[FE_TMP_EXTRA_BUTTON_HTML] . $formElement[FE_INPUT_EXTRA_BUTTON_INFO];
+        return $html . HelperFormElement::getHelpBlock() . $formElement[FE_TMP_EXTRA_BUTTON_HTML] . $formElement[FE_INPUT_EXTRA_BUTTON_INFO];
     }
 
     /**
diff --git a/extension/Classes/Core/BuildFormBootstrap.php b/extension/Classes/Core/BuildFormBootstrap.php
index 11cea35a30c27cefc903762394f1933cc131eae5..8922293e18252b548af7374e8a98ed23f5976e9b 100644
--- a/extension/Classes/Core/BuildFormBootstrap.php
+++ b/extension/Classes/Core/BuildFormBootstrap.php
@@ -807,7 +807,7 @@ EOF;
 
         // Label
         if ($formElement[FE_BS_LABEL_COLUMNS] != '0') {
-            $htmlLabel = $this->buildLabel($htmlFormElementName, $formElement[FE_LABEL], $addClassRequired[FE_LABEL] ?? '');
+            $htmlLabel = HelperFormElement::buildLabel($htmlFormElementName, $formElement[FE_LABEL], $addClassRequired[FE_LABEL] ?? '');
         }
 
         $html .= $this->customWrap($formElement, $htmlLabel, FE_WRAP_LABEL, $formElement[FE_BS_LABEL_COLUMNS],
diff --git a/extension/Classes/Core/Form/Checkbox.php b/extension/Classes/Core/Form/Checkbox.php
index 727b841ef44a40674423c65e89b245f232517770..a167c55d8e4846b9cf766d52f5e7996b0982012e 100644
--- a/extension/Classes/Core/Form/Checkbox.php
+++ b/extension/Classes/Core/Form/Checkbox.php
@@ -23,6 +23,7 @@ use IMATHUZH\Qfq\Core\Helper\Support;
 //use IMATHUZH\Qfq\Core\Store\Sip;
 use IMATHUZH\Qfq\Core\Helper\HelperFormElement;
 use IMATHUZH\Qfq\Core\Store\Store;
+use TYPO3\PharStreamWrapper\Helper;
 
 
 /**
@@ -96,7 +97,7 @@ class Checkbox {
 
         $formElement = HelperFormElement::prepareExtraButton($formElement, false);
 
-        return $html . $formElement[FE_TMP_EXTRA_BUTTON_HTML] . $this->getHelpBlock() . $formElement[FE_INPUT_EXTRA_BUTTON_INFO];
+        return $html . $formElement[FE_TMP_EXTRA_BUTTON_HTML] . HelperFormElement::getHelpBlock() . $formElement[FE_INPUT_EXTRA_BUTTON_INFO];
     }
 
     /**
@@ -135,7 +136,532 @@ class Checkbox {
         if ($formElement[FE_CHECKBOX_CHECKED] === $formElement[FE_CHECKBOX_UNCHECKED]) {
             throw new \UserFormException('FormElement: type=checkbox - checked and unchecked can\'t be the same: ' . $formElement[FE_CHECKBOX_CHECKED], ERROR_CHECKBOX_EQUAL);
         }
+    }
+
+    /**
+     * Build a Checkbox based on two values. Either in HTML plain layout or with Bootstrap Button class.
+     *
+     * @param array $formElement
+     * @param string $htmlFormElementName
+     * @param $attributeBase
+     * @param string $value
+     * @param array $itemKey
+     * @param array $itemValue
+     * @param array $json
+     * @return string
+     * @throws \CodeException
+     * @throws \UserFormException
+     */
+    public function buildCheckboxMulti(array $formElement, $htmlFormElementName, $attributeBase, $value, array $itemKey, array $itemValue, array &$json) {
+
+        if (isset($formElement[FE_BUTTON_CLASS])) {
+
+            if ($formElement[FE_BUTTON_CLASS] == '') {
+                $formElement[FE_BUTTON_CLASS] = 'btn-default';
+            }
+
+            if ($formElement[FE_MODE] == FE_MODE_READONLY) {
+                $formElement[FE_BUTTON_CLASS] .= ' disabled';
+            }
 
+            return $this->constructCheckboxMultiButton($formElement, $htmlFormElementName, $attributeBase, $value, $itemKey, $itemValue, $json);
+        } else {
+            return $this->constructCheckboxMultiPlain($formElement, $htmlFormElementName, $attributeBase, $value, $itemKey, $itemValue, $json);
+        }
     }
 
+    /**
+     * Build as many Checkboxes as items.
+     *
+     * Layout: The Bootstrap Layout needs very special setup, the checkboxes are wrapped differently with <div
+     * class=checkbox> depending of if they aligned horizontal or vertical.
+     *
+     * @param array $formElement
+     * @param string $htmlFormElementName
+     * @param string $attributeBase
+     * @param string $value
+     * @param array $itemKey
+     * @param array $itemValue
+     * @param array $json
+     *
+     * @return string
+     * @throws \CodeException
+     * @throws \UserFormException
+     */
+    private function constructCheckboxMultiButton(array $formElement, $htmlFormElementName, $attributeBase, $value, array $itemKey, array $itemValue, array &$json) {
+        $json = array();
+
+        // Defines which of the checkboxes will be checked.
+        $values = explode(',', $value);
+
+        $attributeBase .= Support::doAttribute('data-load', ($formElement[FE_DYNAMIC_UPDATE] === 'yes') ? 'data-load' : '');
+        $attributeBase .= HelperFormElement::getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
+
+        $key = HelperFormElement::prependFormElementNameCheckBoxMulti($htmlFormElementName, 'h', true);
+        $htmlHidden = HelperFormElement::buildNativeHidden($key, '');
+        $this->fillStoreAdditionalFormElementsCheckboxHidden($formElement, $htmlFormElementName, $htmlHidden);
+
+        $html = '';
+
+        $attribute = $attributeBase;
+        if (isset($formElement[FE_AUTOFOCUS])) {
+            $attribute .= Support::doAttribute('autofocus', $formElement[FE_AUTOFOCUS]);
+        }
+
+        for ($ii = 0, $jj = 1; $ii < count($itemKey); $ii++, $jj++) {
+            $jsonValue = false;
+            $classActive = '';
+            $htmlFormElementNameUniq = HelperFormElement::prependFormElementNameCheckBoxMulti($htmlFormElementName, $ii, true);
+            $attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID] . '-' . $ii);
+            $attribute .= Support::doAttribute('name', $htmlFormElementNameUniq);
+            $attribute .= Support::doAttribute(ATTRIBUTE_DATA_REFERENCE, $formElement[FE_DATA_REFERENCE] . '-' . $ii);
+
+
+            $attribute .= Support::doAttribute('value', $itemKey[$ii], false);
+
+            // Check if the given key is found in field.
+            if (false !== array_search($itemKey[$ii], $values)) {
+                $attribute .= Support::doAttribute('checked', 'checked');
+                $jsonValue = true;
+                $classActive = ' active';
+            }
+
+            // '&nbsp;' - This is necessary to correctly align an empty input.
+            $value = ($itemValue[$ii] === '') ? '&nbsp;' : $itemValue[$ii];
+
+            $htmlElement = '<input ' . $attribute . '>' . $value;
+
+            $html .= Support::wrapTag("<label class='btn " . $formElement[FE_BUTTON_CLASS] . "$classActive'>",
+                $htmlElement, true);
+
+            $json[] = $this->getFormElementForJsonCheckBox($htmlFormElementNameUniq, $jsonValue, $formElement);
+
+            // Init for the next checkbox
+            $attribute = $attributeBase;
+        }
+
+        $html = Support::wrapTag('<div class="btn-group" data-toggle="buttons">', $html);
+
+        return $html;
+    }
+
+    /**
+     * Build as many Checkboxes as items.
+     *
+     * Layout: The Bootstrap Layout needs very special setup, the checkboxes are wrapped differently with <div
+     * class=checkbox> depending of if they aligned horizontal or vertical.
+     *
+     * @param array $formElement
+     * @param string $htmlFormElementName
+     * @param string $attributeBase
+     * @param string $value
+     * @param array $itemKey
+     * @param array $itemValue
+     * @param array $json
+     *
+     * @return string
+     * @throws \CodeException
+     * @throws \UserFormException
+     */
+    private function constructCheckboxMultiPlain(array $formElement, $htmlFormElementName, $attributeBase, $value, array $itemKey, array $itemValue, array &$json) {
+        $json = array();
+
+        // Defines which of the checkboxes will be checked.
+        $values = explode(',', $value);
+
+        $attributeBase .= Support::doAttribute('data-load', ($formElement[FE_DYNAMIC_UPDATE] === 'yes') ? 'data-load' : '');
+        $attributeBase .= HelperFormElement::getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
+
+        // 'font-weight: 400;': class 'checkbox' forces bold for the label - this is not ok.
+        $attributeBaseLabel = Support::doAttribute('style', 'min-width: ' . $formElement[F_FE_MIN_WIDTH] . 'px; font-weight: 400;');
+
+//        $key = HelperFormElement::prependFormElementNameCheckBoxMulti($htmlFormElementName, 'h');
+//        $htmlHidden = HelperFormElement::buildNativeHidden($key, '');
+//        $this->fillStoreAdditionalFormElementsCheckboxHidden($formElement, $htmlFormElementName, $htmlHidden);
+
+        $html = '';
+
+        $orientation = ($formElement[FE_MAX_LENGTH] > 1) ? ALIGN_HORIZONTAL : ALIGN_VERTICAL;
+        $checkboxClass = ($orientation === ALIGN_HORIZONTAL) ? 'checkbox-inline' : 'checkbox';
+        if ($formElement[FE_MODE] == FE_MODE_READONLY) {
+            $checkboxClass .= ' qfq-disabled'; // necessary for own style checkboxes to display them 'disabled'
+        }
+        // Used in getFormElementForJson() for dynamic update.
+        $formElement[FE_TMP_CLASS_OPTION] = $checkboxClass;
+
+        $br = '';
+
+        $flagFirst = true;
+        for ($ii = 0, $jj = 1; $ii < count($itemKey); $ii++, $jj++) {
+            $jsonValue = false;
+            $attribute = $attributeBase;
+            $htmlFormElementNameUniq = HelperFormElement::prependFormElementNameCheckBoxMulti($htmlFormElementName, $ii, true);
+            $checkboxId = HelperFormElement::getCheckboxRadioOptionId($formElement[FE_HTML_ID], $ii);
+            $attribute .= Support::doAttribute('id', $checkboxId);
+            $attribute .= Support::doAttribute('name', $htmlFormElementNameUniq);
+            $attribute .= Support::doAttribute(ATTRIBUTE_DATA_REFERENCE, $formElement[FE_DATA_REFERENCE] . '-' . $ii);
+
+            // Do this only the first round.
+            if ($flagFirst) {
+                $flagFirst = false;
+                if (isset($formElement[FE_AUTOFOCUS]))
+                    $attribute .= Support::doAttribute('autofocus', $formElement[FE_AUTOFOCUS]);
+            }
+
+            $attribute .= Support::doAttribute('value', $itemKey[$ii], false);
+
+            // Check if the given key is found in field.
+            if (false !== array_search($itemKey[$ii], $values)) {
+                $attribute .= Support::doAttribute('checked', 'checked');
+                $jsonValue = true;
+            }
+
+            // '&nbsp;' - This is necessary to correctly align an empty input.
+            $value = ($itemValue[$ii] === '') ? '&nbsp;' : $itemValue[$ii];
+
+            $htmlElement = '<input ' . $attribute . '>' . $value;
+
+            // With ALIGN_HORIZONTAL: the label causes some trouble: skip it
+//            if (($orientation === ALIGN_VERTICAL)) {
+//                $htmlElement = Support::wrapTag('<label>', $htmlElement);
+//            }
+
+            $checkboxLabelId = HelperFormElement::getCheckboxRadioOptionId($formElement[FE_HTML_ID], $ii, HTML_ID_EXTENSION_LABEL);
+            $htmlElement = Support::wrapTag("<label class='$checkboxClass' $attributeBaseLabel id='$checkboxLabelId'>", $htmlElement, true);
+
+            // control orientation
+            if ($formElement[FE_MAX_LENGTH] > 1) {
+
+                if ($jj == $formElement[FE_MAX_LENGTH]) {
+                    $jj = 0;
+                    $br = '<br>';
+                } else {
+                    $br = '';
+                }
+            }
+
+            $html .= $htmlElement . $br;
+            $json[] = $this->getFormElementForJsonCheckbox($htmlFormElementNameUniq, $jsonValue, $formElement, $ii, $checkboxClass);
+
+        }
+
+        return $html;
+    }
+
+    /**
+     * @param array $formElement
+     * @param string $htmlFormElementName
+     * @param string $htmlHidden
+     * @throws \CodeException
+     * @throws \UserFormException
+     */
+    private function fillStoreAdditionalFormElementsCheckboxHidden(array $formElement, $htmlFormElementName, $htmlHidden) {
+
+        if (isset($formElement[NAME_TG_COPIES]) && $formElement[NAME_TG_COPIES] > 0) {
+            for ($ii = 1; $ii <= $formElement[NAME_TG_COPIES]; $ii++) {
+                $key = str_replace('%d', $ii, $htmlFormElementName);
+                $value = str_replace('%d', $ii, $htmlHidden);
+                $this->store->setVar($key, $value, STORE_ADDITIONAL_FORM_ELEMENTS, true);
+            }
+        } else {
+            $this->store->setVar($htmlFormElementName, $htmlHidden, STORE_ADDITIONAL_FORM_ELEMENTS, false);
+        }
+    }
+
+
+    /**
+     * Build a Checkbox based on two values. Either in HTML plain layout or with Bootstrap Button class.
+     *
+     * @param array $formElement
+     * @param string $htmlFormElementName
+     * @param string $attribute
+     * @param string $value
+     * @param array $json
+     * @param string $mode FORM_LOAD | FORM_UPDATE | FORM_SAVE
+     *
+     * @return string
+     * @throws \CodeException
+     * @throws \UserFormException
+     */
+    public function buildCheckboxSingle(array $formElement, $htmlFormElementName, $attribute, $value, array &$json, $mode = FORM_LOAD) {
+
+        if (isset($formElement[FE_BUTTON_CLASS])) {
+
+            if ($formElement[FE_BUTTON_CLASS] == '') {
+                $formElement[FE_BUTTON_CLASS] = 'btn-default';
+            }
+
+            if ($formElement[FE_MODE] == FE_MODE_READONLY) {
+                $formElement[FE_BUTTON_CLASS] .= ' disabled';
+            }
+
+            return $this->constructCheckboxSingleButton($formElement, $htmlFormElementName, $attribute, $value, $json);
+        } else {
+            return $this->constructCheckboxSinglePlain($formElement, $htmlFormElementName, $attribute, $value, $json);
+        }
+    }
+
+    /**
+     * Build a Checkbox based on two values with Bootstrap Button class.
+     *
+     * <div class="btn-group" data-toggle="buttons">
+     *    <input type="hidden" name="$htmlFormElementName" value="$valueUnChecked">
+     *    <label class="btn btn-primary active">
+     *       <input type="checkbox" autocomplete="off" name="$htmlFormElementName" value="$valueChecked"checked>
+     *       Checkbox 1 (pre-checked)
+     *    </label>
+     * </div>
+     *
+     * @param array $formElement
+     * @param string $htmlFormElementName
+     * @param string $attribute
+     * @param string $value
+     * @param array $json
+     *
+     * @return string
+     * @throws \CodeException
+     * @throws \UserFormException
+     */
+    public function constructCheckboxSingleButton(array $formElement, $htmlFormElementName, $attribute, $value, array &$json) {
+        $html = '';
+        $valueJson = false;
+
+        $attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
+        $attribute .= Support::doAttribute('name', $htmlFormElementName);
+        $attribute .= Support::doAttribute('value', $formElement[FE_CHECKBOX_CHECKED], false);
+        $attribute .= Support::doAttribute('data-load', ($formElement[FE_DYNAMIC_UPDATE] === 'yes') ? 'data-load' : '');
+        $attribute .= Support::doAttribute(FE_INPUT_AUTOCOMPLETE, 'off');
+        $attribute .= Support::doAttribute(ATTRIBUTE_DATA_REFERENCE, $formElement[FE_DATA_REFERENCE]);
+
+        $classActive = '';
+        if ($formElement[FE_CHECKBOX_CHECKED] === $value) {
+            $attribute .= Support::doAttribute('checked', 'checked');
+            $valueJson = true;
+            $classActive = ' active';
+        }
+
+        $attribute .= HelperFormElement::getAttributeList($formElement, ['autofocus']);
+        $attribute .= HelperFormElement::getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
+
+        $htmlHidden = HelperFormElement::buildNativeHidden($htmlFormElementName, $formElement[FE_CHECKBOX_UNCHECKED]);
+        $this->store->setVar($htmlFormElementName, $htmlHidden, STORE_ADDITIONAL_FORM_ELEMENTS, false);
+        $html = '';
+
+        $htmlElement = '<input ' . $attribute . '>';
+        if (isset($formElement['label2'])) {
+            $htmlElement .= $formElement['label2'];
+        } else {
+            $htmlElement .= $formElement['checked'];
+        }
+
+        $labelAttribute = Support::doAttribute('title', $formElement[FE_TOOLTIP]);
+        $labelAttribute .= Support::doAttribute('class', 'btn ' . $formElement[FE_BUTTON_CLASS] . $classActive);
+        $html .= Support::wrapTag("<label $labelAttribute>", $htmlElement, true);
+        $html = Support::wrapTag('<div class="btn-group" data-toggle="buttons">', $html);
+
+        $json = $this->getFormElementForJsonCheckbox($htmlFormElementName, $valueJson, $formElement);
+
+        return $html;
+    }
+
+    /**
+     * Create an array with standard elements for 'mode' (hidden, disabled, required, readonly)
+     * 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 string $htmlFormElementName
+     * @param string|array $value
+     * @param array $formElement
+     *
+     * @param int $optionIdx
+     * @param string $class
+     * @return array
+     * @throws \CodeException
+     * @throws \UserFormException
+     */
+    private function getFormElementForJsonCheckBox($htmlFormElementName, $value, array $formElement, $optionIdx = 0, $optionClass = '') {
+        $addClassRequired = array();
+
+        $json = HelperFormElement::getJsonFeMode($formElement[FE_MODE]); // disabled, required
+
+        $json[API_FORM_UPDATE_FORM_ELEMENT] = $htmlFormElementName;
+
+        if (isset($formElement[FE_FLAG_ROW_OPEN_TAG]) && isset($formElement[FE_FLAG_ROW_CLOSE_TAG])) {
+            $flagRowUpdate = ($formElement[FE_FLAG_ROW_OPEN_TAG] && $formElement[FE_FLAG_ROW_CLOSE_TAG]);
+        } else {
+            $flagRowUpdate = true;
+        }
+
+        $statusHidden = ($formElement[FE_MODE] == 'hidden');
+        $pattern = null;
+        if (isset($formElement[FE_CHECK_PATTERN]) && $formElement[FE_CHECK_PATTERN] != '') {
+            $pattern = $statusHidden ? false : $formElement[FE_CHECK_PATTERN];
+        }
+
+        // 'value' update via 'form-update' on the full row: only if there is no other FE in that row
+        if ($flagRowUpdate) {
+            $json[API_FORM_UPDATE_VALUE] = $value;
+
+//CR            if ($pattern !== null) {
+//                $json['pattern'] = $pattern;
+//            }
+        }
+
+        if ($formElement[FE_MODE] == FE_MODE_REQUIRED || $formElement[FE_MODE] == FE_MODE_SHOW_REQUIRED) {
+            $addClassRequired = HelperFormElement::getRequiredPositionClass($formElement[F_FE_REQUIRED_POSITION]);
+        }
+
+        // Label
+        if (isset($formElement[FE_LABEL])) {
+            $key = $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_LABEL;
+            $json[API_ELEMENT_UPDATE][$key][API_ELEMENT_CONTENT] = HelperFormElement::buildLabel($htmlFormElementName, $formElement[FE_LABEL], $addClassRequired[FE_LABEL] ?? '');
+        }
+
+        // Note
+        if (isset($formElement[FE_NOTE])) {
+            $key = $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_NOTE;
+            if (!empty($addClassRequired[FE_NOTE])) {
+                $formElement[FE_NOTE] = Support::wrapTag('<span class="' . $addClassRequired[FE_NOTE] . '">', $formElement[FE_NOTE]);
+            }
+            $json[API_ELEMENT_UPDATE][$key][API_ELEMENT_CONTENT] = $formElement[FE_NOTE];
+        }
+
+        // Input
+        if (isset($formElement[FE_TYPE])) {
+            $key = $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_INPUT;
+
+            // For FE.type='note': update the column 'input'
+            if ($formElement[FE_TYPE] === FE_TYPE_NOTE) {
+                $json[API_ELEMENT_UPDATE][$key][API_ELEMENT_CONTENT] = $value;
+            }
+
+            // Check show/hide: only FE with FE_MODE_SQL given, might change.
+            if (!empty($formElement[FE_MODE_SQL])) {
+                $class = is_numeric($formElement[FE_BS_INPUT_COLUMNS]) ? ('col-md-' . $formElement[FE_BS_INPUT_COLUMNS]) : $formElement[FE_BS_INPUT_COLUMNS];
+//                $class = 'col-md-' . $formElement[FE_BS_INPUT_COLUMNS] . ' ';
+
+                $json[API_ELEMENT_UPDATE][$key][API_ELEMENT_ATTRIBUTE]['required'] = ($formElement[FE_MODE] == 'required');
+                $json[API_ELEMENT_UPDATE][$key][API_ELEMENT_ATTRIBUTE]['hidden'] = $statusHidden;
+                $json[API_ELEMENT_UPDATE][$key][API_ELEMENT_ATTRIBUTE]['readonly'] = $json['disabled'] ? 'readonly' : 'false';
+
+                // Checkbox: Copy attributes to every checkbox (appreciated by screen reader):
+                if ($formElement[FE_TYPE] == FE_TYPE_CHECKBOX) {
+                    $optionsId = $formElement[FE_HTML_ID] . '-' . $optionIdx;
+                    $json[API_ELEMENT_UPDATE][$optionsId][API_ELEMENT_ATTRIBUTE] = $json[API_ELEMENT_UPDATE][$key][API_ELEMENT_ATTRIBUTE];
+                    $json[API_ELEMENT_UPDATE][$optionsId][API_ELEMENT_ATTRIBUTE]['data-disabled'] = $json['disabled'] ? 'yes' : 'no';
+                    $json[API_ELEMENT_UPDATE][$optionsId][API_ELEMENT_ATTRIBUTE]['data-required'] = $json['required'] ? 'yes' : 'no';
+
+                    // Update label class (i.e.: 'qfq-disabled') of Checkbox/Radio (i.e. readonly on/off).
+                    if (isset($formElement[FE_TMP_CLASS_OPTION])) {
+                        $optionsLabelId = HelperFormElement::getCheckboxRadioOptionId($formElement[FE_HTML_ID], $optionIdx, HTML_ID_EXTENSION_LABEL);
+                        $json[API_ELEMENT_UPDATE][$optionsLabelId][API_ELEMENT_ATTRIBUTE]['class'] = $formElement[FE_TMP_CLASS_OPTION];
+                    }
+                }
+
+                $class .= ($formElement[FE_MODE] == FE_MODE_HIDDEN) ? ' hidden' : '';
+                $json[API_ELEMENT_UPDATE][$key][API_ELEMENT_ATTRIBUTE]['class'] = $class;
+
+                if ($pattern !== null) {
+                    $json[API_ELEMENT_UPDATE][$key][API_ELEMENT_ATTRIBUTE]['pattern'] = $pattern;
+                }
+
+            }
+
+            // #3647
+//            if (!$flagRowUpdate) {
+
+            // #4771 - temporary workaround: SELECT in 'multi FE row' won't updated after 'save' or with dynamic update.
+            //TODO #5016 - exception for FE_TYPE_CHECKBOX should be removed ASAP
+            if ($formElement[FE_TYPE] != FE_TYPE_SELECT && $formElement[FE_TYPE] != FE_TYPE_UPLOAD && $formElement[FE_TYPE] != FE_TYPE_CHECKBOX) {
+                $json[API_ELEMENT_UPDATE][$formElement[FE_HTML_ID]][API_ELEMENT_ATTRIBUTE]['value'] = $value;
+                $json[API_ELEMENT_UPDATE][$formElement[FE_HTML_ID]][API_ELEMENT_ATTRIBUTE]['required'] = ($formElement[FE_MODE] == 'required');
+                $json[API_ELEMENT_UPDATE][$formElement[FE_HTML_ID]][API_ELEMENT_ATTRIBUTE]['hidden'] = $statusHidden;
+
+                if ($pattern !== null) {
+                    $json[API_ELEMENT_UPDATE][$formElement[FE_HTML_ID]][API_ELEMENT_ATTRIBUTE]['pattern'] = $pattern;
+                }
+            }
+        }
+
+        // Show / Hide the complete FormElement Row.
+        if (isset($formElement[FE_HTML_ID])) { // HIDDEN_SIP comes without a real existing FE structure.
+            // Activate 'show' or 'hidden' on the current FormElement via JSON 'API_ELEMENT_UPDATE'
+            $class = "form-group clearfix";
+            if ($formElement[FE_MODE] == FE_MODE_HIDDEN) {
+                $class .= ' hidden';
+            }
+
+            if (!empty($addClassRequired[FE_INPUT])) {
+                $class .= ' ' . $addClassRequired[FE_INPUT];
+            }
+
+            $key = $formElement[FE_HTML_ID] . HTML_ID_EXTENSION_ROW;
+            $json[API_ELEMENT_UPDATE][$key][API_ELEMENT_ATTRIBUTE]['class'] = $class;
+//            $json[API_ELEMENT_UPDATE][$key][API_ELEMENT_ATTRIBUTE]['buggy'] = $class;
+        }
+
+        return $json;
+    }
+
+    /**
+     * Build a single HTML plain checkbox based on two values.
+     * Create a 'hidden' input field and a 'checkbox' input field - both with the same HTML 'name'.
+     * HTML does not submit an unchecked checkbox. Then only the 'hidden' input field is submitted.
+     *
+     * Format: <input type="hidden" name="$htmlFormElementName" value="$valueUnChecked">
+     *         <input name="$htmlFormElementName" type="radio" [autofocus="autofocus"]
+     *            [required="required"] [disabled="disabled"] value="<value>" [checked="checked"] >
+     *
+     * @param array $formElement
+     * @param string $htmlFormElementName
+     * @param string $attribute
+     * @param string $value
+     * @param array $json
+     *
+     * @return string
+     * @throws \CodeException
+     * @throws \UserFormException
+     */
+    public function constructCheckboxSinglePlain(array $formElement, $htmlFormElementName, $attribute, $value, array &$json) {
+        $html = '';
+        $valueJson = false;
+
+        $attribute .= Support::doAttribute('id', $formElement[FE_HTML_ID]);
+        $attribute .= Support::doAttribute('name', $htmlFormElementName);
+        $attribute .= Support::doAttribute('value', $formElement[FE_CHECKBOX_CHECKED], false);
+        $attribute .= Support::doAttribute('data-load', ($formElement[FE_DYNAMIC_UPDATE] === 'yes') ? 'data-load' : '');
+        $attribute .= Support::doAttribute(ATTRIBUTE_DATA_REFERENCE, $formElement[FE_DATA_REFERENCE]);
+
+        if ($formElement[FE_CHECKBOX_CHECKED] === $value) {
+            $attribute .= Support::doAttribute('checked', 'checked');
+            $valueJson = $value;
+        }
+
+        $attribute .= HelperFormElement::getAttributeList($formElement, ['autofocus']);
+        $attribute .= HelperFormElement::getAttributeList($formElement, [F_FE_DATA_PATTERN_ERROR, F_FE_DATA_REQUIRED_ERROR, F_FE_DATA_MATCH_ERROR, F_FE_DATA_ERROR]);
+
+        $htmlHidden = HelperFormElement::buildNativeHidden($htmlFormElementName, $formElement[FE_CHECKBOX_UNCHECKED]);
+        $this->store->setVar($htmlFormElementName, $htmlHidden, STORE_ADDITIONAL_FORM_ELEMENTS, false);
+        $html = '';
+
+        $html .= '<input ' . $attribute . '>';
+        if (isset($formElement['label2'])) {
+            $html .= Support::wrapTag("<span style='font-weight: 400;'>", $formElement['label2']);
+        }
+
+        $labelAttribute = Support::doAttribute('title', $formElement[FE_TOOLTIP]);
+
+        $class = 'checkbox';
+        if ($formElement[FE_MODE] == FE_MODE_READONLY) {
+            $class .= ' qfq-disabled'; // necessary for own style checkboxes to display them 'disabled'
+        }
+
+        $html = Support::wrapTag("<label class='$class' $labelAttribute>", $html, true);
+//        $html = Support::wrapTag("<div class='checkbox'>", $html, true);
+
+        $json = $this->getFormElementForJsonCheckBox($htmlFormElementName, $valueJson, $formElement);
+
+        return $html;
+    }
 }
\ No newline at end of file
diff --git a/extension/Classes/Core/Helper/HelperFormElement.php b/extension/Classes/Core/Helper/HelperFormElement.php
index 6a1a02449049bf00657c4763c7318abf380447bb..97e6790c47045d67cdfaece017d07a47aed0272d 100644
--- a/extension/Classes/Core/Helper/HelperFormElement.php
+++ b/extension/Classes/Core/Helper/HelperFormElement.php
@@ -20,7 +20,7 @@ class HelperFormElement {
     /**
      * @var Store
      */
-    protected $store = null;
+    private static $store = null;
 
     /**
      * Expand column $keyName to row array as virtual columns.
@@ -790,4 +790,74 @@ EOF;
         return $attribute;
     }
 
+    /**
+     * Builds a real HTML hidden form element. Useful for checkboxes, Multiple-Select and Radios.
+     *
+     * @param        $htmlFormElementName
+     * @param string $value
+     *
+     * @return string
+     */
+    public static function buildNativeHidden($htmlFormElementName, $value) {
+        return '<input type="hidden" name="' . $htmlFormElementName . '" value="' . htmlentities($value) . '">';
+    }
+
+    /**
+     * Set corresponding JSON attributes readonly/required/disabled, based on $formElement[FE_MODE].
+     *
+     * @param string $feMode
+     *
+     * @return array
+     * @throws \UserFormException
+     */
+    public static function getJsonFeMode($feMode) {
+
+        self::getFeMode($feMode, $dummy, $disabled, $required);
+
+        return [API_FORM_UPDATE_DISABLED => ($disabled === 'yes'), API_FORM_UPDATE_REQUIRED => ($required === 'yes')];
+    }
+
+    /**
+     * Builds a label, typically for an html-'<input>'-element.
+     *
+     * @param string $htmlFormElementName
+     * @param string $label
+     * @param string $addClass
+     *
+     * @return string
+     * @throws \CodeException
+     */
+    public static function buildLabel($htmlFormElementName, $label, $addClass = '') {
+        $attributes = Support::doAttribute('for', $htmlFormElementName);
+        $attributes .= Support::doAttribute('class', ['control-label', $addClass]);
+
+        $html = Support::wrapTag("<label $attributes>", $label);
+
+        return $html;
+    }
+
+    /**
+     * Construct HTML ID for checkbox/radio option elements.
+     * Optional add $type.
+     * Example: $base='173-21612-1-0', $index='0', $type='l' >> '173-21612-1-0-0-l'
+     *
+     * @param $base
+     * @param $index
+     * @param string $type -  ';' for label
+     * @return string
+     */
+    public static function getCheckboxRadioOptionId($base, $index, $type = '') {
+        return $base . '-' . $index . $type;
+    }
+
+    /**
+     * Build HelpBlock
+     *
+     * @return string
+     */
+    public static function getHelpBlock() {
+        return '<div class="help-block with-errors hidden"></div>';
+    }
+
+
 }
\ No newline at end of file