diff --git a/Build/Resources/Public/Less/TYPO3/_main_backend_layout_wizard.less b/Build/Resources/Public/Less/TYPO3/_main_backend_layout_wizard.less
index 830d5aa65ca86980d3e5865a6a19750bbcc64ff9..7761bf2a95c61d7d4371ca0948a48d1e2cbc1b44 100644
--- a/Build/Resources/Public/Less/TYPO3/_main_backend_layout_wizard.less
+++ b/Build/Resources/Public/Less/TYPO3/_main_backend_layout_wizard.less
@@ -38,6 +38,10 @@
 		opacity: 0.5;
 	}
 
+	.grideditor-preview {
+		margin-top: 5px;
+	}
+
 	.link {
 		display: block;
 		position: absolute;
diff --git a/typo3/sysext/backend/Classes/Controller/BackendLayoutWizardController.php b/typo3/sysext/backend/Classes/Controller/BackendLayoutWizardController.php
deleted file mode 100644
index c54cc03d2f5f4b4ca06be2185465b716d2927b14..0000000000000000000000000000000000000000
--- a/typo3/sysext/backend/Classes/Controller/BackendLayoutWizardController.php
+++ /dev/null
@@ -1,378 +0,0 @@
-<?php
-namespace TYPO3\CMS\Backend\Controller;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\ServerRequestInterface;
-use TYPO3\CMS\Backend\Module\AbstractModule;
-use TYPO3\CMS\Backend\Template\Components\ButtonBar;
-use TYPO3\CMS\Backend\Utility\BackendUtility;
-use TYPO3\CMS\Core\Imaging\Icon;
-use TYPO3\CMS\Core\Page\PageRenderer;
-use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-
-/**
- * Script Class for grid wizard
- */
-class BackendLayoutWizardController extends AbstractModule
-{
-    /**
-     * GET vars:
-     * Wizard parameters, coming from TCEforms linking to the wizard.
-     * @var array
-     */
-    public $P;
-
-    /**
-     * Accumulated content.
-     * @var string
-     */
-    public $content;
-
-    /**
-     * @var string
-     */
-    public $formName;
-
-    /**
-     * @var string
-     */
-    public $fieldName;
-
-    /**
-     * @var array
-     */
-    protected $rows;
-
-    /**
-     * @var int
-     */
-    protected $colCount;
-
-    /**
-     * @var int
-     */
-    protected $rowCount;
-
-    /**
-     * Constructor
-     */
-    public function __construct()
-    {
-        parent::__construct();
-        $this->init();
-    }
-
-    /**
-     * Initialises the Class
-     *
-     * @return void
-     * @throws \InvalidArgumentException
-     */
-    public function init()
-    {
-        $lang = $this->getLanguageService();
-        $lang->includeLLFile('EXT:lang/locallang_wizards.xlf');
-
-        // Setting GET vars (used in frameset script):
-        $this->P = GeneralUtility::_GP('P');
-        $this->formName = $this->P['formName'];
-        $this->fieldName = $this->P['itemName'];
-        $hmac_validate = GeneralUtility::hmac($this->formName . $this->fieldName, 'wizard_js');
-        if (!$this->P['hmac'] || ($this->P['hmac'] !== $hmac_validate)) {
-            throw new \InvalidArgumentException('Hmac Validation failed for backend_layout wizard', 1385811397);
-        }
-        $uid = (int)$this->P['uid'];
-
-        /** @var \TYPO3\CMS\Core\Page\PageRenderer $pageRenderer */
-        $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
-        $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/GridEditor');
-        $pageRenderer->addInlineSetting(
-            'ContextHelp',
-            'moduleUrl',
-            BackendUtility::getModuleUrl(
-                'help_CshmanualCshmanual',
-                array(
-                    'tx_cshmanual_help_cshmanualcshmanual' => array(
-                        'controller' => 'Help',
-                        'action' => 'detail'
-                    )
-                )
-            )
-        );
-        $pageRenderer->addJsInlineCode('storeData', '
-            function storeData(data) {
-                if (parent.opener && parent.opener.document && parent.opener.document.' . $this->formName
-                . ' && parent.opener.document.' . $this->formName . '['
-                    . GeneralUtility::quoteJSvalue($this->fieldName) . ']) {
-                    parent.opener.document.' . $this->formName . '['
-                    . GeneralUtility::quoteJSvalue($this->fieldName) . '].value = data;
-                    parent.opener.TBE_EDITOR.fieldChanged("backend_layout","' . $uid . '","config",'
-                    . '"data[backend_layout][' . $uid . '][config]");
-                }
-            }
-            ', false);
-        $languageLabels = array(
-            'save' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_labelSave')),
-            'title' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_windowTitle')),
-            'editCell' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_editCell')),
-            'mergeCell' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_mergeCell')),
-            'splitCell' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_splitCell')),
-            'name' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_name')),
-            'column' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_column')),
-            'notSet' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_notSet')),
-            'nameHelp' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_nameHelp')),
-            'columnHelp' => htmlspecialchars($lang->sL('LLL:EXT:lang/locallang_wizards.xlf:grid_columnHelp'))
-        );
-        $pageRenderer->addInlineLanguageLabelArray($languageLabels);
-        // Select record
-        $record = $this->getDatabaseConnection()->exec_SELECTgetRows(
-            $this->P['field'],
-            $this->P['table'],
-            'uid=' . (int)$this->P['uid']
-        );
-        if (trim($record[0][$this->P['field']]) == '') {
-            $rows = array(array(array('colspan' => 1, 'rowspan' => 1, 'spanned' => false, 'name' => '')));
-            $colCount = 1;
-            $rowCount = 1;
-        } else {
-            // load TS parser
-            $parser = GeneralUtility::makeInstance(TypoScriptParser::class);
-            $parser->parse($record[0][$this->P['field']]);
-            $data = $parser->setup['backend_layout.'];
-            $rows = array();
-            $colCount = $data['colCount'];
-            $rowCount = $data['rowCount'];
-            $dataRows = $data['rows.'];
-            $spannedMatrix = array();
-            for ($i = 1; $i <= $rowCount; $i++) {
-                $cells = array();
-                $row = array_shift($dataRows);
-                $columns = $row['columns.'];
-                for ($j = 1; $j <= $colCount; $j++) {
-                    $cellData = array();
-                    if (!$spannedMatrix[$i][$j]) {
-                        if (is_array($columns) && !empty($columns)) {
-                            $column = array_shift($columns);
-                            if (isset($column['colspan'])) {
-                                $cellData['colspan'] = (int)$column['colspan'];
-                                $columnColSpan = (int)$column['colspan'];
-                                if (isset($column['rowspan'])) {
-                                    $columnRowSpan = (int)$column['rowspan'];
-                                    for ($spanRow = 0; $spanRow < $columnRowSpan; $spanRow++) {
-                                        for ($spanColumn = 0; $spanColumn < $columnColSpan; $spanColumn++) {
-                                            $spannedMatrix[$i + $spanRow][$j + $spanColumn] = 1;
-                                        }
-                                    }
-                                } else {
-                                    for ($spanColumn = 0; $spanColumn < $columnColSpan; $spanColumn++) {
-                                        $spannedMatrix[$i][$j + $spanColumn] = 1;
-                                    }
-                                }
-                            } else {
-                                $cellData['colspan'] = 1;
-                                if (isset($column['rowspan'])) {
-                                    $columnRowSpan = (int)$column['rowspan'];
-                                    for ($spanRow = 0; $spanRow < $columnRowSpan; $spanRow++) {
-                                        $spannedMatrix[$i + $spanRow][$j] = 1;
-                                    }
-                                }
-                            }
-                            if (isset($column['rowspan'])) {
-                                $cellData['rowspan'] = (int)$column['rowspan'];
-                            } else {
-                                $cellData['rowspan'] = 1;
-                            }
-                            if (isset($column['name'])) {
-                                $cellData['name'] = $column['name'];
-                            }
-                            if (isset($column['colPos'])) {
-                                $cellData['column'] = (int)$column['colPos'];
-                            }
-                        }
-                    } else {
-                        $cellData = array('colspan' => 1, 'rowspan' => 1, 'spanned' => 1);
-                    }
-                    $cells[] = $cellData;
-                }
-                $rows[] = $cells;
-                if (!empty($spannedMatrix[$i]) && is_array($spannedMatrix[$i])) {
-                    ksort($spannedMatrix[$i]);
-                }
-            }
-        }
-        $this->rows = $rows;
-        $this->colCount = (int)$colCount;
-        $this->rowCount = (int)$rowCount;
-    }
-
-    /**
-     * Injects the request object for the current request or subrequest
-     * As this controller goes only through the main() method, it is rather simple for now
-     *
-     * @param ServerRequestInterface $request
-     * @param ResponseInterface $response
-     * @return ResponseInterface
-     */
-    public function mainAction(ServerRequestInterface $request, ResponseInterface $response)
-    {
-        $this->main();
-
-        $this->setPagePath($this->P['table'], $this->P['uid']);
-
-        $this->moduleTemplate->setContent($this->content);
-        $response->getBody()->write($this->moduleTemplate->renderContent());
-        return $response;
-    }
-
-    /**
-     * Creates the correct path to the current record
-     *
-     * @param string $table
-     * @param int $uid
-     */
-    protected function setPagePath($table, $uid)
-    {
-        $uid = (int)$uid;
-
-        if ($table === 'pages') {
-            $pageId = $uid;
-        } else {
-            $record = BackendUtility::getRecord($table, $uid, '*', '', false);
-            $pageId = $record['pid'];
-        }
-
-        $pageAccess = BackendUtility::readPageAccess($pageId, $this->getBackendUser()->getPagePermsClause(1));
-        if (is_array($pageAccess)) {
-            $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($pageAccess);
-        }
-    }
-
-    /**
-     * Main Method, rendering either colorpicker or frameset depending on ->showPicker
-     *
-     * @return void
-     */
-    public function main()
-    {
-        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
-        $lang = $this->getLanguageService();
-
-        $saveButton = $buttonBar->makeInputButton()
-            ->setName('_savedok')
-            ->setValue('1')
-            ->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveDoc'))
-            ->setClasses('t3js-grideditor-savedok')
-            ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-save', Icon::SIZE_SMALL));
-
-        $saveAndCloseButton = $buttonBar->makeInputButton()
-            ->setName('_savedokandclose')
-            ->setValue('1')
-            ->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.saveCloseDoc'))
-            ->setClasses('t3js-grideditor-savedokclose')
-            ->setIcon(
-                $this->moduleTemplate->getIconFactory()->getIcon('actions-document-save-close', Icon::SIZE_SMALL)
-            );
-
-        $splitButton = $buttonBar->makeSplitButton()
-            ->addItem($saveButton)
-            ->addItem($saveAndCloseButton);
-        $buttonBar->addButton($splitButton);
-
-        $closeButton = $buttonBar->makeLinkButton()
-            ->setHref('#')
-            ->setTitle($lang->sL('LLL:EXT:lang/locallang_core.xlf:rm.closeDoc'))
-            ->setOnClick('window.close();return true;')
-            ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-document-close', Icon::SIZE_SMALL));
-        $buttonBar->addButton($closeButton, ButtonBar::BUTTON_POSITION_LEFT, 30);
-
-        $markup = array();
-        $markup[] = '';
-        $markup[] = '<table class="grideditor table table-bordered"">';
-        $markup[] = '    <tr>';
-        $markup[] = '        <td class="editor_cell">';
-        $markup[] = '           <div id="editor" class="t3js-grideditor" data-data="' . htmlspecialchars(
-            json_encode(
-                $this->rows,
-                JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS
-            )
-        ) . '" '
-        . 'data-rowcount="' . (int)$this->rowCount . '" '
-        . 'data-colcount="' . (int)$this->colCount . '">';
-        $markup[] = '            </div>';
-        $markup[] = '        </td>';
-        $markup[] = '        <td>';
-        $markup[] = '            <div class="btn-group-vertical">';
-        $markup[] = '               <a class="btn btn-default btn-sm t3js-grideditor-addcolumn" href="#" title="'
-            . htmlspecialchars($lang->getLL('grid_addColumn')) . '">';
-        $markup[] = '                <i class="fa fa-fw fa-arrow-right"></i>';
-        $markup[] = '               </a>';
-        $markup[] = '               <a class="btn btn-default btn-sm t3js-grideditor-removecolumn" href="#" title="'
-            . htmlspecialchars($lang->getLL('grid_removeColumn')) . '">';
-        $markup[] = '                <i class="fa fa-fw fa-arrow-left"></i>';
-        $markup[] = '               </a>';
-        $markup[] = '            </div>';
-        $markup[] = '        </td>';
-        $markup[] = '    </tr>';
-        $markup[] = '    <tr>';
-        $markup[] = '        <td colspan="2" align="center">';
-        $markup[] = '            <div class="btn-group">';
-        $markup[] = '               <a class="btn btn-default btn-sm t3js-grideditor-addrow" href="#" title="'
-            . htmlspecialchars($lang->getLL('grid_addRow')) . '">';
-        $markup[] = '                <i class="fa fa-fw fa-arrow-down"></i>';
-        $markup[] = '               </a>';
-        $markup[] = '               <a class="btn btn-default btn-sm t3js-grideditor-removerow" href="#" title="'
-            . htmlspecialchars($lang->getLL('grid_removeRow')) . '">';
-        $markup[] = '                <i class="fa fa-fw fa-arrow-up"></i>';
-        $markup[] = '               </a>';
-        $markup[] = '            </div>';
-        $markup[] = '        </td>';
-        $markup[] = '    </tr>';
-        $markup[] = '</table>';
-
-        $this->content .= implode(LF, $markup);
-    }
-
-    /**
-     * Returns LanguageService
-     *
-     * @return \TYPO3\CMS\Lang\LanguageService
-     */
-    protected function getLanguageService()
-    {
-        return $GLOBALS['LANG'];
-    }
-
-    /**
-     * Returns the database connection
-     *
-     * @return \TYPO3\CMS\Core\Database\DatabaseConnection
-     */
-    protected function getDatabaseConnection()
-    {
-        return $GLOBALS['TYPO3_DB'];
-    }
-
-    /**
-     * Gets the current backend user.
-     *
-     * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
-     */
-    protected function getBackendUser()
-    {
-        return $GLOBALS['BE_USER'];
-    }
-}
diff --git a/typo3/sysext/backend/Classes/View/Wizard/Element/BackendLayoutWizardElement.php b/typo3/sysext/backend/Classes/View/Wizard/Element/BackendLayoutWizardElement.php
new file mode 100644
index 0000000000000000000000000000000000000000..fe395fbf0377e9a144087d6e3e24fb4f25cb7409
--- /dev/null
+++ b/typo3/sysext/backend/Classes/View/Wizard/Element/BackendLayoutWizardElement.php
@@ -0,0 +1,195 @@
+<?php
+namespace TYPO3\CMS\Backend\View\Wizard\Element;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Backend\Form\Element\AbstractFormElement;
+use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Class BackendLayoutWizardElement
+ */
+class BackendLayoutWizardElement extends AbstractFormElement
+{
+
+    /**
+     * @var array
+     */
+    protected $resultArray = [];
+
+    /**
+     * @var array
+     */
+    protected $rows = [];
+
+    /**
+     * @var int
+     */
+    protected $colCount = 0;
+
+    /**
+     * @var int
+     */
+    protected $rowCount = 0;
+
+    /**
+     * @return array
+     */
+    public function render()
+    {
+        $this->resultArray = $this->initializeResultArray();
+        $this->init();
+
+        $lang = $this->getLanguageService();
+
+        $json = json_encode($this->rows, JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS);
+        $markup = [];
+        $markup[] = '<input type="hidden" name="' . htmlspecialchars($this->data['parameterArray']['itemFormElName'])
+            . '" value="' . htmlspecialchars($this->data['parameterArray']['itemFormElValue']) . '" />';
+        $markup[] = '<table class="grideditor table table-bordered">';
+        $markup[] = '    <tr>';
+        $markup[] = '        <td class="editor_cell">';
+        $markup[] = '           <div id="editor" class="t3js-grideditor" data-data="' . htmlspecialchars($json) . '" '
+            . 'data-rowcount="' . (int)$this->rowCount . '" '
+            . 'data-colcount="' . (int)$this->colCount . '" '
+            . 'data-field="' . htmlspecialchars($this->data['parameterArray']['itemFormElName']) . '" '
+            . '>';
+        $markup[] = '            </div>';
+        $markup[] = '        </td>';
+        $markup[] = '        <td>';
+        $markup[] = '            <div class="btn-group-vertical">';
+        $markup[] = '               <a class="btn btn-default btn-sm t3js-grideditor-addcolumn" href="#" title="'
+            . htmlspecialchars($lang->getLL('grid_addColumn')) . '">';
+        $markup[] = '                <i class="fa fa-fw fa-arrow-right"></i>';
+        $markup[] = '               </a>';
+        $markup[] = '               <a class="btn btn-default btn-sm t3js-grideditor-removecolumn" href="#" title="'
+            . htmlspecialchars($lang->getLL('grid_removeColumn')) . '">';
+        $markup[] = '                <i class="fa fa-fw fa-arrow-left"></i>';
+        $markup[] = '               </a>';
+        $markup[] = '            </div>';
+        $markup[] = '        </td>';
+        $markup[] = '    </tr>';
+        $markup[] = '    <tr>';
+        $markup[] = '        <td colspan="2" align="center">';
+        $markup[] = '            <div class="btn-group">';
+        $markup[] = '               <a class="btn btn-default btn-sm t3js-grideditor-addrow" href="#" title="'
+            . htmlspecialchars($lang->getLL('grid_addRow')) . '">';
+        $markup[] = '                <i class="fa fa-fw fa-arrow-down"></i>';
+        $markup[] = '               </a>';
+        $markup[] = '               <a class="btn btn-default btn-sm t3js-grideditor-removerow" href="#" title="'
+            . htmlspecialchars($lang->getLL('grid_removeRow')) . '">';
+        $markup[] = '                <i class="fa fa-fw fa-arrow-up"></i>';
+        $markup[] = '               </a>';
+        $markup[] = '            </div>';
+        $markup[] = '        </td>';
+        $markup[] = '    </tr>';
+        $markup[] = '    <tr>';
+        $markup[] = '        <td colspan="2">';
+        $markup[] = '            <a href="#" class="btn btn-default btn-sm t3js-grideditor-preview-button"></a>';
+        $markup[] = '            <pre class="t3js-grideditor-preview-config grideditor-preview"><code></code></pre>';
+        $markup[] = '        </td>';
+        $markup[] = '    </tr>';
+        $markup[] = '</table>';
+
+        $content = implode(LF, $markup);
+        $this->resultArray['html'] = $content;
+        $this->resultArray['requireJsModules'][] = 'TYPO3/CMS/Backend/GridEditor';
+        $this->resultArray['additionalInlineLanguageLabelFiles'][] = 'EXT:lang/locallang_wizards.xlf';
+        $this->resultArray['additionalInlineLanguageLabelFiles'][]
+            = 'EXT:backend/Resources/Private/Language/locallang.xlf';
+
+        return $this->resultArray;
+    }
+
+    /**
+     * Initialize wizard
+     */
+    protected function init()
+    {
+        if (empty($this->data['databaseRow']['config'])) {
+            $rows = [[['colspan' => 1, 'rowspan' => 1, 'spanned' => false, 'name' => '']]];
+            $colCount = 1;
+            $rowCount = 1;
+        } else {
+            // load TS parser
+            $parser = GeneralUtility::makeInstance(TypoScriptParser::class);
+            $parser->parse($this->data['databaseRow']['config']);
+            $data = $parser->setup['backend_layout.'];
+            $rows = [];
+            $colCount = $data['colCount'];
+            $rowCount = $data['rowCount'];
+            $dataRows = $data['rows.'];
+            $spannedMatrix = [];
+            for ($i = 1; $i <= $rowCount; $i++) {
+                $cells = [];
+                $row = array_shift($dataRows);
+                $columns = $row['columns.'];
+                for ($j = 1; $j <= $colCount; $j++) {
+                    $cellData = [];
+                    if (!$spannedMatrix[$i][$j]) {
+                        if (is_array($columns) && !empty($columns)) {
+                            $column = array_shift($columns);
+                            if (isset($column['colspan'])) {
+                                $cellData['colspan'] = (int)$column['colspan'];
+                                $columnColSpan = (int)$column['colspan'];
+                                if (isset($column['rowspan'])) {
+                                    $columnRowSpan = (int)$column['rowspan'];
+                                    for ($spanRow = 0; $spanRow < $columnRowSpan; $spanRow++) {
+                                        for ($spanColumn = 0; $spanColumn < $columnColSpan; $spanColumn++) {
+                                            $spannedMatrix[$i + $spanRow][$j + $spanColumn] = 1;
+                                        }
+                                    }
+                                } else {
+                                    for ($spanColumn = 0; $spanColumn < $columnColSpan; $spanColumn++) {
+                                        $spannedMatrix[$i][$j + $spanColumn] = 1;
+                                    }
+                                }
+                            } else {
+                                $cellData['colspan'] = 1;
+                                if (isset($column['rowspan'])) {
+                                    $columnRowSpan = (int)$column['rowspan'];
+                                    for ($spanRow = 0; $spanRow < $columnRowSpan; $spanRow++) {
+                                        $spannedMatrix[$i + $spanRow][$j] = 1;
+                                    }
+                                }
+                            }
+                            if (isset($column['rowspan'])) {
+                                $cellData['rowspan'] = (int)$column['rowspan'];
+                            } else {
+                                $cellData['rowspan'] = 1;
+                            }
+                            if (isset($column['name'])) {
+                                $cellData['name'] = $column['name'];
+                            }
+                            if (isset($column['colPos'])) {
+                                $cellData['column'] = (int)$column['colPos'];
+                            }
+                        }
+                    } else {
+                        $cellData = ['colspan' => 1, 'rowspan' => 1, 'spanned' => 1];
+                    }
+                    $cells[] = $cellData;
+                }
+                $rows[] = $cells;
+                if (!empty($spannedMatrix[$i]) && is_array($spannedMatrix[$i])) {
+                    ksort($spannedMatrix[$i]);
+                }
+            }
+        }
+        $this->rows = $rows;
+        $this->colCount = (int)$colCount;
+        $this->rowCount = (int)$rowCount;
+    }
+}
diff --git a/typo3/sysext/backend/Configuration/Backend/Routes.php b/typo3/sysext/backend/Configuration/Backend/Routes.php
index 60d1e8fc96330f79fa1c0c5be0767bb8a00f2d1c..e62278573f85b8d80ba209e193df9dbb526541af 100644
--- a/typo3/sysext/backend/Configuration/Backend/Routes.php
+++ b/typo3/sysext/backend/Configuration/Backend/Routes.php
@@ -38,12 +38,6 @@ return [
     ],
 
     /** Wizards */
-    // Register backend_layout wizard
-    'wizard_backend_layout' => [
-        'path' => '/wizard/backend_layout',
-        'target' => Controller\BackendLayoutWizardController::class . '::mainAction'
-    ],
-
     // Register colorpicker wizard
     'wizard_colorpicker' => [
         'path' => '/wizard/colorpicker',
diff --git a/typo3/sysext/backend/Resources/Private/Language/locallang.xlf b/typo3/sysext/backend/Resources/Private/Language/locallang.xlf
index ef6538a2f2ce9f5b1a748e7b29b7b21278b926d2..a40bd931e387c2b8132c52eff67da33fadf38f1b 100644
--- a/typo3/sysext/backend/Resources/Private/Language/locallang.xlf
+++ b/typo3/sysext/backend/Resources/Private/Language/locallang.xlf
@@ -85,6 +85,12 @@ Have a nice day.</source>
 			<trans-unit id="login.donate">
 				<source>Donate</source>
 			</trans-unit>
+			<trans-unit id="button.showPageTsConfig">
+				<source>Show PageTS-Config</source>
+			</trans-unit>
+			<trans-unit id="button.hidePageTsConfig">
+				<source>Hide PageTS-Config</source>
+			</trans-unit>
 		</body>
 	</file>
 </xliff>
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/GridEditor.js b/typo3/sysext/backend/Resources/Public/JavaScript/GridEditor.js
index 8c942376167a77a561fa614f67328b17cefb6e36..a558b439b743a689a0a984047454ecbf656169b8 100644
--- a/typo3/sysext/backend/Resources/Public/JavaScript/GridEditor.js
+++ b/typo3/sysext/backend/Resources/Public/JavaScript/GridEditor.js
@@ -20,7 +20,7 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot
 	/**
 	 * The main ContextHelp object
 	 *
-	 * @type {{colCount: number, rowCount: number, data: {}, nameLabel: string, columnLabel: string, targetElement: null}}
+	 * @type {{selectorEditor: string, selectorAddColumn: string, selectorRemoveColumn: string, selectorAddRow: string, selectorRemoveRow: string, selectorLinkEditor: string, selectorLinkExpandRight: string, selectorLinkShrinkLeft: string, selectorLinkExpandDown: string, selectorLinkShrinkUp: string, selectorDocHeaderSave: string, selectorDocHeaderSaveClose: string, selectorConfigPreview: string, selectorConfigPreviewButton: string, colCount: number, rowCount: number, field: string, data: Array, nameLabel: string, columnLabel: string, targetElement: null}}
 	 * @exports TYPO3/CMS/Backend/GridEditor
 	 */
 	var GridEditor = {
@@ -36,8 +36,11 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot
 		selectorLinkShrinkUp: '.t3js-grideditor-link-shrink-up',
 		selectorDocHeaderSave: '.t3js-grideditor-savedok',
 		selectorDocHeaderSaveClose: '.t3js-grideditor-savedokclose',
+		selectorConfigPreview: '.t3js-grideditor-preview-config',
+		selectorConfigPreviewButton: '.t3js-grideditor-preview-button',
 		colCount: 1,
 		rowCount: 1,
+		field: '',
 		data: [],
 		nameLabel: 'name',
 		columnLabel: 'columen label',
@@ -53,39 +56,36 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot
 		var $element = $(GridEditor.selectorEditor);
 		GridEditor.colCount = $element.data('colcount');
 		GridEditor.rowCount = $element.data('rowcount');
+		GridEditor.field = $('input[name="' + $element.data('field') + '"]');
 		GridEditor.data = $element.data('data');
 		GridEditor.nameLabel = config.nameLabel || 'Name';
 		GridEditor.columnLabel = config.columnLabel || 'Column';
 		GridEditor.targetElement = $(GridEditor.selectorEditor);
+		$(GridEditor.selectorConfigPreview).hide();
 
-		$(document).on('click', GridEditor.selectorDocHeaderSave, function(e) {
-			e.preventDefault();
-			storeData(GridEditor.export2LayoutRecord());
-		});
-		$(document).on('click', GridEditor.selectorDocHeaderSaveClose, function(e) {
-			e.preventDefault();
-			storeData(GridEditor.export2LayoutRecord());
-			window.close();
-		});
 		$(document).on('click', GridEditor.selectorAddColumn, function(e) {
 			e.preventDefault();
 			GridEditor.addColumn();
 			GridEditor.drawTable();
+			GridEditor.writeConfig(GridEditor.export2LayoutRecord());
 		});
 		$(document).on('click', GridEditor.selectorRemoveColumn, function(e) {
 			e.preventDefault();
 			GridEditor.removeColumn();
 			GridEditor.drawTable();
+			GridEditor.writeConfig(GridEditor.export2LayoutRecord());
 		});
 		$(document).on('click', GridEditor.selectorAddRow, function(e) {
 			e.preventDefault();
 			GridEditor.addRow();
 			GridEditor.drawTable();
+			GridEditor.writeConfig(GridEditor.export2LayoutRecord());
 		});
 		$(document).on('click', GridEditor.selectorRemoveRow, function(e) {
 			e.preventDefault();
 			GridEditor.removeRow();
 			GridEditor.drawTable();
+			GridEditor.writeConfig(GridEditor.export2LayoutRecord());
 		});
 		$(document).on('click', GridEditor.selectorLinkEditor, function(e) {
 			e.preventDefault();
@@ -101,6 +101,7 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot
 			var row = $element.data('row');
 			GridEditor.addColspan(col, row);
 			GridEditor.drawTable();
+			GridEditor.writeConfig(GridEditor.export2LayoutRecord());
 		});
 		$(document).on('click', GridEditor.selectorLinkShrinkLeft, function(e) {
 			e.preventDefault();
@@ -109,6 +110,7 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot
 			var row = $element.data('row');
 			GridEditor.removeColspan(col, row);
 			GridEditor.drawTable();
+			GridEditor.writeConfig(GridEditor.export2LayoutRecord());
 		});
 		$(document).on('click', GridEditor.selectorLinkExpandDown, function(e) {
 			e.preventDefault();
@@ -117,6 +119,7 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot
 			var row = $element.data('row');
 			GridEditor.addRowspan(col, row);
 			GridEditor.drawTable();
+			GridEditor.writeConfig(GridEditor.export2LayoutRecord());
 		});
 		$(document).on('click', GridEditor.selectorLinkShrinkUp, function(e) {
 			e.preventDefault();
@@ -125,9 +128,53 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot
 			var row = $element.data('row');
 			GridEditor.removeRowspan(col, row);
 			GridEditor.drawTable();
+			GridEditor.writeConfig(GridEditor.export2LayoutRecord());
+		});
+
+		$(GridEditor.selectorConfigPreviewButton).empty().append(TYPO3.lang['button.showPageTsConfig']);
+		$(document).on('click', GridEditor.selectorConfigPreviewButton, function(e) {
+			e.preventDefault();
+			var $preview = $(GridEditor.selectorConfigPreview);
+			var $button = $(GridEditor.selectorConfigPreviewButton);
+			if ($preview.is(':visible')) {
+				$button.empty().append(TYPO3.lang['button.showPageTsConfig']);
+				$(GridEditor.selectorConfigPreview).slideUp();
+			} else {
+				$button.empty().append(TYPO3.lang['button.hidePageTsConfig']);
+				$(GridEditor.selectorConfigPreview).slideDown();
+			}
+
 		});
 
 		GridEditor.drawTable();
+		GridEditor.writeConfig(GridEditor.export2LayoutRecord());
+	};
+
+	/**
+	 * write data back to hidden field
+	 *
+	 * @param data
+	 */
+	GridEditor.writeConfig = function(data) {
+		GridEditor.field.val(data);
+		var configLines = data.split('\n');
+		var config = '';
+		for (var i=0; i<configLines.length; i++) {
+			if (configLines[i].length) {
+				config += '\t\t\t' + configLines[i] + '\n';
+			}
+		}
+		$(GridEditor.selectorConfigPreview).find('code').empty().append(
+			'mod.web_layout.BackendLayouts {\n' +
+			'  exampleKey {\n' +
+			'    title = Example\n' +
+			'    icon = EXT:example_extension/Resources/Public/Images/BackendLayouts/default.gif\n' +
+			'    config {\n' +
+			config.replace(new RegExp('\t', 'g'), '  ') +
+			'    }\n' +
+			'  }\n' +
+			'}\n'
+		);
 	};
 
 	/**
@@ -285,22 +332,22 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot
 				var $container = $('<div class="cell_container">');
 				$cell.append($container);
 				var dataString = ' data-col="' + col + '" data-row="' + row + '"';
-				$container.append($('<a class="t3js-grideditor-link-editor link link_editor" title="' + TYPO3.lang['editCell'] + '" ' + dataString + '  href="#"><!-- --></a>'));
+				$container.append($('<a class="t3js-grideditor-link-editor link link_editor" title="' + TYPO3.lang['grid_editCell'] + '" ' + dataString + '  href="#"><!-- --></a>'));
 				if (GridEditor.cellCanSpanRight(col, row)) {
-					$container.append($('<a class="t3js-grideditor-link-expand-right link link_expand_right" href="#"  title="' + TYPO3.lang['mergeCell'] + '" ' + dataString + '><!-- --></a>'));
+					$container.append($('<a class="t3js-grideditor-link-expand-right link link_expand_right" href="#"  title="' + TYPO3.lang['grid_mergeCell'] + '" ' + dataString + '><!-- --></a>'));
 				}
 				if (GridEditor.cellCanShrinkLeft(col, row)) {
-					$container.append('<a class="t3js-grideditor-link-shrink-left link link_shrink_left" href="#" title="' + TYPO3.lang['splitCell'] + '" ' + dataString + '><!-- --></a>');
+					$container.append('<a class="t3js-grideditor-link-shrink-left link link_shrink_left" href="#" title="' + TYPO3.lang['grid_splitCell'] + '" ' + dataString + '><!-- --></a>');
 				}
 				if (GridEditor.cellCanSpanDown(col, row)) {
-					$container.append('<a class="t3js-grideditor-link-expand-down link link_expand_down" href="#" title="' + TYPO3.lang['mergeCell'] + '" ' + dataString + '><!-- --></a>');
+					$container.append('<a class="t3js-grideditor-link-expand-down link link_expand_down" href="#" title="' + TYPO3.lang['grid_mergeCell'] + '" ' + dataString + '><!-- --></a>');
 				}
 				if (GridEditor.cellCanShrinkUp(col, row)) {
-					$container.append('<a class="t3js-grideditor-link-shrink-up link link_shrink_up" href="#" title="' + TYPO3.lang['splitCell'] + '" ' + dataString + '><!-- --></a>');
+					$container.append('<a class="t3js-grideditor-link-shrink-up link link_shrink_up" href="#" title="' + TYPO3.lang['grid_splitCell'] + '" ' + dataString + '><!-- --></a>');
 				}
-				$cell.append('<div class="cell_data">' + TYPO3.lang['name'] + ': ' + (cell.name ? GridEditor.stripMarkup(cell.name) : TYPO3.lang['notSet'])
-					+ '<br />' + TYPO3.lang['column'] + ': '
-					+ (cell.column === undefined ? TYPO3.lang['notSet'] : parseInt(cell.column, 10)) + '</div>');
+				$cell.append('<div class="cell_data">' + TYPO3.lang['grid_name'] + ': ' + (cell.name ? GridEditor.stripMarkup(cell.name) : TYPO3.lang['grid_notSet'])
+					+ '<br />' + TYPO3.lang['grid_column'] + ': '
+					+ (cell.column === undefined ? TYPO3.lang['grid_notSet'] : parseInt(cell.column, 10)) + '</div>');
 
 				if (cell.colspan > 1) {
 					$cell.attr('colspan', cell.colspan);
@@ -367,20 +414,29 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot
 			return false;
 		}
 
+		var colPos;
+		if (cell.column === 0) {
+			colPos = 0;
+		} else if(parseInt(cell.column, 10)) {
+			colPos = parseInt(cell.column, 10);
+		} else {
+			colPos = '';
+		}
+
 		var $markup = $('<div>');
 		$markup.append(
 			'<div>' +
 				'<div class="form-group">' +
-					'<label>' + TYPO3.lang['nameHelp'] + '</label>' +
+					'<label>' + TYPO3.lang['grid_nameHelp'] + '</label>' +
 					'<input type="text" class="t3js-grideditor-field-name form-control" name="name" value="' + (GridEditor.stripMarkup(cell.name) || '') + '">' +
 				'</div>' +
 				'<div class="form-group">' +
-					'<label>' + TYPO3.lang['columnHelp'] + '</label>' +
-					'<input type="text" class="t3js-grideditor-field-colpos form-control" name="name" value="' + (parseInt(cell.column, 10) || '') + '">' +
+					'<label>' + TYPO3.lang['grid_columnHelp'] + '</label>' +
+					'<input type="text" class="t3js-grideditor-field-colpos form-control" name="name" value="' + colPos + '">' +
 				'</div>' +
 			'</div>'
 		);
-		var $modal = Modal.show(TYPO3.lang['title'], $markup, Severity.notice, [
+		var $modal = Modal.show(TYPO3.lang['grid_windowTitle'], $markup, Severity.notice, [
 			{
 				text: $(this).data('button-close-text') || TYPO3.lang['button.cancel'] || 'Cancel',
 				active: true,
@@ -397,12 +453,13 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'boot
 		$modal.data('row', row);
 		$modal.on('button.clicked', function(e) {
 			if (e.target.name === 'cancel') {
-				$(this).trigger('modal-dismiss');
+				Modal.currentModal.trigger('modal-dismiss');
 			} else if (e.target.name === 'ok') {
 				GridEditor.setName($modal.find('.t3js-grideditor-field-name').val(), $modal.data('col'), $modal.data('row'));
 				GridEditor.setColumn($modal.find('.t3js-grideditor-field-colpos').val(), $modal.data('col'), $modal.data('row'));
 				GridEditor.drawTable();
-				$(this).trigger('modal-dismiss');
+				GridEditor.writeConfig(GridEditor.export2LayoutRecord());
+				Modal.currentModal.trigger('modal-dismiss');
 			}
 		});
 	};
diff --git a/typo3/sysext/backend/ext_localconf.php b/typo3/sysext/backend/ext_localconf.php
index 9535b56af6abdd198f988b7845d272fc70e66a22..3a85e44bbea054c3083020e9eaa6e2b4cb12b7e6 100644
--- a/typo3/sysext/backend/ext_localconf.php
+++ b/typo3/sysext/backend/ext_localconf.php
@@ -26,6 +26,12 @@ if (TYPO3_MODE === 'BE') {
     $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['backend']['avatarProviders']['defaultAvatarProvider'] = array(
         'provider' => \TYPO3\CMS\Backend\Backend\Avatar\DefaultAvatarProvider::class
     );
+
+    $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1460321142] = array(
+        'nodeName' => 'belayoutwizard',
+        'priority' => 40,
+        'class' => \TYPO3\CMS\Backend\View\Wizard\Element\BackendLayoutWizardElement::class,
+    );
 }
 
 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default'] = \TYPO3\CMS\Core\FrontendEditing\FrontendEditingController::class;
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-75497-InlineBackendLayoutWizard.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-75497-InlineBackendLayoutWizard.rst
new file mode 100644
index 0000000000000000000000000000000000000000..ab562ec1589a494d94063db5c2edb1bd7107c6bd
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/master/Breaking-75497-InlineBackendLayoutWizard.rst
@@ -0,0 +1,28 @@
+===============================================
+Breaking: #75497 - inline backend layout wizard
+===============================================
+
+Description
+===========
+
+The ``BackendLayoutWizardController`` has been removed and a new renderType has been added to render the backend layout wizard inline in FormEngine.
+
+Also the backend route ``wizard_backend_layout`` has been removed.
+
+
+Impact
+======
+
+Extending or using the ``BackendLayoutWizardController`` will break your installation.
+
+
+Affected Installations
+======================
+
+An installation which uses an extension which make use of ``BackendLayoutWizardController``
+
+
+Migration
+=========
+
+Use the renderType "belayoutwizard", which renders the backend layout wizard inline in FormEngine.
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-75497-InlineBackendLayoutWizard.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-75497-InlineBackendLayoutWizard.rst
new file mode 100644
index 0000000000000000000000000000000000000000..a89a25539fd1ee56ae8c3f1be0b728862083d513
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-75497-InlineBackendLayoutWizard.rst
@@ -0,0 +1,28 @@
+==============================================
+Feature: #75497 - inline backend layout wizard
+==============================================
+
+Description
+===========
+
+A new renderType was added to render the backend layout wizard inline in FormEngine.
+
+
+Impact
+======
+
+The old ``BackendLayoutWizardController`` which has rendered the backend layout wizard in a popup has been removed.
+
+Use the new renderType ``belayoutwizard`` to render the backend layout wizard inline in FormEngine.
+
+example TCA configuration:
+
+.. code-block:: php
+
+   'config' => array(
+      'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:backend_layout.config',
+      'config' => array(
+         'type' => 'text',
+         'renderType' => 'belayoutwizard',
+      )
+   )
diff --git a/typo3/sysext/frontend/Configuration/TCA/backend_layout.php b/typo3/sysext/frontend/Configuration/TCA/backend_layout.php
index 20bffbb5a8140a8827bd0c860f5c708830c6f7e1..67d4374be9fe4e9cf4483dcefb2e6c50524de4ee 100644
--- a/typo3/sysext/frontend/Configuration/TCA/backend_layout.php
+++ b/typo3/sysext/frontend/Configuration/TCA/backend_layout.php
@@ -46,22 +46,8 @@ return array(
             'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:backend_layout.config',
             'config' => array(
                 'type' => 'text',
-                'rows' => '10',
-                'cols' => '48',
-                'wrap' => 'OFF',
-                'wizards' => array(
-                    0 => array(
-                        'title' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:backend_layout.wizard',
-                        'type' => 'popup',
-                        'icon' => 'wizard-backendlayout',
-                        'module' => array(
-                            'name' => 'wizard_backend_layout'
-                        ),
-                        'JSopenParams' => 'height=800,width=800,status=0,menubar=0,scrollbars=0'
-                    )
-                )
-            ),
-            'defaultExtras' => 'fixed-font : enable-tab',
+                'renderType' => 'belayoutwizard',
+            )
         ),
         'hidden' => array(
             'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.disable',
@@ -87,7 +73,9 @@ return array(
     ),
     'types' => array(
         '1' => array(
-            'showitem' => 'hidden, title, icon, description, config',
+            'showitem' => 'title,icon,config,
+            --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:backend_layout.tabs.access, hidden,
+            --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:backend_layout.tabs.extended, description',
         ),
     )
 );
diff --git a/typo3/sysext/frontend/Resources/Private/Language/locallang_tca.xlf b/typo3/sysext/frontend/Resources/Private/Language/locallang_tca.xlf
index 8da535d560e618a8ea9c78432379ed4c7a2ef709..ede7c95ce9ad57791eb8d6e9b45f91d81d7a833a 100644
--- a/typo3/sysext/frontend/Resources/Private/Language/locallang_tca.xlf
+++ b/typo3/sysext/frontend/Resources/Private/Language/locallang_tca.xlf
@@ -621,6 +621,12 @@
 			<trans-unit id="backend_layout.icon">
 				<source>Icon</source>
 			</trans-unit>
+			<trans-unit id="backend_layout.tabs.access">
+				<source>Access</source>
+			</trans-unit>
+			<trans-unit id="backend_layout.tabs.extended">
+				<source>Extended</source>
+			</trans-unit>
 		</body>
 	</file>
 </xliff>
diff --git a/typo3/sysext/t3skin/Resources/Public/Css/backend.css b/typo3/sysext/t3skin/Resources/Public/Css/backend.css
index 4656599f14066e2440181a4609f040df10ff1fec..ba4800ed70e6c72363fae48454ec34042b4fe7d1 100644
--- a/typo3/sysext/t3skin/Resources/Public/Css/backend.css
+++ b/typo3/sysext/t3skin/Resources/Public/Css/backend.css
@@ -11347,6 +11347,9 @@ span.warningboxheader {
 .grideditor div.cell_container:hover {
   opacity: 0.5;
 }
+.grideditor .grideditor-preview {
+  margin-top: 5px;
+}
 .grideditor .link {
   display: block;
   position: absolute;