diff --git a/typo3/sysext/backend/Classes/Controller/SelectTreeController.php b/typo3/sysext/backend/Classes/Controller/SelectTreeController.php
index 01a25f69ebd8019d0674a548e24b76a18f73383f..a0f6423a6b2b68ba22809a6a9768f5ebe4bfa5d5 100644
--- a/typo3/sysext/backend/Classes/Controller/SelectTreeController.php
+++ b/typo3/sysext/backend/Classes/Controller/SelectTreeController.php
@@ -18,6 +18,7 @@ use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
 use TYPO3\CMS\Backend\Form\FormDataCompiler;
 use TYPO3\CMS\Backend\Form\FormDataGroup\TcaDatabaseRecord;
+use TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -35,25 +36,76 @@ class SelectTreeController
     public function fetchDataAction(ServerRequestInterface $request, ResponseInterface $response)
     {
         $tableName = $request->getQueryParams()['table'];
-        if (!$this->getBackendUser()->check('tables_select', $tableName)) {
-            return $response;
+        $fieldName = $request->getQueryParams()['field'];
+
+        // Prepare processedTca: Remove all column definitions except the one that contains
+        // our tree definition. This way only this field is calculated, everything else is ignored.
+        if (!isset($GLOBALS['TCA'][$tableName])  || !is_array($GLOBALS['TCA'][$tableName])) {
+            throw new \RuntimeException(
+                'TCA for table ' . $tableName . ' not found',
+                1479386729
+            );
         }
+        $processedTca = $GLOBALS['TCA'][$tableName];
+        if (!isset($processedTca['columns'][$fieldName]) || !is_array($processedTca['columns'][$fieldName])) {
+            throw new \RuntimeException(
+                'TCA for table ' . $tableName . ' and field ' . $fieldName . ' not found',
+                1479386990
+            );
+        }
+
+        // Force given record type and set showitem to our field only
+        $recordTypeValue = $request->getQueryParams()['record_type_value'];
+        $processedTca['types'][$recordTypeValue]['showitem'] = $fieldName;
+        // Unset all columns except our field
+        $processedTca['columns'] = [
+            $fieldName => $processedTca['columns'][$fieldName],
+        ];
+
+        $flexFormPath = [];
+        if ($processedTca['columns'][$fieldName]['config']['type'] === 'flex') {
+            $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
+            $dataStructureIdentifier = json_encode($request->getQueryParams()['flex_form_datastructure_identifier']);
+            $dataStructure = $flexFormTools->parseDataStructureByIdentifier($dataStructureIdentifier);
+            // Try to reduce given data structure down to the relevant element only
+            $flexFormPath = $request->getQueryParams()['flex_form_path'];
+            $fieldPattern = 'data[' . $tableName . '][';
+            $flexFormPath = str_replace($fieldPattern, '', $flexFormPath);
+            $flexFormPath = substr($flexFormPath, 0, -1);
+            $flexFormPath = explode('][', $flexFormPath);
+            if (isset($dataStructure['sheets'][$flexFormPath[3]]['ROOT']['el'][$flexFormPath[5]])) {
+                $dataStructure = [
+                    'sheets' => [
+                        $flexFormPath[3] => [
+                            'ROOT' => [
+                                'type' => 'array',
+                                'el' => [
+                                    $flexFormPath[5] => $dataStructure['sheets'][$flexFormPath[3]]['ROOT']['el'][$flexFormPath[5]],
+                                ],
+                            ],
+                        ],
+                    ],
+                ];
+            }
+            $processedTca['columns'][$fieldName]['config']['ds'] = $dataStructure;
+            $processedTca['columns'][$fieldName]['config']['dataStructureIdentifier'] = $dataStructureIdentifier;
+        }
+
         $formDataGroup = GeneralUtility::makeInstance(TcaDatabaseRecord::class);
         $formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class, $formDataGroup);
-
         $formDataCompilerInput = [
             'tableName' => $request->getQueryParams()['table'],
             'vanillaUid' => (int)$request->getQueryParams()['uid'],
             'command' => $request->getQueryParams()['command'],
+            'processedTca' => $processedTca,
+            'recordTypeValue' => $recordTypeValue,
+            'selectTreeCompileItems' => true,
         ];
-
-        $fieldName = $request->getQueryParams()['field'];
         $formData = $formDataCompiler->compile($formDataCompilerInput);
 
         if ($formData['processedTca']['columns'][$fieldName]['config']['type'] === 'flex') {
-            $flexFormFieldName = $request->getQueryParams()['flex_form_field_name'];
-            $value = $this->searchForFieldInFlexStructure($formData['processedTca']['columns'][$fieldName]['config'], $flexFormFieldName);
-            $treeData = $value['config']['treeData'];
+            $treeData = $formData['processedTca']['columns'][$fieldName]['config']['ds']
+                ['sheets'][$flexFormPath[3]]['ROOT']['el'][$flexFormPath[5]]['config']['treeData'];
         } else {
             $treeData = $formData['processedTca']['columns'][$fieldName]['config']['treeData'];
         }
@@ -62,37 +114,4 @@ class SelectTreeController
         $response->getBody()->write($json);
         return $response;
     }
-
-    /**
-     * A workaround for flexforms - there is no easy way to get flex field by key, so we need to search for it
-     *
-     * @todo remove me once flexforms are refactored
-     *
-     * @param array $array
-     * @param string $needle
-     * @return array
-     */
-    protected function searchForFieldInFlexStructure(array $array, $needle)
-    {
-        $needle = trim($needle);
-        $iterator  = new \RecursiveArrayIterator($array);
-        $recursive = new \RecursiveIteratorIterator(
-            $iterator,
-            \RecursiveIteratorIterator::SELF_FIRST
-        );
-        foreach ($recursive as $key => $value) {
-            if ($key === $needle) {
-                return $value;
-            }
-        }
-        return [];
-    }
-
-    /**
-     * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
-     */
-    protected function getBackendUser()
-    {
-        return $GLOBALS['BE_USER'];
-    }
 }
diff --git a/typo3/sysext/backend/Classes/Form/Container/FlexFormElementContainer.php b/typo3/sysext/backend/Classes/Form/Container/FlexFormElementContainer.php
index 5e8d4911732a7f2a97b2251c6d3be04099c3fde9..c8b7cc842fff2982d2ceabbe557e9e9c075167ea 100644
--- a/typo3/sysext/backend/Classes/Form/Container/FlexFormElementContainer.php
+++ b/typo3/sysext/backend/Classes/Form/Container/FlexFormElementContainer.php
@@ -79,8 +79,6 @@ class FlexFormElementContainer extends AbstractContainer
                 // Set up options for single element
                 $fakeParameterArray = [
                     'fieldConf' => [
-                        // @todo review this field during flex refactoring
-                        'flexFormFieldName' => $flexFormFieldName,
                         'label' => $languageService->sL(trim($flexFormFieldArray['label'])),
                         'config' => $flexFormFieldArray['config'],
                         'children' => $flexFormFieldArray['children'],
diff --git a/typo3/sysext/backend/Classes/Form/Element/SelectTreeElement.php b/typo3/sysext/backend/Classes/Form/Element/SelectTreeElement.php
index d1ae3ff5711f3a6392f2163ccbf86da0c4aebfdd..4af7e775f0c6b75c8b13d414fd538783aadb5ff2 100644
--- a/typo3/sysext/backend/Classes/Form/Element/SelectTreeElement.php
+++ b/typo3/sysext/backend/Classes/Form/Element/SelectTreeElement.php
@@ -76,7 +76,12 @@ class SelectTreeElement extends AbstractFormElement
         $heightInPx = $height * $this->itemHeight;
         $treeWrapperId = 'tree_' . $formElementId;
 
-        $flexFormFieldName = !empty($parameterArray['fieldConf']['flexFormFieldName']) ? htmlspecialchars($parameterArray['fieldConf']['flexFormFieldName']) : '';
+        $fieldName = $this->data['fieldName'];
+        $flexDataStructureIdentifier = '';
+        if ($this->data['processedTca']['columns'][$fieldName]['config']['type'] === 'flex') {
+            $flexDataStructureIdentifier = $this->data['processedTca']['columns'][$fieldName]['config']['dataStructureIdentifier'];
+        }
+
         $html = [];
         $html[] = '<div class="typo3-tceforms-tree">';
         $html[] = '    <input class="treeRecord" type="hidden"';
@@ -85,8 +90,9 @@ class SelectTreeElement extends AbstractFormElement
         $html[] = '           data-relatedfieldname="' . htmlspecialchars($parameterArray['itemFormElName']) . '"';
         $html[] = '           data-table="' . htmlspecialchars($this->data['tableName']) . '"';
         $html[] = '           data-field="' . htmlspecialchars($this->data['fieldName']) . '"';
-        $html[] = '           data-flex-form-field-name="' . $flexFormFieldName . '"';
+        $html[] = '           data-flex-form-datastructure-identifier="' . htmlspecialchars($flexDataStructureIdentifier) . '"';
         $html[] = '           data-uid="' . (int)$this->data['vanillaUid'] . '"';
+        $html[] = '           data-recordtypevalue="' . $this->data['recordTypeValue'] . '"';
         $html[] = '           data-command="' . htmlspecialchars($this->data['command']) . '"';
         $html[] = '           data-read-only="' . $readOnly . '"';
         $html[] = '           data-tree-exclusive-keys="' . htmlspecialchars($exclusiveKeys) . '"';
diff --git a/typo3/sysext/backend/Classes/Form/FormDataCompiler.php b/typo3/sysext/backend/Classes/Form/FormDataCompiler.php
index 24fff348aff55b7fe333d09a2520b48b6db25693..ff8729cf9475bd09ac9695bde60cf7e079acdd6e 100644
--- a/typo3/sysext/backend/Classes/Form/FormDataCompiler.php
+++ b/typo3/sysext/backend/Classes/Form/FormDataCompiler.php
@@ -190,7 +190,7 @@ class FormDataCompiler
             // can be shown. This array holds those additional language records, Array key is sys_language_uid.
             'additionalLanguageRows' => [],
             // The tca record type value of the record. Forced to string, there can be "named" type values.
-            'recordTypeValue' => '0',
+            'recordTypeValue' => '',
             // TCA of table with processed fields. After processing, this array contains merged and resolved
             // array data, items were resolved, only used types are set, renderTypes are set.
             'processedTca' => [],
@@ -204,6 +204,10 @@ class FormDataCompiler
             // itemsProcFunc need to have this data at hand to do their job.
             'flexParentDatabaseRow' => [],
 
+            // If true, TcaSelectTreeItems data provider will compile tree items. This is false by default since
+            // on opening a record items are not calculated but are fetch in an ajax request, see SelectTreeController.
+            'selectTreeCompileItems' => false,
+
             // BackendUser->uc['inlineView'] - This array holds status of expand / collapsed inline items
             // This array is "flat", an inline structure with parent uid 1 having firstChild uid 2 having secondChild uid 3
             // firstChild and secondChild are not nested. If an uid is set it means "record is expanded", example:
diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/DatabaseRecordTypeValue.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/DatabaseRecordTypeValue.php
index e78cb7a115114aaf1f76fcdefa1601cae002dfd8..dc8a85dc128f37094d442e80d8092c13028fae3e 100644
--- a/typo3/sysext/backend/Classes/Form/FormDataProvider/DatabaseRecordTypeValue.php
+++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/DatabaseRecordTypeValue.php
@@ -46,6 +46,11 @@ class DatabaseRecordTypeValue implements FormDataProviderInterface
             );
         }
 
+        // Guard clause to suppress any calculation if record type value has been set from outside already
+        if ($result['recordTypeValue'] !== '') {
+            return $result;
+        }
+
         $recordTypeValue = '0';
         if (!empty($result['processedTca']['ctrl']['type'])) {
             $tcaTypeField = $result['processedTca']['ctrl']['type'];
diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/InitializeProcessedTca.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/InitializeProcessedTca.php
index 2d807f4fd27c31a75dcc229e8d6ddfef9babd16e..4cfb47adf60d644b6315081be4bb3dba812cf0b2 100644
--- a/typo3/sysext/backend/Classes/Form/FormDataProvider/InitializeProcessedTca.php
+++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/InitializeProcessedTca.php
@@ -30,16 +30,19 @@ class InitializeProcessedTca implements FormDataProviderInterface
      */
     public function addData(array $result)
     {
-        if (
-            !isset($GLOBALS['TCA'][$result['tableName']])
-            || !is_array($GLOBALS['TCA'][$result['tableName']])
-        ) {
-            throw new \UnexpectedValueException(
-                'TCA for table ' . $result['tableName'] . ' not found',
-                1437914223
-            );
+        if (empty($result['processedTca'])) {
+            if (
+                !isset($GLOBALS['TCA'][$result['tableName']])
+                || !is_array($GLOBALS['TCA'][$result['tableName']])
+            ) {
+                throw new \UnexpectedValueException(
+                    'TCA for table ' . $result['tableName'] . ' not found',
+                    1437914223
+                );
+            }
+
+            $result['processedTca'] = $GLOBALS['TCA'][$result['tableName']];
         }
-        $result['processedTca'] = $GLOBALS['TCA'][$result['tableName']];
 
         if (!is_array($result['processedTca']['columns'])) {
             throw new \UnexpectedValueException(
diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php
index 054fd306432fd29326c05cba3db61e37eab5b202..e0f2843b3714403890d3a597f14ed2c317817167 100644
--- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php
+++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php
@@ -63,16 +63,21 @@ class TcaFlexPrepare implements FormDataProviderInterface
      */
     protected function initializeDataStructure(array $result, $fieldName)
     {
-        $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
-        $dataStructureIdentifier = $flexFormTools->getDataStructureIdentifier(
-            $result['processedTca']['columns'][$fieldName],
-            $result['tableName'],
-            $fieldName,
-            $result['databaseRow']
-        );
-        // Add the identifier to TCA to use it later during rendering
-        $result['processedTca']['columns'][$fieldName]['config']['dataStructureIdentifier'] = $dataStructureIdentifier;
-        $dataStructureArray = $flexFormTools->parseDataStructureByIdentifier($dataStructureIdentifier);
+        if (!isset($result['processedTca']['columns'][$fieldName]['config']['dataStructureIdentifier'])) {
+            $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
+            $dataStructureIdentifier = $flexFormTools->getDataStructureIdentifier(
+                $result['processedTca']['columns'][$fieldName],
+                $result['tableName'],
+                $fieldName,
+                $result['databaseRow']
+            );
+            // Add the identifier to TCA to use it later during rendering
+            $result['processedTca']['columns'][$fieldName]['config']['dataStructureIdentifier'] = $dataStructureIdentifier;
+            $dataStructureArray = $flexFormTools->parseDataStructureByIdentifier($dataStructureIdentifier);
+        } else {
+            // Assume the data structure has been given from outside if the data structure identifier is already set.
+            $dataStructureArray = $result['processedTca']['columns'][$fieldName]['config']['ds'];
+        }
         if (!isset($dataStructureArray['meta']) || !is_array($dataStructureArray['meta'])) {
             $dataStructureArray['meta'] = [];
         }
diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexProcess.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexProcess.php
index ada1c46063fa87818932502e8c3b10b85f3a4bbc..b40826741017ad49cd3451cb727bd391fda9fac1 100644
--- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexProcess.php
+++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexProcess.php
@@ -468,6 +468,7 @@ class TcaFlexProcess implements FormDataProviderInterface
                                                 $singleFieldName => $singleFieldConfiguration,
                                             ],
                                         ],
+                                        'selectTreeCompileItems' => false,
                                         'flexParentDatabaseRow' => $result['databaseRow'],
                                     ];
                                     $flexSegmentResult = $formDataCompiler->compile($inputToFlexFormSegment);
@@ -518,6 +519,8 @@ class TcaFlexProcess implements FormDataProviderInterface
                     'columns' => [],
                 ],
                 'flexParentDatabaseRow' => $result['databaseRow'],
+                // Whether to compile TCA tree items - inherit from parent
+                'selectTreeCompileItems' => $result['selectTreeCompileItems'],
             ];
 
             if (!empty($tcaNewColumns)) {
diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectTreeItems.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectTreeItems.php
index eede7112f17cc949d3ba54f9235bf7289fc29ee5..92fed04939be7fd3cee7e68f5a82ba10e153250a 100644
--- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectTreeItems.php
+++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectTreeItems.php
@@ -46,42 +46,8 @@ class TcaSelectTreeItems extends AbstractItemProvider implements FormDataProvide
                 continue;
             }
 
-            $fieldConfig['config']['items'] = $this->sanitizeItemArray($fieldConfig['config']['items'], $table, $fieldName);
             $fieldConfig['config']['maxitems'] = $this->sanitizeMaxItems($fieldConfig['config']['maxitems']);
 
-            $pageTsConfigAddItems = $this->addItemsFromPageTsConfig($result, $fieldName, []);
-            $fieldConfig['config']['items'] = $this->addItemsFromSpecial($result, $fieldName, $fieldConfig['config']['items']);
-            $fieldConfig['config']['items'] = $this->addItemsFromFolder($result, $fieldName, $fieldConfig['config']['items']);
-            $staticItems = $fieldConfig['config']['items'] + $pageTsConfigAddItems;
-
-            $fieldConfig['config']['items'] = $this->addItemsFromForeignTable($result, $fieldName, $fieldConfig['config']['items']);
-            $dynamicItems = array_diff_key($fieldConfig['config']['items'], $staticItems);
-
-            $fieldConfig['config']['items'] = $this->removeItemsByKeepItemsPageTsConfig($result, $fieldName, $fieldConfig['config']['items']);
-            $fieldConfig['config']['items'] = $pageTsConfigAddItems + $fieldConfig['config']['items'];
-            $fieldConfig['config']['items'] = $this->removeItemsByRemoveItemsPageTsConfig($result, $fieldName, $fieldConfig['config']['items']);
-
-            $fieldConfig['config']['items'] = $this->removeItemsByUserLanguageFieldRestriction($result, $fieldName, $fieldConfig['config']['items']);
-            $fieldConfig['config']['items'] = $this->removeItemsByUserAuthMode($result, $fieldName, $fieldConfig['config']['items']);
-            $fieldConfig['config']['items'] = $this->removeItemsByDoktypeUserRestriction($result, $fieldName, $fieldConfig['config']['items']);
-
-            // Resolve "itemsProcFunc"
-            if (!empty($fieldConfig['config']['itemsProcFunc'])) {
-                $fieldConfig['config']['items'] = $this->resolveItemProcessorFunction($result, $fieldName, $fieldConfig['config']['items']);
-                // itemsProcFunc must not be used anymore
-                unset($fieldConfig['config']['itemsProcFunc']);
-            }
-
-            // Translate labels
-            $fieldConfig['config']['items'] = $this->translateLabels($result, $fieldConfig['config']['items'], $table, $fieldName);
-
-            $staticValues = $this->getStaticValues($fieldConfig['config']['items'], $dynamicItems);
-            $result['databaseRow'][$fieldName] = $this->processDatabaseFieldValue($result['databaseRow'], $fieldName);
-            $result['databaseRow'][$fieldName] = $this->processSelectFieldValue($result, $fieldName, $staticValues);
-
-            // Keys may contain table names, so a numeric array is created
-            $fieldConfig['config']['items'] = array_values($fieldConfig['config']['items']);
-
             // A couple of tree specific config parameters can be overwritten via page TS.
             // Pick those that influence the data fetching and write them into the config
             // given to the tree data provider
@@ -102,7 +68,44 @@ class TcaSelectTreeItems extends AbstractItemProvider implements FormDataProvide
                 }
             }
 
-            $fieldConfig['config']['treeData'] = $this->renderTree($result, $fieldConfig, $fieldName, $staticItems);
+            if ($result['selectTreeCompileItems']) {
+                $fieldConfig['config']['items'] = $this->sanitizeItemArray($fieldConfig['config']['items'], $table, $fieldName);
+
+                $pageTsConfigAddItems = $this->addItemsFromPageTsConfig($result, $fieldName, []);
+                $fieldConfig['config']['items'] = $this->addItemsFromSpecial($result, $fieldName, $fieldConfig['config']['items']);
+                $fieldConfig['config']['items'] = $this->addItemsFromFolder($result, $fieldName, $fieldConfig['config']['items']);
+                $staticItems = $fieldConfig['config']['items'] + $pageTsConfigAddItems;
+
+                $fieldConfig['config']['items'] = $this->addItemsFromForeignTable($result, $fieldName, $fieldConfig['config']['items']);
+                $dynamicItems = array_diff_key($fieldConfig['config']['items'], $staticItems);
+
+                $fieldConfig['config']['items'] = $this->removeItemsByKeepItemsPageTsConfig($result, $fieldName, $fieldConfig['config']['items']);
+                $fieldConfig['config']['items'] = $pageTsConfigAddItems + $fieldConfig['config']['items'];
+                $fieldConfig['config']['items'] = $this->removeItemsByRemoveItemsPageTsConfig($result, $fieldName, $fieldConfig['config']['items']);
+
+                $fieldConfig['config']['items'] = $this->removeItemsByUserLanguageFieldRestriction($result, $fieldName, $fieldConfig['config']['items']);
+                $fieldConfig['config']['items'] = $this->removeItemsByUserAuthMode($result, $fieldName, $fieldConfig['config']['items']);
+                $fieldConfig['config']['items'] = $this->removeItemsByDoktypeUserRestriction($result, $fieldName, $fieldConfig['config']['items']);
+
+                // Resolve "itemsProcFunc"
+                if (!empty($fieldConfig['config']['itemsProcFunc'])) {
+                    $fieldConfig['config']['items'] = $this->resolveItemProcessorFunction($result, $fieldName, $fieldConfig['config']['items']);
+                    // itemsProcFunc must not be used anymore
+                    unset($fieldConfig['config']['itemsProcFunc']);
+                }
+
+                // Translate labels
+                $fieldConfig['config']['items'] = $this->translateLabels($result, $fieldConfig['config']['items'], $table, $fieldName);
+
+                $staticValues = $this->getStaticValues($fieldConfig['config']['items'], $dynamicItems);
+                $result['databaseRow'][$fieldName] = $this->processDatabaseFieldValue($result['databaseRow'], $fieldName);
+                $result['databaseRow'][$fieldName] = $this->processSelectFieldValue($result, $fieldName, $staticValues);
+
+                // Keys may contain table names, so a numeric array is created
+                $fieldConfig['config']['items'] = array_values($fieldConfig['config']['items']);
+
+                $fieldConfig['config']['treeData'] = $this->renderTree($result, $fieldConfig, $fieldName, $staticItems);
+            }
 
             $result['processedTca']['columns'][$fieldName] = $fieldConfig;
         }
@@ -151,7 +154,6 @@ class TcaSelectTreeItems extends AbstractItemProvider implements FormDataProvide
 
         $treeConfig = [
             'items' => $treeItems,
-            'selectedNodes' => $this->prepareSelectedNodes($fieldConfig['config']['items'], $result['databaseRow'][$fieldName])
         ];
 
         return $treeConfig;
@@ -186,31 +188,6 @@ class TcaSelectTreeItems extends AbstractItemProvider implements FormDataProvide
         return $additionalItems;
     }
 
-    /**
-     * Make sure to only keep the selected nodes that are really available in the database and for the user
-     * (e.g. after permissions etc)
-     *
-     * @param array $itemArray
-     * @param array $databaseValues
-     * @return array
-     * @todo: this is ugly - should be removed with the tree rewrite
-     */
-    protected function prepareSelectedNodes(array $itemArray, array $databaseValues)
-    {
-        $selectedNodes = [];
-        if (!empty($databaseValues)) {
-            foreach ($databaseValues as $selectedNode) {
-                foreach ($itemArray as $possibleSelectBoxItem) {
-                    if ((string)$possibleSelectBoxItem[1] === (string)$selectedNode) {
-                        $selectedNodes[] = $selectedNode;
-                    }
-                }
-            }
-        }
-
-        return $selectedNodes;
-    }
-
     /**
      * Determines whether the current field is a valid target for this DataProvider
      *
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectTreeElement.js b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectTreeElement.js
index a596eae76b56f480f3a4d2e341af3d229a9dad40..c9f5c769b18650dd17f62b7d8c5e4409ba895892 100644
--- a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectTreeElement.js
+++ b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectTreeElement.js
@@ -33,7 +33,9 @@ define(['jquery', 'TYPO3/CMS/Backend/FormEngine/Element/SelectTree'], function (
                 table: treeInput.data('table'),
                 field: treeInput.data('field'),
                 uid: treeInput.data('uid'),
-                flex_form_field_name: treeInput.data('flex-form-field-name'),
+                record_type_value: treeInput.data('recordtypevalue'),
+                flex_form_datastructure_identifier: treeInput.data('flex-form-datastructure-identifier'),
+                flex_form_path: treeInput.data('formengine-input-name'),
                 command: treeInput.data('command')
             };
             var $wrapper = treeInput.parent().siblings('.svg-tree-wrapper');
diff --git a/typo3/sysext/backend/Tests/Unit/Controller/SelectTreeControllerTest.php b/typo3/sysext/backend/Tests/Unit/Controller/SelectTreeControllerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5dddc632b5acb6063df2f061a9188f1729556fa2
--- /dev/null
+++ b/typo3/sysext/backend/Tests/Unit/Controller/SelectTreeControllerTest.php
@@ -0,0 +1,55 @@
+<?php
+namespace TYPO3\CMS\Backend\Tests\Unit\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\Controller\SelectTreeController;
+use TYPO3\CMS\Core\Tests\UnitTestCase;
+
+/**
+ * Test case
+ */
+class SelectTreeControllerTest extends UnitTestCase
+{
+    /**
+     * @test
+     */
+    public function fetchDataActionThrowsExceptionIfTcaOfTableDoesNotExist()
+    {
+        $requestProphecy = $this->prophesize(ServerRequestInterface::class);
+        $responseProphecy = $this->prophesize(ResponseInterface::class);
+        $this->expectException(\RuntimeException::class);
+        $this->expectExceptionCode(1479386729);
+        (new SelectTreeController())->fetchDataAction($requestProphecy->reveal(), $responseProphecy->reveal());
+    }
+
+    /**
+     * @test
+     */
+    public function fetchDataActionThrowsExceptionIfTcaOfTableFieldDoesNotExist()
+    {
+        $responseProphecy = $this->prophesize(ResponseInterface::class);
+        $requestProphecy = $this->prophesize(ServerRequestInterface::class);
+        $requestProphecy->getQueryParams()->shouldBeCalled()->willReturn([
+            'table' => 'aTable',
+            'field' => 'aField',
+        ]);
+        $GLOBALS['TCA']['aTable']['columns'] = [];
+        $this->expectException(\RuntimeException::class);
+        $this->expectExceptionCode(1479386990);
+        (new SelectTreeController())->fetchDataAction($requestProphecy->reveal(), $responseProphecy->reveal());
+    }
+}
diff --git a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/DatabaseRecordTypeValueTest.php b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/DatabaseRecordTypeValueTest.php
index 2193388c8fa38d505decd6e6a3121f229976a7be..89ef3b0889fde2a28d4a146e44cab7210cda3907 100644
--- a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/DatabaseRecordTypeValueTest.php
+++ b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/DatabaseRecordTypeValueTest.php
@@ -58,12 +58,47 @@ class DatabaseRecordTypeValueTest extends UnitTestCase
         $this->subject->addData($input);
     }
 
+    /**
+     * @test
+     */
+    public function addDataKeepsExistingTcaRecordTypeValue()
+    {
+        $input = [
+            'recordTypeValue' => 'egon',
+            'processedTca' => [
+                'types' => [
+                    '1' => 'foo',
+                ],
+            ],
+        ];
+        $expected = $input;
+        $this->assertSame($expected, $this->subject->addData($input));
+    }
+
+    /**
+     * @test
+     */
+    public function addDataKeepsExistingTcaRecordTypeValueWithValueZero()
+    {
+        $input = [
+            'recordTypeValue' => 0,
+            'processedTca' => [
+                'types' => [
+                    '1' => 'foo',
+                ],
+            ],
+        ];
+        $expected = $input;
+        $this->assertSame($expected, $this->subject->addData($input));
+    }
+
     /**
      * @test
      */
     public function addDataSetsRecordTypeValueToHistoricalOneIfTypeZeroIsNotDefined()
     {
         $input = [
+            'recordTypeValue' => '',
             'processedTca' => [
                 'types' => [
                     '1' => 'foo',
@@ -81,6 +116,7 @@ class DatabaseRecordTypeValueTest extends UnitTestCase
     public function addDataSetsRecordTypeValueToZero()
     {
         $input = [
+            'recordTypeValue' => '',
             'processedTca' => [
                 'types' => [
                     '0' => 'foo',
@@ -100,6 +136,7 @@ class DatabaseRecordTypeValueTest extends UnitTestCase
     public function addDataThrowsExceptionIfTypePointsToANotExistingField()
     {
         $input = [
+            'recordTypeValue' => '',
             'processedTca' => [
                 'ctrl' => [
                     'type' => 'notExists',
@@ -125,6 +162,7 @@ class DatabaseRecordTypeValueTest extends UnitTestCase
     public function addDataSetsRecordTypeValueToValueOfDatabaseField()
     {
         $input = [
+            'recordTypeValue' => '',
             'processedTca' => [
                 'ctrl' => [
                     'type' => 'aField',
@@ -150,6 +188,7 @@ class DatabaseRecordTypeValueTest extends UnitTestCase
     public function addDataSetsRecordTypeValueToZeroIfValueOfDatabaseFieldIsNotDefinedInTca()
     {
         $input = [
+            'recordTypeValue' => '',
             'processedTca' => [
                 'ctrl' => [
                     'type' => 'aField',
@@ -175,6 +214,7 @@ class DatabaseRecordTypeValueTest extends UnitTestCase
     public function addDataSetsRecordTypeValueToZeroIfValueOfDatabaseFieldIsEmptyString()
     {
         $input = [
+            'recordTypeValue' => '',
             'processedTca' => [
                 'ctrl' => [
                     'type' => 'aField',
@@ -200,6 +240,7 @@ class DatabaseRecordTypeValueTest extends UnitTestCase
     public function addDataThrowsExceptionIfValueTypesNotExistsAndNoFallbackExists()
     {
         $input = [
+            'recordTypeValue' => '',
             'processedTca' => [
                 'ctrl' => [
                     'type' => 'aField',
@@ -225,6 +266,7 @@ class DatabaseRecordTypeValueTest extends UnitTestCase
     public function addDataSetsRecordTypeValueToValueOfDefaultLanguageRecordIfConfiguredAsExclude()
     {
         $input = [
+            'recordTypeValue' => '',
             'processedTca' => [
                 'ctrl' => [
                     'languageField' => 'sys_language_uid',
@@ -260,6 +302,7 @@ class DatabaseRecordTypeValueTest extends UnitTestCase
     public function addDataSetsRecordTypeValueToValueOfDefaultLanguageRecordIfConfiguredAsMergeIfNotBlank()
     {
         $input = [
+            'recordTypeValue' => '',
             'processedTca' => [
                 'ctrl' => [
                     'languageField' => 'sys_language_uid',
@@ -295,6 +338,7 @@ class DatabaseRecordTypeValueTest extends UnitTestCase
     public function addDataSetsRecordTypeValueToValueOfLocalizedRecordIfConfiguredAsMergeIfNotBlankButNotBlank()
     {
         $input = [
+            'recordTypeValue' => '',
             'processedTca' => [
                 'ctrl' => [
                     'languageField' => 'sys_language_uid',
@@ -330,6 +374,7 @@ class DatabaseRecordTypeValueTest extends UnitTestCase
     public function addDataThrowsExceptionForForeignTypeConfigurationNotAsSelectOrGroup()
     {
         $input = [
+            'recordTypeValue' => '',
             'processedTca' => [
                 'ctrl' => [
                     'type' => 'localField:foreignField',
@@ -359,6 +404,7 @@ class DatabaseRecordTypeValueTest extends UnitTestCase
     public function addDataThrowsExceptionForForeignTypeIfPointerConfigurationHasNoTable()
     {
         $input = [
+            'recordTypeValue' => '',
             'processedTca' => [
                 'ctrl' => [
                     'type' => 'localField:foreignField',
@@ -391,6 +437,7 @@ class DatabaseRecordTypeValueTest extends UnitTestCase
     public function addDataSetsTypeValueFromForeignTableRecord()
     {
         $input = [
+            'recordTypeValue' => '',
             'processedTca' => [
                 'ctrl' => [
                     'type' => 'localField:foreignField',
@@ -434,6 +481,7 @@ class DatabaseRecordTypeValueTest extends UnitTestCase
     public function addDataSetsTypeValueFromNestedTcaGroupField()
     {
         $input = [
+            'recordTypeValue' => '',
             'processedTca' => [
                 'ctrl' => [
                     'type' => 'uid_local:type',
diff --git a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/InitializeProcessedTcaTest.php b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/InitializeProcessedTcaTest.php
index cd8557cc92ba0be8af3ef4f11b00da3b7586cc4b..e904e76d554bad62fa59ba430a4cdcb0b05bb2ef 100644
--- a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/InitializeProcessedTcaTest.php
+++ b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/InitializeProcessedTcaTest.php
@@ -48,6 +48,23 @@ class InitializeProcessedTcaTest extends UnitTestCase
         $this->assertEquals($expected, $result['processedTca']);
     }
 
+    /**
+     * @test
+     */
+    public function addDataKeepsGivenProcessedTca()
+    {
+        $input = [
+            'tableName' => 'aTable',
+            'processedTca' => [
+                'columns' => [
+                    'afield' => [],
+                ],
+            ],
+        ];
+        $expected = $input;
+        $this->assertEquals($expected, $this->subject->addData($input));
+    }
+
     /**
      * @test
      */
diff --git a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaFlexPrepareTest.php b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaFlexPrepareTest.php
index 0f48598c424af6a922f28ff2b44c7bd05341407d..bda0637ad86269369d4d3445d54546e03cc96618 100644
--- a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaFlexPrepareTest.php
+++ b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaFlexPrepareTest.php
@@ -64,6 +64,53 @@ class TcaFlexPrepareTest extends UnitTestCase
         parent::tearDown();
     }
 
+    /**
+     * @test
+     */
+    public function addDataKeepsExistingDataStructure()
+    {
+        $input = [
+            'systemLanguageRows' => [],
+            'tableName' => 'aTableName',
+            'databaseRow' => [
+                'aField' => [
+                    'data' => [],
+                    'meta' => [],
+                ],
+            ],
+            'processedTca' => [
+                'columns' => [
+                    'aField' => [
+                        'config' => [
+                            'type' => 'flex',
+                            'dataStructureIdentifier' => '{"type":"tca","tableName":"aTableName","fieldName":"aField","dataStructureKey":"default"}',
+                            'ds' => [
+                                'sheets' => [
+                                    'sDEF' => [
+                                        'ROOT' => [
+                                            'type' => 'array',
+                                            'el' => [
+                                                'aFlexField' => [
+                                                    'label' => 'aFlexFieldLabel',
+                                                    'config' => [
+                                                        'type' => 'input',
+                                                    ],
+                                                ],
+                                            ],
+                                        ],
+                                    ],
+                                ],
+                                'meta' => [],
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+        ];
+        $expected = $input;
+        $this->assertEquals($expected, $this->subject->addData($input));
+    }
+
     /**
      * @test
      */
diff --git a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaSelectTreeItemsTest.php b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaSelectTreeItemsTest.php
index 35787a8f801b4a2e610cd9c60d6cd4e5d2f4bc96..f3d66dd20a878e288bdb86b30bab3514ad1399dc 100644
--- a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaSelectTreeItemsTest.php
+++ b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaSelectTreeItemsTest.php
@@ -175,13 +175,13 @@ class TcaSelectTreeItemsTest extends UnitTestCase
                     ],
                 ],
             ],
+            'selectTreeCompileItems' => true,
         ];
 
         $expected = $input;
         $expected['databaseRow']['aField'] = ['1'];
         $expected['processedTca']['columns']['aField']['config']['treeData'] = [
             'items' => [['fake', 'tree', 'data']],
-            'selectedNodes' => []
         ];
         $this->assertEquals($expected, $this->subject->addData($input));
     }
@@ -247,6 +247,7 @@ class TcaSelectTreeItemsTest extends UnitTestCase
                     ],
                 ],
             ],
+            'selectTreeCompileItems' => true,
         ];
 
         $this->subject->addData($input);
diff --git a/typo3/sysext/core/Tests/Acceptance/Backend/Page/AddPageInPageModuleCest.php b/typo3/sysext/core/Tests/Acceptance/Backend/Page/AddPageInPageModuleCest.php
index 823d18b1b95e70c0e4b305df8629a3c6160f3f32..d77facf0619f6c079f4cd7d1ad2e1e624b91d366 100644
--- a/typo3/sysext/core/Tests/Acceptance/Backend/Page/AddPageInPageModuleCest.php
+++ b/typo3/sysext/core/Tests/Acceptance/Backend/Page/AddPageInPageModuleCest.php
@@ -65,7 +65,6 @@ class AddPageInPageModuleCest
 
         // Check empty
         $I->amGoingTo('check empty error');
-        $I->click($saveButton);
         $I->wait(2);
         $editControllerDiv = '#EditDocumentController > div';
         $generalTab = $editControllerDiv . ' > div:nth-child(1) > ul > li';