From a7dd022535312710aa050e8b4869ce901a95e002 Mon Sep 17 00:00:00 2001
From: Oliver Bartsch <bo@cedev.de>
Date: Fri, 30 Sep 2022 00:51:37 +0200
Subject: [PATCH] [!!!][FEATURE] Introduce TCA type "file"

In the process of using dedicated TCA types,
the new TCA type "file" is introduced and
replaces TCA type "inline" with "foreign_table"
set to "sys_file_reference".

The new type allows to remove a lot of cross
dependencies and special cases for type "inline",
in case the field is used in FAL context. Also
DataHandler and friends benefit from this change,
since dedicated functionality can be used now.

It therefore effectively allows to improve FAL
independently in the future.

Due to the nature of "inline" a lot of code had
to be copied for the new type, while changing the
internal naming was not always easily possible.
This will be done step by step with further patches.

Besides the new TCA type also three new PSR-14 Events
are introduced:

- CustomFileControlsEvent
- ModifyFileReferenceControlsEvent
- ModifyFileReferenceEnabledControlsEvent

While the ModifyFileReferenceControlsEvent and
ModifyFileReferenceEnabledControlsEvent are equal
to their inline counterparts does the CustomFileControlsEvent
replace the "customControls" hook option, which is
therefore only available for type "inline".

Further notable changed:

- Superfluous field "table_local" is removed from "sys_file_reference"
- ExtensionManagementUtility::getFileFieldTCAConfig() is deprecated
- Placeholders are introduced for common image/media/file types
- File extension filtering is now done automatically in FormEngine
  and DataHandler

Executed commands:

    composer u typo3/cms-styleguide

Resolves: #98479
Releases: main
Change-Id: Ie7a14e8cef444816d3c1844df43e6c0c93706d5d
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/75916
Tested-by: core-ci <typo3@b13.com>
Tested-by: Jochen <rothjochen@gmail.com>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Jochen <rothjochen@gmail.com>
Reviewed-by: Benni Mack <benni@typo3.org>
---
 .../backend/form-engine-validation.ts         |   2 +-
 .../container/files-control-container.ts      | 705 ++++++++++++++++++
 Build/phpstan/phpstan-baseline.neon           |   5 -
 composer.lock                                 |  10 +-
 .../Backend/Avatar/DefaultAvatarProvider.php  |   4 -
 .../Controller/FormFilesAjaxController.php    | 531 +++++++++++++
 .../Controller/FormInlineAjaxController.php   |  21 +-
 .../ElementBrowserInterface.php               |   2 +-
 .../Form/Container/FileReferenceContainer.php | 551 ++++++++++++++
 .../Form/Container/FilesControlContainer.php  | 431 +++++++++++
 .../Form/Container/InlineControlContainer.php | 148 +---
 .../Form/Container/InlineRecordContainer.php  | 160 +---
 .../Form/Event/CustomFileControlsEvent.php    | 109 +++
 .../ModifyFileReferenceControlsEvent.php      | 136 ++++
 ...odifyFileReferenceEnabledControlsEvent.php | 147 ++++
 .../Form/FieldControl/ElementBrowser.php      |  25 +-
 .../DefaultLanguageDifferences.php            |   1 +
 .../Form/FieldWizard/OtherLanguageContent.php |   1 +
 .../FieldWizard/OtherLanguageThumbnails.php   |   2 +-
 .../FormDataProvider/AbstractItemProvider.php |  11 +-
 .../Form/FormDataProvider/TcaFiles.php        | 352 +++++++++
 .../Form/FormDataProvider/TcaFlexPrepare.php  |   5 +
 .../Form/FormDataProvider/TcaFlexProcess.php  |  24 +-
 .../Form/FormDataProvider/TcaInline.php       |   1 -
 .../FormDataProvider/TcaInputPlaceholders.php |   1 +
 .../Form/FormDataProvider/TcaRecordTitle.php  |   1 +
 .../Form/FormDataProvider/TcaSiteLanguage.php |   2 +-
 .../backend/Classes/Form/NodeFactory.php      |   5 +-
 .../Form/Utility/FormEngineUtility.php        |   1 +
 .../RecordList/ElementBrowserRecordList.php   |  12 +
 .../Classes/Utility/BackendUtility.php        |   5 +-
 .../Configuration/Backend/AjaxRoutes.php      |  27 +
 .../backend/Configuration/Services.yaml       |   3 +
 .../Templates/Form/FilesControlContainer.html |  52 ++
 .../JavaScript/form-engine-validation.js      |   2 +-
 .../container/files-control-container.js      |  13 +
 .../Form/FieldControl/ElementBrowserTest.php  |  10 +-
 .../InlineOverrideChildTcaTest.php            |  10 +-
 .../TcaInlineConfigurationTest.php            |   9 +-
 .../Tests/Unit/Utility/BackendUtilityTest.php |   4 +-
 .../Configuration/FlexForm/FlexFormTools.php  |  54 ++
 .../core/Classes/DataHandling/DataHandler.php | 240 ++++--
 .../Localization/DataMapProcessor.php         |  25 +-
 .../Classes/DataHandling/TableColumnType.php  |   1 +
 .../core/Classes/Database/ReferenceIndex.php  |   4 +-
 .../core/Classes/Database/RelationHandler.php |   2 +-
 .../core/Classes/Migrations/TcaMigration.php  | 226 +++++-
 .../Classes/Preparations/TcaPreparation.php   |  72 ++
 .../Resource/Filter/FileExtensionFilter.php   | 122 +--
 .../Processing/FileDeletionAspect.php         |   1 -
 .../Service/UserFileInlineLabelService.php    |  10 +
 .../DatabaseTreeDataProvider.php              |   3 +-
 .../Utility/ExtensionManagementUtility.php    |  57 +-
 .../core/Classes/Utility/RootlineUtility.php  |   2 +-
 .../Configuration/DefaultConfiguration.php    |  15 +
 .../core/Configuration/TCA/be_users.php       |  10 +-
 typo3/sysext/core/Configuration/TCA/pages.php |  56 +-
 .../Configuration/TCA/sys_file_collection.php |   4 +-
 .../Configuration/TCA/sys_file_reference.php  |  15 -
 ...movedFileReferenceRelatedFunctionality.rst |  65 ++
 ...catedFileReferenceRelatedFunctionality.rst |  59 ++
 .../12.0/Feature-98479-NewTCATypeFile.rst     | 200 +++++
 .../Private/Language/locallang_tca.xlf        |   3 -
 .../{InlineFalCest.php => FileCest.php}       |  14 +-
 .../FormEngine/NullPlaceholderCest.php        |   8 +-
 .../FlexformIrre/DataSet/ImportDefault.csv    |   4 +-
 .../FAL/DataSet/ImportDefault.csv             |  10 +-
 .../FAL/DataSet/ImportDefaultWorkspaces.csv   |  10 +-
 .../Modify/DataSet/changeContentSorting.csv   |  10 +-
 .../FAL/Modify/DataSet/copyContent.csv        |  14 +-
 .../Modify/DataSet/copyContentToLanguage.csv  |  14 +-
 .../DataSet/createContentWFileReference.csv   |  12 +-
 ...tentWFileReferenceNDeleteFileReference.csv |  12 +-
 .../FAL/Modify/DataSet/deleteContent.csv      |  10 +-
 .../FAL/Modify/DataSet/localizeContent.csv    |  14 +-
 .../FAL/Modify/DataSet/modifyContent.csv      |  10 +-
 .../modifyContentNAddFileReference.csv        |  12 +-
 .../modifyContentNDeleteAllFileReference.csv  |  10 +-
 .../modifyContentNDeleteFileReference.csv     |  10 +-
 .../DataSet/modifyContentWFileReference.csv   |  10 +-
 .../DataSet/moveContentToDifferentPage.csv    |  10 +-
 ...veContentToDifferentPageNChangeSorting.csv |  10 +-
 .../DataSet/changeContentSorting.csv          |  10 +-
 .../WorkspacesDiscard/DataSet/copyContent.csv |  10 +-
 .../DataSet/createContentWFileReference.csv   |  10 +-
 ...tentWFileReferenceNDeleteFileReference.csv |  10 +-
 .../DataSet/deleteContent.csv                 |  10 +-
 .../DataSet/localizeContent.csv               |  10 +-
 .../DataSet/modifyContent.csv                 |  10 +-
 .../modifyContentNAddFileReference.csv        |  10 +-
 .../modifyContentNDeleteAllFileReference.csv  |  10 +-
 .../modifyContentNDeleteFileReference.csv     |  10 +-
 .../DataSet/modifyContentWFileReference.csv   |  10 +-
 .../DataSet/moveContentToDifferentPage.csv    |  10 +-
 ...veContentToDifferentPageNChangeSorting.csv |  10 +-
 .../DataSet/changeContentSorting.csv          |  14 +-
 .../WorkspacesModify/DataSet/copyContent.csv  |  14 +-
 .../DataSet/createContentWFileReference.csv   |  12 +-
 ...tentWFileReferenceNDeleteFileReference.csv |  10 +-
 .../DataSet/deleteContent.csv                 |  14 +-
 .../DataSet/localizeContent.csv               |  14 +-
 .../DataSet/modifyContent.csv                 |  14 +-
 .../modifyContentNAddFileReference.csv        |  16 +-
 .../modifyContentNDeleteAllFileReference.csv  |  14 +-
 .../modifyContentNDeleteFileReference.csv     |  14 +-
 .../DataSet/modifyContentWFileReference.csv   |  14 +-
 .../DataSet/moveContentToDifferentPage.csv    |  14 +-
 ...veContentToDifferentPageNChangeSorting.csv |  18 +-
 .../DataSet/changeContentSorting.csv          |  10 +-
 .../WorkspacesPublish/DataSet/copyContent.csv |  14 +-
 .../DataSet/createContentWFileReference.csv   |  12 +-
 ...tentWFileReferenceNDeleteFileReference.csv |  10 +-
 .../DataSet/deleteContent.csv                 |  10 +-
 .../DataSet/localizeContent.csv               |  14 +-
 .../DataSet/modifyContent.csv                 |  10 +-
 .../modifyContentNAddFileReference.csv        |  12 +-
 .../modifyContentNDeleteAllFileReference.csv  |  10 +-
 .../modifyContentNDeleteFileReference.csv     |  10 +-
 .../DataSet/modifyContentWFileReference.csv   |  10 +-
 .../DataSet/moveContentToDifferentPage.csv    |  10 +-
 ...veContentToDifferentPageNChangeSorting.csv |  10 +-
 .../DataSet/changeContentSorting.csv          |  10 +-
 .../DataSet/copyContent.csv                   |  14 +-
 .../DataSet/createContentWFileReference.csv   |  12 +-
 ...tentWFileReferenceNDeleteFileReference.csv |  10 +-
 .../DataSet/deleteContent.csv                 |  10 +-
 .../DataSet/localizeContent.csv               |  14 +-
 .../DataSet/modifyContent.csv                 |  10 +-
 .../modifyContentNAddFileReference.csv        |  12 +-
 .../modifyContentNDeleteAllFileReference.csv  |  10 +-
 .../modifyContentNDeleteFileReference.csv     |  10 +-
 .../DataSet/modifyContentWFileReference.csv   |  10 +-
 .../DataSet/moveContentToDifferentPage.csv    |  10 +-
 ...veContentToDifferentPageNChangeSorting.csv |  10 +-
 .../Fixtures/Frontend/JsonRenderer.typoscript |   2 +-
 .../Unit/DataHandling/DataHandlerTest.php     |   4 +-
 .../Unit/Migrations/TcaMigrationTest.php      | 378 ++++++++++
 .../Unit/Preparations/TcaPreparationTest.php  |  26 +
 .../Utility/FileExtensionFilterTest.php       |  25 +-
 .../Utility/FileExtensionFilterTest.php       |  77 ++
 typo3/sysext/core/ext_tables.sql              |   1 -
 .../TCA/tx_blogexample_domain_model_blog.php  |   4 +-
 .../Generic/Mapper/DataMapFactoryTest.php     |   1 +
 .../Link/FileViewHelper/DatabaseImport.csv    |   4 +-
 .../I/Concepts/Finishers/Index.rst            |   4 -
 .../Configuration/TCA/backend_layout.php      |  16 +-
 .../frontend/Configuration/TCA/fe_users.php   |  12 +-
 .../frontend/Configuration/TCA/tt_content.php |  17 +-
 .../ContentObject/DataSet/FileReferences.csv  |   4 +-
 .../DataSet/FilesContentObjectDataSet.csv     |  34 +-
 .../Rendering/DataSet/LiveDefaultElements.csv |  16 +-
 .../PagesAndTtContentWithImagesTest.php       |   1 -
 ...ontentWithDifferentImageToExistingData.csv |   6 +-
 ...elatedTtContentWithImageWithForcedUids.csv |   4 +-
 ...latedTtContentWithImagesButNotIncluded.csv |   4 +-
 ...outStorageOnCaseInsensitiveFilesystems.csv |   4 +-
 ...thoutStorageOnCaseSensitiveFilesystems.csv |   4 +-
 ...WithImagesOnCaseInsensitiveFilesystems.csv |   4 +-
 ...ntWithImagesOnCaseSensitiveFilesystems.csv |   4 +-
 ...tedTtContentWithImagesWithSpacesInPath.csv |   4 +-
 ...edTtContentWithSameImageToExistingData.csv |   6 +-
 ...tContentWithRemappingNewSysFileEntries.csv |   8 +-
 ...elationsBetweenImportedPagesAndRecords.csv |   6 +-
 ...ontentWithDifferentImageToExistingData.csv |   4 +-
 ...ferentImageToExistingDataAndPagesAsNew.csv |   4 +-
 .../DatabaseImports/sys_file_reference.csv    |   4 +-
 ...pages-and-ttcontent-with-corrupt-image.xml |   1 -
 ...-ttcontent-with-image-but-not-included.xml |   1 -
 .../pages-and-ttcontent-with-image.xml        |   1 -
 ...tcontent-with-existing-different-image.xml |   1 -
 ...and-ttcontent-with-existing-same-image.xml |   1 -
 ...-ttcontent-with-image-but-not-included.xml |   1 -
 ...-ttcontent-with-image-with-forced-uids.xml |   1 -
 ...ontent-with-image-with-invalid-storage.xml |   1 -
 ...content-with-image-with-spaces-in-path.xml |   1 -
 ...d-ttcontent-with-image-without-storage.xml |   1 -
 .../pages-and-ttcontent-with-image.xml        |   1 -
 ...pages-and-ttcontent-with-missing-image.xml |   1 -
 .../pages-and-ttcontent-with-two-images.xml   |   3 -
 .../ExtensionScanner/Php/ClassNameMatcher.php |   5 +
 .../Php/MethodCallMatcher.php                 |   8 +-
 .../Php/MethodCallStaticMatcher.php           |   7 +
 .../seo/Configuration/TCA/Overrides/pages.php |  84 +--
 .../Controller/SetupModuleController.php      |   9 -
 typo3/sysext/setup/ext_tables.php             |   2 +-
 .../Controller/Remote/RemoteServer.php        |   6 +-
 .../Dependency/ElementEntityProcessor.php     |   4 +-
 .../Classes/Hook/DataHandlerHook.php          |  53 +-
 188 files changed, 5266 insertions(+), 1206 deletions(-)
 create mode 100644 Build/Sources/TypeScript/backend/form-engine/container/files-control-container.ts
 create mode 100644 typo3/sysext/backend/Classes/Controller/FormFilesAjaxController.php
 create mode 100644 typo3/sysext/backend/Classes/Form/Container/FileReferenceContainer.php
 create mode 100644 typo3/sysext/backend/Classes/Form/Container/FilesControlContainer.php
 create mode 100644 typo3/sysext/backend/Classes/Form/Event/CustomFileControlsEvent.php
 create mode 100644 typo3/sysext/backend/Classes/Form/Event/ModifyFileReferenceControlsEvent.php
 create mode 100644 typo3/sysext/backend/Classes/Form/Event/ModifyFileReferenceEnabledControlsEvent.php
 create mode 100644 typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFiles.php
 create mode 100644 typo3/sysext/backend/Resources/Private/Templates/Form/FilesControlContainer.html
 create mode 100644 typo3/sysext/backend/Resources/Public/JavaScript/form-engine/container/files-control-container.js
 create mode 100644 typo3/sysext/core/Documentation/Changelog/12.0/Breaking-98479-RemovedFileReferenceRelatedFunctionality.rst
 create mode 100644 typo3/sysext/core/Documentation/Changelog/12.0/Deprecation-98479-DeprecatedFileReferenceRelatedFunctionality.rst
 create mode 100644 typo3/sysext/core/Documentation/Changelog/12.0/Feature-98479-NewTCATypeFile.rst
 rename typo3/sysext/core/Tests/Acceptance/Application/FormEngine/{InlineFalCest.php => FileCest.php} (88%)
 create mode 100644 typo3/sysext/core/Tests/UnitDeprecated/Resource/Utility/FileExtensionFilterTest.php

diff --git a/Build/Sources/TypeScript/backend/form-engine-validation.ts b/Build/Sources/TypeScript/backend/form-engine-validation.ts
index 511dcfe338c8..045ca4c02706 100644
--- a/Build/Sources/TypeScript/backend/form-engine-validation.ts
+++ b/Build/Sources/TypeScript/backend/form-engine-validation.ts
@@ -552,7 +552,7 @@ export default (function() {
     $(sectionElement).find(FormEngineValidation.rulesSelector).each((index: number, field: HTMLElement) => {
       const $field = $(field);
 
-      if (!$field.closest('.t3js-flex-section-deleted, .t3js-inline-record-deleted').length) {
+      if (!$field.closest('.t3js-flex-section-deleted, .t3js-inline-record-deleted, .t3js-file-reference-deleted').length) {
         let modified = false;
         const currentValue = $field.val();
         const newValue = FormEngineValidation.validateField($field, currentValue);
diff --git a/Build/Sources/TypeScript/backend/form-engine/container/files-control-container.ts b/Build/Sources/TypeScript/backend/form-engine/container/files-control-container.ts
new file mode 100644
index 000000000000..f3dc1945a14a
--- /dev/null
+++ b/Build/Sources/TypeScript/backend/form-engine/container/files-control-container.ts
@@ -0,0 +1,705 @@
+/*
+ * 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!
+ */
+
+import AjaxRequest from '@typo3/core/ajax/ajax-request';
+import {MessageUtility} from '../../utility/message-utility';
+import {AjaxDispatcher} from './../inline-relation/ajax-dispatcher';
+import {InlineResponseInterface} from './../inline-relation/inline-response-interface';
+import NProgress from 'nprogress';
+import Sortable from 'sortablejs';
+import FormEngine from '@typo3/backend/form-engine';
+import FormEngineValidation from '@typo3/backend/form-engine-validation';
+import Icons from '../../icons';
+import InfoWindow from '../../info-window';
+import Modal, {ModalElement} from '../../modal';
+import RegularEvent from '@typo3/core/event/regular-event';
+import Severity from '../../severity';
+import Utility from '../../utility';
+
+enum Selectors {
+  toggleSelector = '[data-bs-toggle="formengine-file"]',
+  controlSectionSelector = '.t3js-formengine-file-header-control',
+  deleteRecordButtonSelector = '.t3js-editform-delete-file-reference',
+  enableDisableRecordButtonSelector = '.t3js-toggle-visibility-button',
+  infoWindowButton = '[data-action="infowindow"]',
+  synchronizeLocalizeRecordButtonSelector = '.t3js-synchronizelocalize-button',
+  controlContainer = '.t3js-file-controls',
+}
+
+enum States {
+  new = 'isNewFileReference',
+  visible = 'panel-visible',
+  collapsed = 'panel-collapsed',
+  notLoaded = 't3js-not-loaded',
+}
+
+enum Separators {
+  structureSeparator = '-',
+}
+
+enum SortDirections {
+  DOWN = 'down',
+  UP = 'up',
+}
+
+interface RequestQueue {
+  [key: string]: AjaxRequest;
+}
+
+interface ProgressQueue {
+  [key: string]: any;
+}
+
+interface Appearance {
+  expandSingle?: boolean;
+  useSortable?: boolean;
+}
+
+/**
+ * Module: @typo3/backend/form-engine/container/files-control-container
+ *
+ * Functionality for the files control container
+ *
+ * @example
+ * <typo3-formengine-container-files identifier="some-id">
+ *   ...
+ * </typo3-formengine-container-files>
+ *
+ * This is based on W3C custom elements ("web components") specification, see
+ * https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements
+ */
+class FilesControlContainer extends HTMLElement {
+  private container: HTMLElement = null;
+  private ajaxDispatcher: AjaxDispatcher = null;
+  private appearance: Appearance = null;
+  private requestQueue: RequestQueue = {};
+  private progessQueue: ProgressQueue = {};
+  private noTitleString: string = (TYPO3.lang ? TYPO3.lang['FormEngine.noRecordTitle'] : '[No title]');
+
+  private static getFileReferenceContainer(objectId: string): HTMLDivElement {
+    return <HTMLDivElement>document.querySelector('[data-object-id="' + objectId + '"]');
+  }
+
+  private static getCollapseButton(objectId: string): HTMLButtonElement {
+    return <HTMLButtonElement>document.querySelector('[aria-controls="' + objectId + '_fields"]');
+  }
+
+  private static toggleElement(objectId: string): void {
+    const fileReferenceContainer = FilesControlContainer.getFileReferenceContainer(objectId);
+    if (fileReferenceContainer.classList.contains(States.collapsed)) {
+      FilesControlContainer.expandElement(fileReferenceContainer, objectId);
+    } else {
+      FilesControlContainer.collapseElement(fileReferenceContainer, objectId);
+    }
+  }
+
+  private static collapseElement(recordContainer: HTMLDivElement, objectId: string): void {
+    const collapseButton = FilesControlContainer.getCollapseButton(objectId);
+    recordContainer.classList.remove(States.visible);
+    recordContainer.classList.add(States.collapsed);
+    collapseButton.setAttribute('aria-expanded', 'false');
+  }
+
+  private static expandElement(recordContainer: HTMLDivElement, objectId: string): void {
+    const collapseButton = FilesControlContainer.getCollapseButton(objectId);
+    recordContainer.classList.remove(States.collapsed);
+    recordContainer.classList.add(States.visible);
+    collapseButton.setAttribute('aria-expanded', 'true');
+  }
+
+  private static isNewRecord(objectId: string): boolean {
+    const fileReferenceContainer = FilesControlContainer.getFileReferenceContainer(objectId);
+    return fileReferenceContainer.classList.contains(States.new);
+  }
+
+  private static updateExpandedCollapsedStateLocally(objectId: string, value: boolean): void {
+    const fileReferenceContainer = FilesControlContainer.getFileReferenceContainer(objectId);
+
+    const ucFormObj = document.getElementsByName(
+      'uc[inlineView]'
+      + '[' + fileReferenceContainer.dataset.topmostParentTable + ']'
+      + '[' + fileReferenceContainer.dataset.topmostParentUid + ']'
+      + fileReferenceContainer.dataset.fieldName
+    );
+
+    if (ucFormObj.length) {
+      (<HTMLInputElement>ucFormObj[0]).value = value ? '1' : '0';
+    }
+  }
+
+  public connectedCallback(): void {
+    const identifier = this.getAttribute('identifier') || '' as string;
+    this.container = <HTMLElement>this.querySelector('#' + identifier);
+
+    if (this.container !== null) {
+      this.ajaxDispatcher = new AjaxDispatcher(this.container.dataset.objectGroup);
+      this.registerEvents();
+    }
+  }
+
+  private registerEvents(): void {
+    this.registerInfoButton();
+    this.registerSort();
+    this.registerEnableDisableButton();
+    this.registerDeleteButton();
+    this.registerSynchronizeLocalize();
+    this.registerToggle();
+
+    new RegularEvent('message', this.handlePostMessage).bindTo(window);
+
+    if (this.getAppearance().useSortable) {
+      const recordListContainer = <HTMLDivElement>document.getElementById(this.container.getAttribute('id') + '_records');
+      // tslint:disable-next-line:no-unused-expression
+      new Sortable(recordListContainer, {
+        group: recordListContainer.getAttribute('id'),
+        handle: '.sortableHandle',
+        onSort: (): void => {
+          this.updateSorting();
+        },
+      });
+    }
+  }
+
+  private registerToggle(): void {
+    const me = this;
+    new RegularEvent('click', function(this: HTMLElement, e: Event) {
+      e.preventDefault();
+      e.stopImmediatePropagation();
+
+      me.loadRecordDetails(this.closest(Selectors.toggleSelector).parentElement.dataset.objectId);
+    }).delegateTo(this.container, `${Selectors.toggleSelector} .form-irre-header-cell:not(${Selectors.controlSectionSelector}`);
+  }
+
+  private registerSort(): void {
+    const me = this;
+    new RegularEvent('click', function(this: HTMLElement, e: Event) {
+      e.preventDefault();
+      e.stopImmediatePropagation();
+
+      me.changeSortingByButton(
+        (<HTMLDivElement>this.closest('[data-object-id]')).dataset.objectId,
+        <SortDirections>this.dataset.direction,
+      );
+    }).delegateTo(this.container, Selectors.controlSectionSelector + ' [data-action="sort"]');
+  }
+
+  private handlePostMessage = (e: MessageEvent): void => {
+    if (!MessageUtility.verifyOrigin(e.origin)) {
+      throw 'Denied message sent by ' + e.origin;
+    }
+
+    if (e.data.actionName === 'typo3:foreignRelation:insert') {
+      if (typeof e.data.objectGroup === 'undefined') {
+        throw 'No object group defined for message';
+      }
+
+      if (e.data.objectGroup !== this.container.dataset.objectGroup) {
+        // Received message isn't provisioned for current FilesContainer instance
+        return;
+      }
+
+      this.importRecord([e.data.objectGroup, e.data.uid]).then((): void => {
+        if (e.source) {
+          const message = {
+            actionName: 'typo3:foreignRelation:inserted',
+            objectGroup: e.data.objectId,
+            table: e.data.table,
+            uid: e.data.uid,
+          };
+          MessageUtility.send(message, e.source as Window);
+        }
+      });
+    }
+  }
+
+  private createRecord(uid: string, markup: string, afterUid: string = null, selectedValue: string = null): void {
+    let objectId = this.container.dataset.objectGroup;
+    if (afterUid !== null) {
+      objectId += Separators.structureSeparator + afterUid;
+    }
+
+    if (afterUid !== null) {
+      FilesControlContainer.getFileReferenceContainer(objectId).insertAdjacentHTML('afterend', markup);
+      this.memorizeAddRecord(uid, afterUid, selectedValue);
+    } else {
+      document.getElementById(this.container.getAttribute('id') + '_records').insertAdjacentHTML('beforeend', markup);
+      this.memorizeAddRecord(uid, null, selectedValue);
+    }
+  }
+
+  private async importRecord(params: Array<any>, afterUid?: string): Promise<void> {
+    return this.ajaxDispatcher.send(
+      this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint('file_reference_create')),
+      params,
+    ).then(async (response: InlineResponseInterface): Promise<void> => {
+      if (this.isBelowMax()) {
+        this.createRecord(
+          response.compilerInput.uid,
+          response.data,
+          typeof afterUid !== 'undefined' ? afterUid : null,
+          typeof response.compilerInput.childChildUid !== 'undefined' ? response.compilerInput.childChildUid : null,
+        );
+      }
+    });
+  }
+
+  private registerEnableDisableButton(): void {
+    new RegularEvent('click', (e: Event, target: HTMLElement): void => {
+      e.preventDefault();
+      e.stopImmediatePropagation();
+
+      const objectId = (<HTMLDivElement>target.closest('[data-object-id]')).dataset.objectId;
+      const recordContainer = FilesControlContainer.getFileReferenceContainer(objectId);
+      const hiddenFieldName = 'data' + recordContainer.dataset.fieldName + '[' + target.dataset.hiddenField + ']';
+      const hiddenValueCheckBox = <HTMLInputElement>document.querySelector('[data-formengine-input-name="' + hiddenFieldName + '"');
+      const hiddenValueInput = <HTMLInputElement>document.querySelector('[name="' + hiddenFieldName + '"');
+
+      if (hiddenValueCheckBox !== null && hiddenValueInput !== null) {
+        hiddenValueCheckBox.checked = !hiddenValueCheckBox.checked;
+        hiddenValueInput.value = hiddenValueCheckBox.checked ? '1' : '0';
+        FormEngineValidation.markFieldAsChanged(hiddenValueCheckBox);
+      }
+
+      const hiddenClass = 't3-form-field-container-inline-hidden';
+      const isHidden = recordContainer.classList.contains(hiddenClass);
+      let toggleIcon: string;
+
+      if (isHidden) {
+        toggleIcon = 'actions-edit-hide';
+        recordContainer.classList.remove(hiddenClass);
+      } else {
+        toggleIcon = 'actions-edit-unhide';
+        recordContainer.classList.add(hiddenClass);
+      }
+
+      Icons.getIcon(toggleIcon, Icons.sizes.small).then((markup: string): void => {
+        target.replaceChild(document.createRange().createContextualFragment(markup), target.querySelector('.t3js-icon'));
+      });
+    }).delegateTo(this.container, Selectors.enableDisableRecordButtonSelector);
+  }
+
+  private registerInfoButton(): void {
+    new RegularEvent('click', function(this: HTMLElement, e: Event) {
+      e.preventDefault();
+      e.stopImmediatePropagation();
+
+      InfoWindow.showItem(this.dataset.infoTable, this.dataset.infoUid);
+    }).delegateTo(this.container, Selectors.infoWindowButton);
+  }
+
+  private registerDeleteButton(): void {
+    const me = this;
+    new RegularEvent('click', function(this: HTMLElement, e: Event) {
+      e.preventDefault();
+      e.stopImmediatePropagation();
+
+      const title = TYPO3.lang['label.confirm.delete_record.title'] || 'Delete this record?';
+      const content = TYPO3.lang['label.confirm.delete_record.content'] || 'Are you sure you want to delete this record?';
+      Modal.confirm(title, content, Severity.warning, [
+        {
+          text: TYPO3.lang['buttons.confirm.delete_record.no'] || 'Cancel',
+          active: true,
+          btnClass: 'btn-default',
+          name: 'no',
+          trigger: (e: Event, modal: ModalElement) => modal.hideModal(),
+        },
+        {
+          text: TYPO3.lang['buttons.confirm.delete_record.yes'] || 'Yes, delete this record',
+          btnClass: 'btn-warning',
+          name: 'yes',
+          trigger: (e: Event, modal: ModalElement): void => {
+            me.deleteRecord((<HTMLDivElement>this.closest('[data-object-id]')).dataset.objectId);
+            modal.hideModal();
+          }
+        },
+      ]);
+    }).delegateTo(this.container, Selectors.deleteRecordButtonSelector);
+  }
+
+  private registerSynchronizeLocalize(): void {
+    const me = this;
+    new RegularEvent('click', function(this: HTMLElement, e: Event) {
+      e.preventDefault();
+      e.stopImmediatePropagation();
+
+      me.ajaxDispatcher.send(
+        me.ajaxDispatcher.newRequest(me.ajaxDispatcher.getEndpoint('file_reference_synchronizelocalize')),
+        [me.container.dataset.objectGroup, this.dataset.type],
+      ).then(async (response: InlineResponseInterface): Promise<any> => {
+        document.getElementById(me.container.getAttribute('id') + '_records').insertAdjacentHTML('beforeend', response.data);
+
+        const objectIdPrefix = me.container.dataset.objectGroup + Separators.structureSeparator;
+        for (let itemUid of response.compilerInput.delete) {
+          me.deleteRecord(objectIdPrefix + itemUid, true);
+        }
+
+        for (let item of Object.values(response.compilerInput.localize)) {
+          if (typeof item.remove !== 'undefined') {
+            const removableRecordContainer = FilesControlContainer.getFileReferenceContainer(objectIdPrefix + item.remove);
+            removableRecordContainer.parentElement.removeChild(removableRecordContainer);
+          }
+
+          me.memorizeAddRecord(item.uid, null, item.selectedValue);
+        }
+      });
+    }).delegateTo(this.container, Selectors.synchronizeLocalizeRecordButtonSelector);
+  }
+
+  private loadRecordDetails(objectId: string): void {
+    const recordFieldsContainer = document.getElementById(objectId + '_fields');
+    const recordContainer = FilesControlContainer.getFileReferenceContainer(objectId);
+    const isLoading = typeof this.requestQueue[objectId] !== 'undefined';
+    const isLoaded = recordFieldsContainer !== null && !recordContainer.classList.contains(States.notLoaded);
+
+    if (!isLoaded) {
+      const progress = this.getProgress(objectId, recordContainer.dataset.objectIdHash);
+
+      if (!isLoading) {
+        const ajaxRequest = this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint('file_reference_details'));
+        const request = this.ajaxDispatcher.send(ajaxRequest, [objectId]);
+
+        request.then(async (response: InlineResponseInterface): Promise<any> => {
+          delete this.requestQueue[objectId];
+          delete this.progessQueue[objectId];
+
+          recordContainer.classList.remove(States.notLoaded);
+          recordFieldsContainer.innerHTML = response.data;
+          this.collapseExpandRecord(objectId);
+
+          progress.done();
+
+          FormEngine.reinitialize();
+          FormEngineValidation.initializeInputFields();
+          FormEngineValidation.validate(this.container);
+        });
+
+        this.requestQueue[objectId] = ajaxRequest;
+        progress.start();
+      } else {
+        // Abort loading if collapsed again
+        this.requestQueue[objectId].abort();
+        delete this.requestQueue[objectId];
+        delete this.progessQueue[objectId];
+        progress.done();
+      }
+
+      return;
+    }
+
+    this.collapseExpandRecord(objectId);
+  }
+
+  private collapseExpandRecord(objectId: string): void {
+    const recordElement = FilesControlContainer.getFileReferenceContainer(objectId);
+    const expandSingle = this.getAppearance().expandSingle === true;
+    const isCollapsed: boolean = recordElement.classList.contains(States.collapsed);
+    let collapse: Array<string> = [];
+    const expand: Array<string> = [];
+
+    if (expandSingle && isCollapsed) {
+      collapse = this.collapseAllRecords(recordElement.dataset.objectUid);
+    }
+
+    FilesControlContainer.toggleElement(objectId);
+
+    if (FilesControlContainer.isNewRecord(objectId)) {
+      FilesControlContainer.updateExpandedCollapsedStateLocally(objectId, isCollapsed);
+    } else if (isCollapsed) {
+      expand.push(recordElement.dataset.objectUid);
+    } else if (!isCollapsed) {
+      collapse.push(recordElement.dataset.objectUid);
+    }
+
+    this.ajaxDispatcher.send(
+      this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint('file_reference_expandcollapse')),
+      [objectId, expand.join(','), collapse.join(',')]
+    );
+  }
+
+  private memorizeAddRecord(newUid: string, afterUid: string = null, selectedValue: string = null): void {
+    const formField = this.getFormFieldForElements();
+    if (formField === null) {
+      return;
+    }
+
+    let records = Utility.trimExplode(',', (<HTMLInputElement>formField).value);
+    if (afterUid) {
+      const newRecords = [];
+      for (let i = 0; i < records.length; i++) {
+        if (records[i].length) {
+          newRecords.push(records[i]);
+        }
+        if (afterUid === records[i]) {
+          newRecords.push(newUid);
+        }
+      }
+      records = newRecords;
+    } else {
+      records.push(newUid);
+    }
+
+    (<HTMLInputElement>formField).value = records.join(',');
+    (<HTMLInputElement>formField).classList.add('has-change');
+    document.dispatchEvent(new Event('change'));
+
+    this.redrawSortingButtons(this.container.dataset.objectGroup, records);
+
+    if (!this.isBelowMax()) {
+      this.toggleContainerControls(false);
+    }
+
+    FormEngine.reinitialize();
+    FormEngineValidation.initializeInputFields();
+    FormEngineValidation.validate(this.container);
+  }
+
+  private memorizeRemoveRecord(objectUid: string): Array<string> {
+    const formField = this.getFormFieldForElements();
+    if (formField === null) {
+      return [];
+    }
+
+    let records = Utility.trimExplode(',', (<HTMLInputElement>formField).value);
+    const indexOfRemoveUid = records.indexOf(objectUid);
+    if (indexOfRemoveUid > -1) {
+      delete records[indexOfRemoveUid];
+
+      (<HTMLInputElement>formField).value = records.join(',');
+      (<HTMLInputElement>formField).classList.add('has-change');
+      document.dispatchEvent(new Event('change'));
+
+      this.redrawSortingButtons(this.container.dataset.objectGroup, records);
+    }
+
+    return records;
+  }
+
+  private changeSortingByButton(objectId: string, direction: SortDirections): void {
+    const fileReferenceContainer = FilesControlContainer.getFileReferenceContainer(objectId);
+    const objectUid = fileReferenceContainer.dataset.objectUid;
+    const recordListContainer = <HTMLDivElement>document.getElementById(this.container.getAttribute('id') + '_records');
+    const records = Array.from(recordListContainer.children).map((child: HTMLElement) => child.dataset.objectUid);
+    let position = records.indexOf(objectUid);
+    let isChanged = false;
+
+    if (direction === SortDirections.UP && position > 0) {
+      records[position] = records[position - 1];
+      records[position - 1] = objectUid;
+      isChanged = true;
+    } else if (direction === SortDirections.DOWN && position < records.length - 1) {
+      records[position] = records[position + 1];
+      records[position + 1] = objectUid;
+      isChanged = true;
+    }
+
+    if (isChanged) {
+      const objectIdPrefix = this.container.dataset.objectGroup + Separators.structureSeparator;
+      const adjustment = direction === SortDirections.UP ? 1 : 0;
+      fileReferenceContainer.parentElement.insertBefore(
+        FilesControlContainer.getFileReferenceContainer(objectIdPrefix + records[position - adjustment]),
+        FilesControlContainer.getFileReferenceContainer(objectIdPrefix + records[position + 1 - adjustment]),
+      );
+
+      this.updateSorting();
+    }
+  }
+
+  private updateSorting(): void {
+    const formField = this.getFormFieldForElements();
+    if (formField === null) {
+      return;
+    }
+
+    const recordListContainer = <HTMLDivElement>document.getElementById(this.container.getAttribute('id') + '_records');
+    const records = Array.from(recordListContainer.querySelectorAll('[data-object-parent-group="' + this.container.dataset.objectGroup + '"][data-placeholder-record="0"]'))
+      .map((child: HTMLElement) => child.dataset.objectUid);
+
+    (<HTMLInputElement>formField).value = records.join(',');
+    (<HTMLInputElement>formField).classList.add('has-change');
+    document.dispatchEvent(new Event('formengine:files:sorting-changed'));
+    document.dispatchEvent(new Event('change'));
+
+    this.redrawSortingButtons(this.container.dataset.objectGroup, records);
+  }
+
+  private deleteRecord(objectId: string, forceDirectRemoval: boolean = false): void {
+    const recordContainer = FilesControlContainer.getFileReferenceContainer(objectId);
+    const objectUid = recordContainer.dataset.objectUid;
+
+    recordContainer.classList.add('t3js-file-reference-deleted');
+
+    if (!FilesControlContainer.isNewRecord(objectId) && !forceDirectRemoval) {
+      const deleteCommandInput = this.container.querySelector('[name="cmd' + recordContainer.dataset.fieldName + '[delete]"]');
+      deleteCommandInput.removeAttribute('disabled');
+
+      // Move input field to inline container so we can remove the record container
+      recordContainer.parentElement.insertAdjacentElement('afterbegin', deleteCommandInput);
+    }
+
+    new RegularEvent('transitionend', (): void => {
+      recordContainer.parentElement.removeChild(recordContainer);
+      FormEngineValidation.validate(this.container);
+    }).bindTo(recordContainer);
+
+    this.memorizeRemoveRecord(objectUid);
+    recordContainer.classList.add('form-irre-object--deleted');
+
+    if (this.isBelowMax()) {
+      this.toggleContainerControls(true);
+    }
+  }
+
+  private toggleContainerControls(visible: boolean): void {
+    const controlContainer = this.container.querySelector(Selectors.controlContainer);
+    if (controlContainer === null) {
+      return;
+    }
+    const controlContainerButtons = controlContainer.querySelectorAll('button, a');
+    controlContainerButtons.forEach((button: HTMLElement): void => {
+      button.style.display = visible ? null : 'none';
+    });
+  }
+
+  private getProgress(objectId: string, objectIdHash: string): any {
+    const headerIdentifier = '#' + objectIdHash + '_header';
+    let progress: any;
+
+    if (typeof this.progessQueue[objectId] !== 'undefined') {
+      progress = this.progessQueue[objectId];
+    } else {
+      progress = NProgress;
+      progress.configure({parent: headerIdentifier, showSpinner: false});
+      this.progessQueue[objectId] = progress;
+    }
+
+    return progress;
+  }
+
+  private collapseAllRecords(excludeUid: string): Array<string> {
+    const formField = this.getFormFieldForElements();
+    const collapse: Array<string> = [];
+
+    if (formField !== null) {
+      const records = Utility.trimExplode(',', (<HTMLInputElement>formField).value);
+      for (let recordUid of records) {
+        if (recordUid === excludeUid) {
+          continue;
+        }
+
+        const recordObjectId = this.container.dataset.objectGroup + Separators.structureSeparator + recordUid;
+        const recordContainer = FilesControlContainer.getFileReferenceContainer(recordObjectId);
+        if (recordContainer.classList.contains(States.visible)) {
+          FilesControlContainer.collapseElement(recordContainer, recordObjectId);
+
+          if (FilesControlContainer.isNewRecord(recordObjectId)) {
+            FilesControlContainer.updateExpandedCollapsedStateLocally(recordObjectId, false);
+          } else {
+            collapse.push(recordUid);
+          }
+        }
+      }
+    }
+
+    return collapse;
+  }
+
+  private getFormFieldForElements(): HTMLInputElement | null {
+    const formFields = document.getElementsByName(this.container.dataset.formField);
+    if (formFields.length > 0) {
+      return <HTMLInputElement>formFields[0];
+    }
+
+    return null;
+  }
+
+  private redrawSortingButtons(objectId: string, records: Array<string> = []): void {
+    if (records.length === 0) {
+      const formField = this.getFormFieldForElements();
+      if (formField !== null) {
+        records = Utility.trimExplode(',', (<HTMLInputElement>formField).value);
+      }
+    }
+
+    if (records.length === 0) {
+      return;
+    }
+
+    records.forEach((recordUid: string, index: number): void => {
+      const recordContainer = FilesControlContainer.getFileReferenceContainer(objectId + Separators.structureSeparator + recordUid);
+      const headerIdentifier = recordContainer.dataset.objectIdHash + '_header';
+      const headerElement = document.getElementById(headerIdentifier);
+      const sortUp = headerElement.querySelector('[data-action="sort"][data-direction="' + SortDirections.UP + '"]');
+
+      if (sortUp !== null) {
+        let iconIdentifier = 'actions-move-up';
+        if (index === 0) {
+          sortUp.classList.add('disabled');
+          iconIdentifier = 'empty-empty';
+        } else {
+          sortUp.classList.remove('disabled');
+        }
+        Icons.getIcon(iconIdentifier, Icons.sizes.small).then((markup: string): void => {
+          sortUp.replaceChild(document.createRange().createContextualFragment(markup), sortUp.querySelector('.t3js-icon'));
+        });
+      }
+
+      const sortDown = headerElement.querySelector('[data-action="sort"][data-direction="' + SortDirections.DOWN + '"]');
+      if (sortDown !== null) {
+        let iconIdentifier = 'actions-move-down';
+        if (index === records.length - 1) {
+          sortDown.classList.add('disabled');
+          iconIdentifier = 'empty-empty';
+        } else {
+          sortDown.classList.remove('disabled');
+        }
+        Icons.getIcon(iconIdentifier, Icons.sizes.small).then((markup: string): void => {
+          sortDown.replaceChild(document.createRange().createContextualFragment(markup), sortDown.querySelector('.t3js-icon'));
+        });
+      }
+    });
+  }
+
+  private isBelowMax(): boolean {
+    const formField = this.getFormFieldForElements();
+    if (formField === null) {
+      return true;
+    }
+
+    if (typeof TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup] !== 'undefined') {
+      const records = Utility.trimExplode(',', (<HTMLInputElement>formField).value);
+      if (records.length >= TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup].max) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  private getAppearance(): Appearance {
+    if (this.appearance === null) {
+      this.appearance = {};
+
+      if (typeof this.container.dataset.appearance === 'string') {
+        try {
+          this.appearance = JSON.parse(this.container.dataset.appearance);
+        } catch (e) {
+          console.error(e);
+        }
+      }
+    }
+
+    return this.appearance;
+  }
+}
+
+window.customElements.define('typo3-formengine-container-files', FilesControlContainer);
diff --git a/Build/phpstan/phpstan-baseline.neon b/Build/phpstan/phpstan-baseline.neon
index 73b3fff2ab5b..50d91ef3ae54 100644
--- a/Build/phpstan/phpstan-baseline.neon
+++ b/Build/phpstan/phpstan-baseline.neon
@@ -435,11 +435,6 @@ parameters:
 			count: 1
 			path: ../../typo3/sysext/core/Classes/DataHandling/DataHandler.php
 
-		-
-			message: "#^Variable \\$uids in empty\\(\\) always exists and is not falsy\\.$#"
-			count: 1
-			path: ../../typo3/sysext/core/Classes/DataHandling/DataHandler.php
-
 		-
 			message: "#^Method TYPO3\\\\CMS\\\\Core\\\\DataHandling\\\\Localization\\\\DataMapProcessor\\:\\:fetchDependencies\\(\\) should return array\\<array\\<TYPO3\\\\CMS\\\\Core\\\\DataHandling\\\\Localization\\\\DataMapItem\\>\\> but returns array\\<int\\|string, array\\<string, array\\<int, TYPO3\\\\CMS\\\\Core\\\\DataHandling\\\\Localization\\\\DataMapItem\\>\\>\\>\\.$#"
 			count: 1
diff --git a/composer.lock b/composer.lock
index a5b4dda0ec3b..682f8815e640 100644
--- a/composer.lock
+++ b/composer.lock
@@ -8483,12 +8483,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/TYPO3/styleguide.git",
-                "reference": "5759503933c13dd5ea13c535ac0c026b3a2a0281"
+                "reference": "e9076c14eb9fb62582c4c3c5912b21f4c75b2bf7"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/TYPO3/styleguide/zipball/5759503933c13dd5ea13c535ac0c026b3a2a0281",
-                "reference": "5759503933c13dd5ea13c535ac0c026b3a2a0281",
+                "url": "https://api.github.com/repos/TYPO3/styleguide/zipball/e9076c14eb9fb62582c4c3c5912b21f4c75b2bf7",
+                "reference": "e9076c14eb9fb62582c4c3c5912b21f4c75b2bf7",
                 "shasum": ""
             },
             "require-dev": {
@@ -8547,7 +8547,7 @@
                 "issues": "https://github.com/TYPO3/styleguide/issues",
                 "source": "https://github.com/TYPO3/styleguide/tree/main"
             },
-            "time": "2022-09-26T09:45:10+00:00"
+            "time": "2022-10-01T13:43:50+00:00"
         },
         {
             "name": "typo3/testing-framework",
@@ -8650,5 +8650,5 @@
     "platform-overrides": {
         "php": "8.1.1"
     },
-    "plugin-api-version": "2.3.0"
+    "plugin-api-version": "2.2.0"
 }
diff --git a/typo3/sysext/backend/Classes/Backend/Avatar/DefaultAvatarProvider.php b/typo3/sysext/backend/Classes/Backend/Avatar/DefaultAvatarProvider.php
index cdb61eeb5041..1ece7193d9ff 100644
--- a/typo3/sysext/backend/Classes/Backend/Avatar/DefaultAvatarProvider.php
+++ b/typo3/sysext/backend/Classes/Backend/Avatar/DefaultAvatarProvider.php
@@ -84,10 +84,6 @@ class DefaultAvatarProvider implements AvatarProviderInterface
                     'fieldname',
                     $queryBuilder->createNamedParameter('avatar', \PDO::PARAM_STR)
                 ),
-                $queryBuilder->expr()->eq(
-                    'table_local',
-                    $queryBuilder->createNamedParameter('sys_file', \PDO::PARAM_STR)
-                ),
                 $queryBuilder->expr()->eq(
                     'uid_foreign',
                     $queryBuilder->createNamedParameter((int)$backendUserId, \PDO::PARAM_INT)
diff --git a/typo3/sysext/backend/Classes/Controller/FormFilesAjaxController.php b/typo3/sysext/backend/Classes/Controller/FormFilesAjaxController.php
new file mode 100644
index 000000000000..629abcf7e307
--- /dev/null
+++ b/typo3/sysext/backend/Classes/Controller/FormFilesAjaxController.php
@@ -0,0 +1,531 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * 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!
+ */
+
+namespace TYPO3\CMS\Backend\Controller;
+
+use Psr\Http\Message\ResponseFactoryInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Message\StreamFactoryInterface;
+use TYPO3\CMS\Backend\Form\Container\FileReferenceContainer;
+use TYPO3\CMS\Backend\Form\FormDataCompiler;
+use TYPO3\CMS\Backend\Form\FormDataGroup\TcaDatabaseRecord;
+use TYPO3\CMS\Backend\Form\InlineStackProcessor;
+use TYPO3\CMS\Backend\Form\NodeFactory;
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\DataHandling\DataHandler;
+use TYPO3\CMS\Core\Messaging\FlashMessageService;
+use TYPO3\CMS\Core\Page\JavaScriptItems;
+use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\MathUtility;
+
+/**
+ * Handle FormEngine files ajax calls
+ */
+class FormFilesAjaxController extends AbstractFormEngineAjaxController
+{
+    private const FILE_REFERENCE_TABLE = 'sys_file_reference';
+
+    public function __construct(
+        private readonly ResponseFactoryInterface $responseFactory,
+        private readonly StreamFactoryInterface $streamFactory
+    ) {
+    }
+
+    /**
+     * Create a new file reference via AJAX.
+     */
+    public function createAction(ServerRequestInterface $request): ResponseInterface
+    {
+        $arguments = $request->getParsedBody()['ajax'];
+        $parentConfig = $this->extractSignedParentConfigFromRequest((string)($arguments['context'] ?? ''));
+
+        $domObjectId = (string)($arguments[0] ?? '');
+        $inlineFirstPid = $this->getInlineFirstPidFromDomObjectId($domObjectId);
+        if (!MathUtility::canBeInterpretedAsInteger($inlineFirstPid) && !str_starts_with((string)$inlineFirstPid, 'NEW')) {
+            throw new \RuntimeException(
+                'inlineFirstPid should either be an integer or a "NEW..." string',
+                1664440476
+            );
+        }
+        $fileId = null;
+        if (isset($arguments[1]) && MathUtility::canBeInterpretedAsInteger($arguments[1])) {
+            $fileId = (int)$arguments[1];
+        }
+
+        $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
+        $inlineStackProcessor->initializeByParsingDomObjectIdString($domObjectId);
+        $inlineStackProcessor->injectAjaxConfiguration($parentConfig);
+        $inlineTopMostParent = $inlineStackProcessor->getStructureLevel(0);
+
+        $parent = $inlineStackProcessor->getStructureLevel(-1);
+        $fileReference = $inlineStackProcessor->getUnstableStructure();
+
+        if (isset($fileReference['uid']) && MathUtility::canBeInterpretedAsInteger($fileReference['uid'])) {
+            // If uid comes in, it is the id of the record neighbor record "create after"
+            $fileReferenceVanillaUid = -1 * abs((int)$fileReference['uid']);
+        } else {
+            // Else inline first Pid is the storage pid of new inline records
+            $fileReferenceVanillaUid = $inlineFirstPid;
+        }
+
+        $formDataCompilerInput = [
+            'command' => 'new',
+            'tableName' => self::FILE_REFERENCE_TABLE,
+            'vanillaUid' => $fileReferenceVanillaUid,
+            'isInlineChild' => true,
+            'inlineStructure' => $inlineStackProcessor->getStructure(),
+            'inlineFirstPid' => $inlineFirstPid,
+            'inlineParentUid' => $parent['uid'],
+            'inlineParentTableName' => $parent['table'],
+            'inlineParentFieldName' => $parent['field'],
+            'inlineParentConfig' => $parentConfig,
+            'inlineTopMostParentUid' => $inlineTopMostParent['uid'],
+            'inlineTopMostParentTableName' => $inlineTopMostParent['table'],
+            'inlineTopMostParentFieldName' => $inlineTopMostParent['field'],
+        ];
+        if ($fileId) {
+            $formDataCompilerInput['inlineChildChildUid'] = $fileId;
+        }
+
+        $fileReferenceData = GeneralUtility::makeInstance(
+            FormDataCompiler::class,
+            GeneralUtility::makeInstance(TcaDatabaseRecord::class)
+        )->compile($formDataCompilerInput);
+
+        $fileReferenceData['inlineParentUid'] = $parent['uid'];
+        $fileReferenceData['renderType'] = FileReferenceContainer::NODE_TYPE_IDENTIFIER;
+
+        return $this->jsonResponse(
+            $this->mergeFileReferenceResultIntoJsonResult(
+                [
+                    'data' => '',
+                    'stylesheetFiles' => [],
+                    'scriptItems' => GeneralUtility::makeInstance(JavaScriptItems::class),
+                    'scriptCall' => [],
+                    'compilerInput' => [
+                        'uid' => $fileReferenceData['databaseRow']['uid'],
+                        'childChildUid' => $fileId,
+                        'parentConfig' => $parentConfig,
+                    ],
+                ],
+                GeneralUtility::makeInstance(NodeFactory::class)->create($fileReferenceData)->render()
+            )
+        );
+    }
+
+    /**
+     * Show the details of a file reference
+     */
+    public function detailsAction(ServerRequestInterface $request): ResponseInterface
+    {
+        $arguments = $request->getParsedBody()['ajax'] ?? $request->getQueryParams()['ajax'];
+
+        $domObjectId = (string)($arguments[0] ?? '');
+        $inlineFirstPid = $this->getInlineFirstPidFromDomObjectId($domObjectId);
+        $parentConfig = $this->extractSignedParentConfigFromRequest((string)($arguments['context'] ?? ''));
+
+        $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
+        $inlineStackProcessor->initializeByParsingDomObjectIdString($domObjectId);
+        $inlineStackProcessor->injectAjaxConfiguration($parentConfig);
+
+        $parent = $inlineStackProcessor->getStructureLevel(-1);
+        $parentFieldName = $parent['field'];
+
+        // Set flag in config so that only the fields are rendered
+        // @todo: Solve differently / rename / whatever
+        $parentConfig['renderFieldsOnly'] = true;
+
+        $parentData = [
+            'processedTca' => [
+                'columns' => [
+                    $parentFieldName => [
+                        'config' => $parentConfig,
+                    ],
+                ],
+            ],
+            'uid' => $parent['uid'],
+            'tableName' => $parent['table'],
+            'inlineFirstPid' => $inlineFirstPid,
+            'returnUrl' => $parentConfig['originalReturnUrl'],
+        ];
+
+        $fileReference = $inlineStackProcessor->getUnstableStructure();
+        $fileReferenceData = $this->compileFileReference(
+            $parentData,
+            $parentFieldName,
+            (int)$fileReference['uid'],
+            $inlineStackProcessor->getStructure()
+        );
+        $fileReferenceData['inlineParentUid'] = (int)$parent['uid'];
+        $fileReferenceData['renderType'] = FileReferenceContainer::NODE_TYPE_IDENTIFIER;
+
+        return $this->jsonResponse(
+            $this->mergeFileReferenceResultIntoJsonResult(
+                [
+                    'data' => '',
+                    'stylesheetFiles' => [],
+                    'scriptItems' => GeneralUtility::makeInstance(JavaScriptItems::class),
+                    'scriptCall' => [],
+                ],
+                GeneralUtility::makeInstance(NodeFactory::class)->create($fileReferenceData)->render()
+            )
+        );
+    }
+
+    /**
+     * Adds localizations or synchronizes the locations of all file references.
+     */
+    public function synchronizeLocalizeAction(ServerRequestInterface $request): ResponseInterface
+    {
+        $arguments = $request->getParsedBody()['ajax'];
+
+        $domObjectId = (string)($arguments[0] ?? '');
+        $type = $arguments[1] ?? null;
+        $parentConfig = $this->extractSignedParentConfigFromRequest((string)($arguments['context'] ?? ''));
+
+        $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
+        $inlineStackProcessor->initializeByParsingDomObjectIdString($domObjectId);
+        $inlineStackProcessor->injectAjaxConfiguration($parentConfig);
+        $inlineFirstPid = $this->getInlineFirstPidFromDomObjectId($domObjectId);
+
+        $jsonArray = [
+            'data' => '',
+            'stylesheetFiles' => [],
+            'scriptItems' => GeneralUtility::makeInstance(JavaScriptItems::class),
+            'compilerInput' => [
+                'localize' => [],
+            ],
+        ];
+        if ($type === 'localize' || $type === 'synchronize' || MathUtility::canBeInterpretedAsInteger($type)) {
+            // Parent, this table embeds the sys_file_reference table
+            $parent = $inlineStackProcessor->getStructureLevel(-1);
+            $parentFieldName = $parent['field'];
+
+            $processedTca = $GLOBALS['TCA'][$parent['table']];
+            $processedTca['columns'][$parentFieldName]['config'] = $parentConfig;
+
+            $formDataCompilerInputForParent = [
+                'vanillaUid' => (int)$parent['uid'],
+                'command' => 'edit',
+                'tableName' => $parent['table'],
+                'processedTca' => $processedTca,
+                'inlineFirstPid' => $inlineFirstPid,
+                'columnsToProcess' => [
+                    $parentFieldName,
+                ],
+                // @todo: still needed? NO!
+                'inlineStructure' => $inlineStackProcessor->getStructure(),
+                // Do not compile existing file references, we don't need them now
+                'inlineCompileExistingChildren' => false,
+            ];
+            // Full TcaDatabaseRecord is required here to have the list of connected uids $oldItemList
+            $parentData = GeneralUtility::makeInstance(
+                FormDataCompiler::class,
+                GeneralUtility::makeInstance(TcaDatabaseRecord::class)
+            )->compile($formDataCompilerInputForParent);
+            $parentLanguageField = $parentData['processedTca']['ctrl']['languageField'];
+            $parentLanguage = $parentData['databaseRow'][$parentLanguageField];
+            $oldItemList = $parentData['databaseRow'][$parentFieldName];
+
+            // DataHandler cannot handle arrays as field value
+            if (is_array($parentLanguage)) {
+                $parentLanguage = implode(',', $parentLanguage);
+            }
+
+            $cmd = [];
+            // Localize a single file reference from default language of the parent element
+            if (MathUtility::canBeInterpretedAsInteger($type)) {
+                $cmd[$parent['table']][$parent['uid']]['inlineLocalizeSynchronize'] = [
+                    'field' => $parent['field'],
+                    'language' => $parentLanguage,
+                    'ids' => [$type],
+                ];
+            } else {
+                // Either localize or synchronize all file references from default language of the parent element
+                $cmd[$parent['table']][$parent['uid']]['inlineLocalizeSynchronize'] = [
+                    'field' => $parent['field'],
+                    'language' => $parentLanguage,
+                    'action' => $type,
+                ];
+            }
+
+            $tce = GeneralUtility::makeInstance(DataHandler::class);
+            $tce->start([], $cmd);
+            $tce->process_cmdmap();
+
+            $oldItems = $this->getFileReferenceUids((string)$oldItemList);
+
+            $newItemList = (string)($tce->registerDBList[$parent['table']][$parent['uid']][$parentFieldName] ?? '');
+            $newItems = $this->getFileReferenceUids($newItemList);
+
+            // Render error messages from DataHandler
+            $tce->printLogErrorMessages();
+            $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
+            $messages = $flashMessageService->getMessageQueueByIdentifier()->getAllMessagesAndFlush();
+            if (!empty($messages)) {
+                foreach ($messages as $message) {
+                    $jsonArray['messages'][] = [
+                        'title'    => $message->getTitle(),
+                        'message'  => $message->getMessage(),
+                        'severity' => $message->getSeverity(),
+                    ];
+                    if ($message->getSeverity() === ContextualFeedbackSeverity::ERROR) {
+                        $jsonArray['hasErrors'] = true;
+                    }
+                }
+            }
+
+            // Set the items that should be removed in the forms view:
+            $removedItems = array_diff($oldItems, $newItems);
+            $jsonArray['compilerInput']['delete'] = $removedItems;
+
+            $localizedItems = array_diff($newItems, $oldItems);
+            foreach ($localizedItems as $i => $localizedFileReferenceUid) {
+                $fileReferenceData = $this->compileFileReference($parentData, $parentFieldName, (int)$localizedFileReferenceUid, $inlineStackProcessor->getStructure());
+                $fileReferenceData['inlineParentUid'] = (int)$parent['uid'];
+                $fileReferenceData['renderType'] = FileReferenceContainer::NODE_TYPE_IDENTIFIER;
+
+                $jsonArray = $this->mergeFileReferenceResultIntoJsonResult(
+                    $jsonArray,
+                    GeneralUtility::makeInstance(NodeFactory::class)->create($fileReferenceData)->render()
+                );
+
+                // Get the name of the field used as foreign selector (if any):
+                $selectedValue = $fileReferenceData['databaseRow']['uid_local'];
+                if (is_array($selectedValue)) {
+                    $selectedValue = $selectedValue[0];
+                }
+
+                $jsonArray['compilerInput']['localize'][$i] = [
+                    'uid' => $localizedFileReferenceUid,
+                    'selectedValue' => $selectedValue,
+                ];
+
+                // Remove possible virtual records in the form which showed that a file reference could be
+                // localized:
+                $transOrigPointerFieldName = $fileReferenceData['processedTca']['ctrl']['transOrigPointerField'];
+                if (isset($fileReferenceData['databaseRow'][$transOrigPointerFieldName]) && $fileReferenceData['databaseRow'][$transOrigPointerFieldName]) {
+                    $transOrigPointerFieldValue = $fileReferenceData['databaseRow'][$transOrigPointerFieldName];
+                    if (is_array($transOrigPointerFieldValue)) {
+                        $transOrigPointerFieldValue = $transOrigPointerFieldValue[0];
+                        if (is_array($transOrigPointerFieldValue) && ($transOrigPointerFieldValue['uid'] ?? false)) {
+                            $transOrigPointerFieldValue = $transOrigPointerFieldValue['uid'];
+                        }
+                    }
+                    $jsonArray['compilerInput']['localize'][$i]['remove'] = $transOrigPointerFieldValue;
+                }
+            }
+        }
+        return $this->jsonResponse($jsonArray);
+    }
+
+    /**
+     * Store status of file references' expand / collapse state in backend user UC.
+     */
+    public function expandOrCollapseAction(ServerRequestInterface $request): ResponseInterface
+    {
+        [$domObjectId, $expand, $collapse] = $request->getParsedBody()['ajax'];
+
+        $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
+        $inlineStackProcessor->initializeByParsingDomObjectIdString($domObjectId);
+
+        $currentTable = $inlineStackProcessor->getUnstableStructure()['table'];
+        $top = $inlineStackProcessor->getStructureLevel(0);
+        $stateArray = $this->getReferenceExpandCollapseStateArray();
+        // Only do some action if the top record and the current record were saved before
+        if (MathUtility::canBeInterpretedAsInteger($top['uid'])) {
+            // Set records to be expanded
+            foreach (GeneralUtility::trimExplode(',', $expand) as $uid) {
+                $stateArray[$top['table']][$top['uid']][$currentTable][] = $uid;
+            }
+            // Set records to be collapsed
+            foreach (GeneralUtility::trimExplode(',', $collapse) as $uid) {
+                $stateArray[$top['table']][$top['uid']][$currentTable] = $this->removeFromArray(
+                    $uid,
+                    $stateArray[$top['table']][$top['uid']][$currentTable]
+                );
+            }
+            // Save states back to database
+            if (is_array($stateArray[$top['table']][$top['uid']][$currentTable] ?? false)) {
+                $stateArray[$top['table']][$top['uid']][$currentTable] = array_unique($stateArray[$top['table']][$top['uid']][$currentTable]);
+                $backendUser = $this->getBackendUserAuthentication();
+                $backendUser->uc['inlineView'] = json_encode($stateArray);
+                $backendUser->writeUC();
+            }
+        }
+        return $this->jsonResponse();
+    }
+
+    protected function compileFileReference(array $parentData, $parentFieldName, $fileReferenceUid, array $inlineStructure): array
+    {
+        $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
+        $inlineStackProcessor->initializeByGivenStructure($inlineStructure);
+        $inlineTopMostParent = $inlineStackProcessor->getStructureLevel(0);
+
+        return GeneralUtility::makeInstance(
+            FormDataCompiler::class,
+            GeneralUtility::makeInstance(TcaDatabaseRecord::class)
+        )->compile([
+            'command' => 'edit',
+            'tableName' => self::FILE_REFERENCE_TABLE,
+            'vanillaUid' => (int)$fileReferenceUid,
+            'returnUrl' => $parentData['returnUrl'],
+            'isInlineChild' => true,
+            'inlineStructure' => $inlineStructure,
+            'inlineFirstPid' => $parentData['inlineFirstPid'],
+            'inlineParentConfig' => $parentData['processedTca']['columns'][$parentFieldName]['config'],
+            'isInlineAjaxOpeningContext' => true,
+            'inlineParentUid' => $parentData['databaseRow']['uid'] ?? $parentData['uid'],
+            'inlineParentTableName' => $parentData['tableName'],
+            'inlineParentFieldName' => $parentFieldName,
+            'inlineTopMostParentUid' => $inlineTopMostParent['uid'],
+            'inlineTopMostParentTableName' => $inlineTopMostParent['table'],
+            'inlineTopMostParentFieldName' => $inlineTopMostParent['field'],
+        ]);
+    }
+
+    /**
+     * Merge compiled file reference data into the json result array.
+     */
+    protected function mergeFileReferenceResultIntoJsonResult(array $jsonResult, array $fileReferenceData): array
+    {
+        /** @var JavaScriptItems $scriptItems */
+        $scriptItems = $jsonResult['scriptItems'];
+
+        $jsonResult['data'] .= $fileReferenceData['html'];
+        $jsonResult['stylesheetFiles'] = [];
+        foreach ($fileReferenceData['stylesheetFiles'] as $stylesheetFile) {
+            $jsonResult['stylesheetFiles'][] = $this->getRelativePathToStylesheetFile($stylesheetFile);
+        }
+        if (!empty($fileReferenceData['inlineData'])) {
+            $jsonResult['inlineData'] = $fileReferenceData['inlineData'];
+        }
+        // @todo deprecate with TYPO3 v12.0
+        foreach ($fileReferenceData['additionalJavaScriptPost'] as $singleAdditionalJavaScriptPost) {
+            $jsonResult['scriptCall'][] = $singleAdditionalJavaScriptPost;
+        }
+        if (!empty($fileReferenceData['additionalInlineLanguageLabelFiles'])) {
+            $labels = [];
+            foreach ($fileReferenceData['additionalInlineLanguageLabelFiles'] as $additionalInlineLanguageLabelFile) {
+                ArrayUtility::mergeRecursiveWithOverrule(
+                    $labels,
+                    $this->getLabelsFromLocalizationFile($additionalInlineLanguageLabelFile)
+                );
+            }
+            $scriptItems->addGlobalAssignment(['TYPO3' => ['lang' => $labels]]);
+        }
+        $this->addRegisteredRequireJsModulesToJavaScriptItems($fileReferenceData, $scriptItems);
+
+        return $jsonResult;
+    }
+
+    /**
+     * Gets an array with the uids of file references out of a list of items.
+     */
+    protected function getFileReferenceUids(string $itemList): array
+    {
+        $itemArray = GeneralUtility::trimExplode(',', $itemList, true);
+        // Perform modification of the selected items array:
+        foreach ($itemArray as &$value) {
+            $parts = explode('|', $value, 2);
+            $value = $parts[0];
+        }
+        unset($value);
+        return $itemArray;
+    }
+
+    /**
+     * Get expand / collapse state of inline items
+     *
+     * @return array
+     */
+    protected function getReferenceExpandCollapseStateArray(): array
+    {
+        $backendUser = $this->getBackendUserAuthentication();
+        if (empty($backendUser->uc['inlineView'])) {
+            return [];
+        }
+
+        $state = json_decode($backendUser->uc['inlineView'], true);
+        if (!is_array($state)) {
+            $state = [];
+        }
+
+        return $state;
+    }
+
+    /**
+     * Remove an element from an array.
+     */
+    protected function removeFromArray(mixed $needle, array $haystack, bool $strict = false): array
+    {
+        $pos = array_search($needle, $haystack, $strict);
+        if ($pos !== false) {
+            unset($haystack[$pos]);
+        }
+        return $haystack;
+    }
+
+    /**
+     * Get inlineFirstPid from a given objectId string
+     */
+    protected function getInlineFirstPidFromDomObjectId(string $domObjectId): int|string|null
+    {
+        // Substitute FlexForm addition and make parsing a bit easier
+        $domObjectId = str_replace('---', ':', $domObjectId);
+        // The starting pattern of an object identifier (e.g. "data-<firstPidValue>-<anything>)
+        $pattern = '/^data-(.+?)-(.+)$/';
+        if (preg_match($pattern, $domObjectId, $match)) {
+            return $match[1];
+        }
+        return null;
+    }
+
+    /**
+     * Validates the config that is transferred over the wire to provide the
+     * correct TCA config for the parent table
+     */
+    protected function extractSignedParentConfigFromRequest(string $contextString): array
+    {
+        if ($contextString === '') {
+            throw new \RuntimeException('Empty context string given', 1664486783);
+        }
+        $context = json_decode($contextString, true);
+        if (empty($context['config'])) {
+            throw new \RuntimeException('Empty context config section given', 1664486790);
+        }
+        if (!hash_equals(GeneralUtility::hmac((string)$context['config'], 'FilesContext'), (string)$context['hmac'])) {
+            throw new \RuntimeException('Hash does not validate', 1664486791);
+        }
+        return json_decode($context['config'], true);
+    }
+
+    protected function jsonResponse(array $json = []): ResponseInterface
+    {
+        return $this->responseFactory->createResponse()
+            ->withHeader('Content-Type', 'application/json; charset=utf-8')
+            ->withBody($this->streamFactory->createStream((string)json_encode($json)));
+    }
+
+    protected function getBackendUserAuthentication(): BackendUserAuthentication
+    {
+        return $GLOBALS['BE_USER'];
+    }
+}
diff --git a/typo3/sysext/backend/Classes/Controller/FormInlineAjaxController.php b/typo3/sysext/backend/Classes/Controller/FormInlineAjaxController.php
index 8775767befe0..53cb7beb695c 100644
--- a/typo3/sysext/backend/Classes/Controller/FormInlineAjaxController.php
+++ b/typo3/sysext/backend/Classes/Controller/FormInlineAjaxController.php
@@ -365,7 +365,7 @@ class FormInlineAjaxController extends AbstractFormEngineAjaxController
                         $transOrigPointerFieldValue = $transOrigPointerFieldValue[0];
                         if (is_array($transOrigPointerFieldValue) && ($transOrigPointerFieldValue['uid'] ?? false)) {
                             // With nested inline containers (eg. fal sys_file_reference), row[l10n_parent][0] is sometimes
-                            // a table / row combination again. See tx_styleguide_inline_fal inline_5. If this happens we
+                            // a table / row combination again. See tx_styleguide_file file_5. If this happens we
                             // pick the uid field from the array ... Basically, we need the uid of the 'default language' record,
                             // since this is used in JS to locate and remove the 'shadowed' container.
                             // @todo: Find out if this is really necessary that sometimes ['databaseRow']['l10n_parent'][0]
@@ -579,25 +579,6 @@ class FormInlineAjaxController extends AbstractFormEngineAjaxController
         return $itemArray;
     }
 
-    /**
-     * Return expand / collapse state array for a given table / uid combination
-     *
-     * @param string $table Handled table
-     * @param int $uid Handled uid
-     * @return array
-     */
-    protected function getInlineExpandCollapseStateArrayForTableUid($table, $uid)
-    {
-        $inlineView = $this->getInlineExpandCollapseStateArray();
-        $result = [];
-        if (MathUtility::canBeInterpretedAsInteger($uid)) {
-            if (!empty($inlineView[$table][$uid])) {
-                $result = $inlineView[$table][$uid];
-            }
-        }
-        return $result;
-    }
-
     /**
      * Get expand / collapse state of inline items
      *
diff --git a/typo3/sysext/backend/Classes/ElementBrowser/ElementBrowserInterface.php b/typo3/sysext/backend/Classes/ElementBrowser/ElementBrowserInterface.php
index 88bcc7ab5635..b0035be35377 100644
--- a/typo3/sysext/backend/Classes/ElementBrowser/ElementBrowserInterface.php
+++ b/typo3/sysext/backend/Classes/ElementBrowser/ElementBrowserInterface.php
@@ -20,7 +20,7 @@ namespace TYPO3\CMS\Backend\ElementBrowser;
 /**
  * Element browsers are modals rendered when records are attached to FormEngine elements.
  * Core usages:
- * * Managing TCA inline FAL file relations of some record
+ * * Managing TCA type=file relations
  * * Managing FAL folder relations a TCA type=folder
  * * Managing various target relations of a TCA type=group
  */
diff --git a/typo3/sysext/backend/Classes/Form/Container/FileReferenceContainer.php b/typo3/sysext/backend/Classes/Form/Container/FileReferenceContainer.php
new file mode 100644
index 000000000000..a66448108283
--- /dev/null
+++ b/typo3/sysext/backend/Classes/Form/Container/FileReferenceContainer.php
@@ -0,0 +1,551 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * 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!
+ */
+
+namespace TYPO3\CMS\Backend\Form\Container;
+
+use Psr\EventDispatcher\EventDispatcherInterface;
+use TYPO3\CMS\Backend\Form\Event\ModifyFileReferenceControlsEvent;
+use TYPO3\CMS\Backend\Form\Event\ModifyFileReferenceEnabledControlsEvent;
+use TYPO3\CMS\Backend\Form\InlineStackProcessor;
+use TYPO3\CMS\Backend\Form\NodeFactory;
+use TYPO3\CMS\Backend\Routing\UriBuilder;
+use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Imaging\Icon;
+use TYPO3\CMS\Core\Imaging\IconFactory;
+use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection;
+use TYPO3\CMS\Core\Localization\LanguageService;
+use TYPO3\CMS\Core\Resource\Exception\InvalidUidException;
+use TYPO3\CMS\Core\Resource\Index\MetaDataRepository;
+use TYPO3\CMS\Core\Resource\ProcessedFile;
+use TYPO3\CMS\Core\Resource\ResourceFactory;
+use TYPO3\CMS\Core\Type\Bitmask\Permission;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\MathUtility;
+
+/**
+ * Render a single file reference.
+ *
+ * This container is called by FilesControlContainer to render a single file (reference). The container is also
+ * called by FormEngine for an incoming ajax request to expand an existing file (reference) or to create a new one.
+ *
+ * This container creates the outer HTML of single file (references) - e.g. drag and drop and delete buttons.
+ * For rendering of the record itself processing is handed over to FullRecordContainer.
+ */
+class FileReferenceContainer extends AbstractContainer
+{
+    public const NODE_TYPE_IDENTIFIER = 'fileReferenceContainer';
+
+    private const FILE_REFERENCE_TABLE = 'sys_file_reference';
+    private const FOREIGN_SELECTOR = 'uid_local';
+
+    private const SYS_FILE_LABEL_FIELDS = [
+        'title',
+        'name',
+    ];
+
+    /**
+     * File reference data used for JSON output
+     */
+    protected array $fileReferenceData = [];
+
+    protected InlineStackProcessor $inlineStackProcessor;
+    protected IconFactory $iconFactory;
+    protected EventDispatcherInterface $eventDispatcher;
+
+    public function __construct(NodeFactory $nodeFactory, array $data)
+    {
+        parent::__construct($nodeFactory, $data);
+        $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
+        $this->inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
+        $this->eventDispatcher = GeneralUtility::makeInstance(EventDispatcherInterface::class);
+    }
+
+    public function render(): array
+    {
+        $inlineStackProcessor = $this->inlineStackProcessor;
+        $inlineStackProcessor->initializeByGivenStructure($this->data['inlineStructure']);
+
+        // Send a mapping information to the browser via JSON:
+        // e.g. data[<curTable>][<curId>][<curField>] => data-<pid>-<parentTable>-<parentId>-<parentField>-<curTable>-<curId>-<curField>
+        $formPrefix = $inlineStackProcessor->getCurrentStructureFormPrefix();
+        $domObjectId = $inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']);
+
+        $this->fileReferenceData = $this->data['inlineData'];
+        $this->fileReferenceData['map'][$formPrefix] = $domObjectId;
+
+        $resultArray = $this->initializeResultArray();
+        $resultArray['inlineData'] = $this->fileReferenceData;
+
+        $html = '';
+        $classes = [];
+        $combinationHtml = '';
+        $record = $this->data['databaseRow'];
+        $uid = $record['uid'] ?? 0;
+        $appendFormFieldNames = '[' . self::FILE_REFERENCE_TABLE . '][' . $uid . ']';
+        $objectId = $domObjectId . '-' . self::FILE_REFERENCE_TABLE . '-' . $uid;
+        $isNewRecord = $this->data['command'] === 'new';
+        $hiddenFieldName = (string)($this->data['processedTca']['ctrl']['enablecolumns']['disabled'] ?? '');
+        if (!$this->data['isInlineDefaultLanguageRecordInLocalizedParentContext']) {
+            if ($isNewRecord || $this->data['isInlineChildExpanded']) {
+                $fileReferenceData = $this->renderFileReference($this->data);
+                $html = $fileReferenceData['html'];
+                $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fileReferenceData, false);
+            } else {
+                // This class is the marker for the JS-function to check if the full content has already been loaded
+                $classes[] = 't3js-not-loaded';
+            }
+            if ($isNewRecord) {
+                // Add pid of file reference as hidden field
+                $html .= '<input type="hidden" name="data' . htmlspecialchars($appendFormFieldNames)
+                    . '[pid]" value="' . (int)$record['pid'] . '"/>';
+                // Tell DataHandler this file reference is expanded
+                $ucFieldName = 'uc[inlineView]'
+                    . '[' . $this->data['inlineTopMostParentTableName'] . ']'
+                    . '[' . $this->data['inlineTopMostParentUid'] . ']'
+                    . htmlspecialchars($appendFormFieldNames);
+                $html .= '<input type="hidden" name="' . htmlspecialchars($ucFieldName)
+                    . '" value="' . (int)$this->data['isInlineChildExpanded'] . '" />';
+            } else {
+                // Set additional field for processing for saving
+                $html .= '<input type="hidden" name="cmd' . htmlspecialchars($appendFormFieldNames)
+                    . '[delete]" value="1" disabled="disabled" />';
+                if ($hiddenFieldName !== ''
+                    && (!$this->data['isInlineChildExpanded']
+                        || !in_array($hiddenFieldName, $this->data['columnsToProcess'], true))
+                ) {
+                    $isHidden = (bool)($record[$hiddenFieldName] ?? false);
+                    $html .= '<input type="checkbox" class="d-none" data-formengine-input-name="data'
+                        . htmlspecialchars($appendFormFieldNames)
+                        . '[' . htmlspecialchars($hiddenFieldName) . ']" value="1"'
+                        . ($isHidden ? ' checked="checked"' : '') . ' />';
+                    $html .= '<input type="input" class="d-none" name="data' . htmlspecialchars($appendFormFieldNames)
+                        . '[' . htmlspecialchars($hiddenFieldName) . ']" value="' . (int)$isHidden . '" />';
+                }
+            }
+            // If this file reference should be shown collapsed
+            $classes[] = $this->data['isInlineChildExpanded'] ? 'panel-visible' : 'panel-collapsed';
+        }
+        $hiddenFieldHtml = implode("\n", $resultArray['additionalHiddenFields'] ?? []);
+
+        if ($this->data['inlineParentConfig']['renderFieldsOnly'] ?? false) {
+            // Render "body" part only
+            $resultArray['html'] = $html . $hiddenFieldHtml . $combinationHtml;
+            return $resultArray;
+        }
+
+        // Render header row and content (if expanded)
+        if ($this->data['isInlineDefaultLanguageRecordInLocalizedParentContext']) {
+            $classes[] = 't3-form-field-container-inline-placeHolder';
+        }
+        if ($record[$hiddenFieldName] ?? false) {
+            $classes[] = 't3-form-field-container-inline-hidden';
+        }
+        if ($isNewRecord) {
+            $classes[] = 'isNewFileReference';
+        }
+
+        // The hashed object id needs a non-numeric prefix, the value is used as ID selector in JavaScript
+        $hashedObjectId = 'hash-' . md5($objectId);
+        $containerAttributes = [
+            'id' => $objectId . '_div',
+            'class' => 'form-irre-object panel panel-default panel-condensed ' . trim(implode(' ', $classes)),
+            'data-object-uid' => $record['uid'] ?? 0,
+            'data-object-id' => $objectId,
+            'data-object-id-hash' => $hashedObjectId,
+            'data-object-parent-group' => $domObjectId . '-' . self::FILE_REFERENCE_TABLE,
+            'data-field-name' => $appendFormFieldNames,
+            'data-topmost-parent-table' => $this->data['inlineTopMostParentTableName'],
+            'data-topmost-parent-uid' => $this->data['inlineTopMostParentUid'],
+            'data-placeholder-record' => $this->data['isInlineDefaultLanguageRecordInLocalizedParentContext'] ? '1' : '0',
+        ];
+
+        $ariaControls = htmlspecialchars($objectId . '_fields', ENT_QUOTES | ENT_HTML5);
+        $resultArray['html'] = '
+            <div ' . GeneralUtility::implodeAttributes($containerAttributes, true) . '>
+                <div class="panel-heading" data-bs-toggle="formengine-file" id="' . htmlspecialchars($hashedObjectId, ENT_QUOTES | ENT_HTML5) . '_header" data-expandSingle="' . (($this->data['inlineParentConfig']['appearance']['expandSingle'] ?? false) ? 1 : 0) . '">
+                    <div class="form-irre-header">
+                        <div class="form-irre-header-cell form-irre-header-icon">
+                            <span class="caret"></span>
+                        </div>
+                        ' . $this->renderFileHeader('aria-expanded="' . (($this->data['isInlineChildExpanded'] ?? false) ? 'true' : 'false') . '" aria-controls="' . $ariaControls . '"') . '
+                    </div>
+                </div>
+                <div class="panel-collapse" id="' . $ariaControls . '">' . $html . $hiddenFieldHtml . $combinationHtml . '</div>
+            </div>';
+
+        return $resultArray;
+    }
+
+    protected function renderFileReference(array $data): array
+    {
+        $data['tabAndInlineStack'][] = [
+            'inline',
+            $this->inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($data['inlineFirstPid'])
+            . '-'
+            . $data['tableName']
+            . '-'
+            . $data['databaseRow']['uid'],
+        ];
+
+        return $this->nodeFactory->create(array_replace_recursive($data, [
+            'inlineData' => $this->fileReferenceData,
+            'renderType' => 'fullRecordContainer',
+        ]))->render();
+    }
+
+    /**
+     * Renders the HTML header for the file, such as the title, toggle-function, drag'n'drop, etc.
+     * Later on the command-icons are inserted here, too.
+     */
+    protected function renderFileHeader(string $ariaAttributesString): string
+    {
+        $languageService = $this->getLanguageService();
+
+        $databaseRow = $this->data['databaseRow'];
+        $recordTitle = $this->getRecordTitle();
+
+        if (empty($recordTitle)) {
+            $recordTitle = '<em>[' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.no_title')) . ']</em>';
+        }
+
+        $objectId = $this->inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid'])
+            . '-' . self::FILE_REFERENCE_TABLE
+            . '-' . ($databaseRow['uid'] ?? 0);
+
+        $altText = BackendUtility::getRecordIconAltText($databaseRow, self::FILE_REFERENCE_TABLE);
+
+        // Renders a thumbnail for the header
+        $thumbnail = '';
+        if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['thumbnails'] ?? false) {
+            $fileUid = $databaseRow[self::FOREIGN_SELECTOR][0]['uid'] ?? null;
+            if (!empty($fileUid)) {
+                try {
+                    $fileObject = GeneralUtility::makeInstance(ResourceFactory::class)->getFileObject($fileUid);
+                    if ($fileObject->isMissing()) {
+                        $thumbnail = '
+                            <span class="badge badge-danger">'
+                                . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:warning.file_missing')) . '
+                            </span>&nbsp;
+                            ' . htmlspecialchars($fileObject->getName()) . '
+                            <br />';
+                    } elseif ($fileObject->isImage()) {
+                        $imageSetup = $this->data['inlineParentConfig']['appearance']['headerThumbnail'] ?? [];
+                        $cropVariantCollection = CropVariantCollection::create($databaseRow['crop'] ?? '');
+                        if (!$cropVariantCollection->getCropArea()->isEmpty()) {
+                            $imageSetup['crop'] = $cropVariantCollection->getCropArea()->makeAbsoluteBasedOnFile($fileObject);
+                        }
+                        $processedImage = $fileObject->process(
+                            ProcessedFile::CONTEXT_IMAGECROPSCALEMASK,
+                            array_merge(['maxWidth' => '145', 'maxHeight' => '45'], $imageSetup)
+                        );
+                        // Only use a thumbnail if the processing process was successful by checking if image width is set
+                        if ($processedImage->getProperty('width')) {
+                            $imageUrl = $processedImage->getPublicUrl() ?? '';
+                            $thumbnail = '<img src="' . htmlspecialchars($imageUrl) . '" ' .
+                                'width="' . $processedImage->getProperty('width') . '" ' .
+                                'height="' . $processedImage->getProperty('height') . '" ' .
+                                'alt="' . $altText . '" ' .
+                                'title="' . $altText . '">';
+                        }
+                    }
+                } catch (\InvalidArgumentException $e) {
+                    $fileObject = null;
+                }
+            }
+        }
+
+        if ($thumbnail !== '') {
+            $headerImage = '
+                <div class="form-irre-header-thumbnail" id="' . $objectId . '_thumbnailcontainer">
+                    ' . $thumbnail . '
+                </div>';
+        } else {
+            $headerImage = '
+                <div class="form-irre-header-icon" id="' . $objectId . '_iconcontainer">
+                    <span title="' . $altText . '" id="' . htmlspecialchars($objectId) . '_icon">
+                        ' . $this->iconFactory->getIconForRecord(self::FILE_REFERENCE_TABLE, $databaseRow, Icon::SIZE_SMALL)->render() . '
+                    </span>
+                </div>';
+        }
+
+        // @todo check classes and change to dedicated file related ones if possible
+        return '
+            <button class="form-irre-header-cell form-irre-header-button" ' . $ariaAttributesString . '>
+                ' . $headerImage . '
+                <div class="form-irre-header-body">
+                    <span id="' . $objectId . '_label">' . $recordTitle . '</span>
+                </div>
+            </button>
+            <div class="form-irre-header-cell form-irre-header-control t3js-formengine-file-header-control">
+                ' . $this->renderFileReferenceHeaderControl() . '
+            </div>';
+    }
+
+    /**
+     * Render the control-icons for a file reference (e.g. create new, sorting, delete, disable/enable).
+     */
+    protected function renderFileReferenceHeaderControl(): string
+    {
+        $controls = [];
+        $databaseRow = $this->data['databaseRow'];
+        $databaseRow += [
+            'uid' => 0,
+        ];
+        $parentConfig = $this->data['inlineParentConfig'];
+        $languageService = $this->getLanguageService();
+        $backendUser = $this->getBackendUserAuthentication();
+        $isNewItem = str_starts_with((string)$databaseRow['uid'], 'NEW');
+        $fileReferenceTableTca = $GLOBALS['TCA'][self::FILE_REFERENCE_TABLE];
+        $calcPerms = new Permission(
+            $backendUser->calcPerms(BackendUtility::readPageAccess(
+                (int)($this->data['parentPageRow']['uid'] ?? 0),
+                $backendUser->getPagePermsClause(Permission::PAGE_SHOW)
+            ))
+        );
+        $event = $this->eventDispatcher->dispatch(
+            new ModifyFileReferenceEnabledControlsEvent($this->data, $databaseRow)
+        );
+        if ($this->data['isInlineDefaultLanguageRecordInLocalizedParentContext']) {
+            $controls['localize'] = '
+                <span title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:localize.isLocalizable')) . '">
+                    ' . $this->iconFactory->getIcon('actions-edit-localize-status-low', Icon::SIZE_SMALL)->render() . '
+                </span>';
+        }
+        if ($event->isControlEnabled('info')) {
+            if ($isNewItem) {
+                $controls['info'] = '
+                    <span class="btn btn-default disabled">
+                        ' . $this->iconFactory->getIcon('empty-empty', Icon::SIZE_SMALL)->render() . '
+                    </span>';
+            } else {
+                $controls['info'] = '
+                    <button type="button" class="btn btn-default" data-action="infowindow" data-info-table="' . htmlspecialchars('_FILE') . '" data-info-uid="' . (int)$databaseRow['uid_local'][0]['uid'] . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:showInfo')) . '">
+                        ' . $this->iconFactory->getIcon('actions-document-info', Icon::SIZE_SMALL)->render() . '
+                    </button>';
+            }
+        }
+        // If the table is NOT a read-only table, then show these links:
+        if (!($parentConfig['readOnly'] ?? false)
+            && !($fileReferenceTableTca['ctrl']['readOnly'] ?? false)
+            && !($this->data['isInlineDefaultLanguageRecordInLocalizedParentContext'] ?? false)
+        ) {
+            if ($event->isControlEnabled('sort')) {
+                $icon = 'actions-move-up';
+                $class = '';
+                if ((int)$parentConfig['inline']['first'] === (int)$databaseRow['uid']) {
+                    $class = ' disabled';
+                    $icon = 'empty-empty';
+                }
+                $controls['sort.up'] = '
+                    <button type="button" class="btn btn-default' . $class . '" data-action="sort" data-direction="up" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:moveUp')) . '">
+                        ' . $this->iconFactory->getIcon($icon, Icon::SIZE_SMALL)->render() . '
+                    </button>';
+
+                $icon = 'actions-move-down';
+                $class = '';
+                if ((int)$parentConfig['inline']['last'] === (int)$databaseRow['uid']) {
+                    $class = ' disabled';
+                    $icon = 'empty-empty';
+                }
+                $controls['sort.down'] = '
+                    <button type="button" class="btn btn-default' . $class . '" data-action="sort" data-direction="down" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:moveDown')) . '">
+                        ' . $this->iconFactory->getIcon($icon, Icon::SIZE_SMALL)->render() . '
+                    </button>';
+            }
+            if (!$isNewItem
+                && ($languageField = ($GLOBALS['TCA']['sys_file_metadata']['ctrl']['languageField'] ?? false))
+                && $backendUser->check('tables_modify', 'sys_file_metadata')
+                && $event->isControlEnabled('edit')
+            ) {
+                $languageId = (int)(is_array($databaseRow[$languageField] ?? null)
+                    ? ($databaseRow[$languageField][0] ?? 0)
+                    : ($databaseRow[$languageField] ?? 0));
+                $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
+                    ->getQueryBuilderForTable('sys_file_metadata');
+                $metadataRecord = $queryBuilder
+                    ->select('uid')
+                    ->from('sys_file_metadata')
+                    ->where(
+                        $queryBuilder->expr()->eq(
+                            'file',
+                            $queryBuilder->createNamedParameter((int)$databaseRow['uid_local'][0]['uid'], \PDO::PARAM_INT)
+                        ),
+                        $queryBuilder->expr()->eq(
+                            $languageField,
+                            $queryBuilder->createNamedParameter($languageId, \PDO::PARAM_INT)
+                        )
+                    )
+                    ->setMaxResults(1)
+                    ->executeQuery()
+                    ->fetchAssociative();
+                if (!empty($metadataRecord)) {
+                    $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
+                    $url = (string)$uriBuilder->buildUriFromRoute('record_edit', [
+                        'edit[sys_file_metadata][' . (int)$metadataRecord['uid'] . ']' => 'edit',
+                        'returnUrl' => $this->data['returnUrl'],
+                    ]);
+                    $controls['edit'] = '
+                        <a class="btn btn-default" href="' . htmlspecialchars($url) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.editMetadata')) . '">
+                            ' . $this->iconFactory->getIcon('actions-open', Icon::SIZE_SMALL)->render() . '
+                        </a>';
+                }
+            }
+            if ($event->isControlEnabled('delete') && $calcPerms->editPagePermissionIsGranted()) {
+                $recordInfo = $this->data['databaseRow']['uid_local'][0]['title'] ?? $this->data['recordTitle'] ?? '';
+                if ($this->getBackendUserAuthentication()->shallDisplayDebugInformation()) {
+                    $recordInfo .= ' [' . $this->data['tableName'] . ':' . $this->data['vanillaUid'] . ']';
+                }
+                $controls['delete'] = '
+                    <button type="button" class="btn btn-default t3js-editform-delete-file-reference" data-record-info="' . htmlspecialchars(trim($recordInfo)) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:delete')) . '">
+                        ' . $this->iconFactory->getIcon('actions-edit-delete', Icon::SIZE_SMALL)->render() . '
+                    </button>';
+            }
+            if (($hiddenField = (string)($fileReferenceTableTca['ctrl']['enablecolumns']['disabled'] ?? '')) !== ''
+                && ($fileReferenceTableTca['columns'][$hiddenField] ?? false)
+                && $event->isControlEnabled('hide')
+                && (
+                    !($fileReferenceTableTca['columns'][$hiddenField]['exclude'] ?? false)
+                    || $backendUser->check('non_exclude_fields', self::FILE_REFERENCE_TABLE . ':' . $hiddenField)
+                )
+            ) {
+                if ($databaseRow[$hiddenField] ?? false) {
+                    $controls['hide'] = '
+                        <button type="button" class="btn btn-default t3js-toggle-visibility-button" data-hidden-field="' . htmlspecialchars($hiddenField) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:unHide')) . '">
+                            ' . $this->iconFactory->getIcon('actions-edit-unhide', Icon::SIZE_SMALL)->render() . '
+                        </button>';
+                } else {
+                    $controls['hide'] = '
+                        <button type="button" class="btn btn-default t3js-toggle-visibility-button" data-hidden-field="' . htmlspecialchars($hiddenField) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:hide')) . '">
+                            ' . $this->iconFactory->getIcon('actions-edit-hide', Icon::SIZE_SMALL)->render() . '
+                        </button>';
+                }
+            }
+            if (($parentConfig['appearance']['useSortable'] ?? false) && $event->isControlEnabled('dragdrop')) {
+                $controls['dragdrop'] = '
+                    <span class="btn btn-default sortableHandle" data-id="' . (int)$databaseRow['uid'] . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.move')) . '">
+                        ' . $this->iconFactory->getIcon('actions-move-move', Icon::SIZE_SMALL)->render() . '
+                    </span>';
+            }
+        } elseif (($this->data['isInlineDefaultLanguageRecordInLocalizedParentContext'] ?? false)
+            && MathUtility::canBeInterpretedAsInteger($this->data['inlineParentUid'])
+            && $event->isControlEnabled('localize')
+        ) {
+            $controls['localize'] = '
+                <button type="button" class="btn btn-default t3js-synchronizelocalize-button" data-type="' . htmlspecialchars((string)$databaseRow['uid']) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:localize')) . '">
+                    ' . $this->iconFactory->getIcon('actions-document-localize', Icon::SIZE_SMALL)->render() . '
+                </button>';
+        }
+        if ($lockInfo = BackendUtility::isRecordLocked(self::FILE_REFERENCE_TABLE, $databaseRow['uid'])) {
+            $controls['locked'] = '
+				<button type="button" class="btn btn-default" data-bs-toggle="tooltip" title="' . htmlspecialchars($lockInfo['msg']) . '">
+					' . $this->iconFactory->getIcon('status-user-backend', Icon::SIZE_SMALL, 'overlay-edit')->render() . '
+				</button>';
+        }
+
+        // Get modified controls. This means their markup was modified, new controls were added or controls got removed.
+        $controls = $this->eventDispatcher->dispatch(
+            new ModifyFileReferenceControlsEvent($controls, $this->data, $databaseRow)
+        )->getControls();
+
+        $out = '';
+        if (($controls['edit'] ?? false) || ($controls['hide'] ?? false) || ($controls['delete'] ?? false)) {
+            $out .= '
+                <div class="btn-group btn-group-sm" role="group">
+                    ' . ($controls['edit'] ?? '') . ($controls['hide'] ?? '') . ($controls['delete'] ?? '') . '
+                </div>';
+            unset($controls['edit'], $controls['hide'], $controls['delete']);
+        }
+        if (($controls['info'] ?? false) || ($controls['new'] ?? false) || ($controls['sort.up'] ?? false) || ($controls['sort.down'] ?? false) || ($controls['dragdrop'] ?? false)) {
+            $out .= '
+                <div class="btn-group btn-group-sm" role="group">
+                    ' . ($controls['info'] ?? '') . ($controls['new'] ?? '') . ($controls['sort.up'] ?? '') . ($controls['sort.down'] ?? '') . ($controls['dragdrop'] ?? '') . '
+                </div>';
+            unset($controls['info'], $controls['new'], $controls['sort.up'], $controls['sort.down'], $controls['dragdrop']);
+        }
+        if ($controls['localize'] ?? false) {
+            $out .= '<div class="btn-group btn-group-sm" role="group">' . $controls['localize'] . '</div>';
+            unset($controls['localize']);
+        }
+        if ($controls !== [] && ($remainingControls = trim(implode('', $controls))) !== '') {
+            $out .= '<div class="btn-group btn-group-sm" role="group">' . $remainingControls . '</div>';
+        }
+        return $out;
+    }
+
+    protected function getRecordTitle(): string
+    {
+        $databaseRow = $this->data['databaseRow'];
+        $fileRecord = $databaseRow['uid_local'][0]['row'] ?? null;
+
+        if ($fileRecord === null) {
+            return $this->data['recordTitle'] ?: (string)$databaseRow['uid'];
+        }
+
+        $title = '';
+        foreach (self::SYS_FILE_LABEL_FIELDS as $field) {
+            $value = '';
+            if ($field === 'title') {
+                $fullTitle = '';
+                if (isset($databaseRow['title'])) {
+                    $fullTitle = $databaseRow['title'];
+                } elseif ($fileRecord['uid'] ?? false) {
+                    try {
+                        $metaDataRepository = GeneralUtility::makeInstance(MetaDataRepository::class);
+                        $metaData = $metaDataRepository->findByFileUid($fileRecord['uid']);
+                        $fullTitle = $metaData['title'] ?? '';
+                    } catch (InvalidUidException $e) {
+                    }
+                }
+                $value = BackendUtility::getRecordTitlePrep($fullTitle);
+            } elseif (isset($databaseRow[$field])) {
+                $value = htmlspecialchars((string)$databaseRow[$field]);
+            } elseif (isset($fileRecord[$field])) {
+                $value = BackendUtility::getRecordTitlePrep($fileRecord[$field]);
+            }
+            if ($value === '') {
+                continue;
+            }
+
+            $title = '
+                <dt class="col text-truncate">
+                    ' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file.' . $field)) . '
+                </dt>
+                <dd class="col">
+                    ' . $value . '
+                </dd>';
+
+            // In debug mode, add the table name to the record title
+            if ($this->getBackendUserAuthentication()->shallDisplayDebugInformation()) {
+                $title .= '<div class="col"><code class="m-0">[' . self::FILE_REFERENCE_TABLE . ']</code></div>';
+            }
+        }
+
+        return '<dl class="row row-cols-auto g-2">' . $title . '</dl>';
+    }
+
+    protected function getBackendUserAuthentication(): BackendUserAuthentication
+    {
+        return $GLOBALS['BE_USER'];
+    }
+
+    protected function getLanguageService(): LanguageService
+    {
+        return $GLOBALS['LANG'];
+    }
+}
diff --git a/typo3/sysext/backend/Classes/Form/Container/FilesControlContainer.php b/typo3/sysext/backend/Classes/Form/Container/FilesControlContainer.php
new file mode 100644
index 000000000000..dd87ea1feb7d
--- /dev/null
+++ b/typo3/sysext/backend/Classes/Form/Container/FilesControlContainer.php
@@ -0,0 +1,431 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * 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!
+ */
+
+namespace TYPO3\CMS\Backend\Form\Container;
+
+use Psr\EventDispatcher\EventDispatcherInterface;
+use TYPO3\CMS\Backend\Form\Event\CustomFileControlsEvent;
+use TYPO3\CMS\Backend\Form\InlineStackProcessor;
+use TYPO3\CMS\Backend\Form\NodeFactory;
+use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\Imaging\Icon;
+use TYPO3\CMS\Core\Imaging\IconFactory;
+use TYPO3\CMS\Core\Localization\LanguageService;
+use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction;
+use TYPO3\CMS\Core\Resource\Folder;
+use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\MathUtility;
+use TYPO3\CMS\Core\Utility\StringUtility;
+use TYPO3Fluid\Fluid\View\TemplateView;
+
+/**
+ * Files entry container.
+ *
+ * This container is the entry step to rendering a file reference. It is created by SingleFieldContainer.
+ *
+ * The code creates the main structure for the single file reference, initializes the inlineData array,
+ * that is manipulated and also returned back in its manipulated state. The "control" stuff of file
+ * references is rendered here, for example the "create new" button.
+ *
+ * For each existing file reference, a FileReferenceContainer is called for further processing.
+ */
+class FilesControlContainer extends AbstractContainer
+{
+    public const NODE_TYPE_IDENTIFIER = 'file';
+
+    private const FILE_REFERENCE_TABLE = 'sys_file_reference';
+
+    /**
+     * Inline data array used in JS, returned as JSON object to frontend
+     */
+    protected array $fileReferenceData = [];
+
+    /**
+     * @var array<int,JavaScriptModuleInstruction|string|array<string,string>>
+     */
+    protected array $requireJsModules = [];
+
+    protected IconFactory $iconFactory;
+    protected InlineStackProcessor $inlineStackProcessor;
+
+    protected $defaultFieldInformation = [
+        'tcaDescription' => [
+            'renderType' => 'tcaDescription',
+        ],
+    ];
+
+    protected $defaultFieldWizard = [
+        'localizationStateSelector' => [
+            'renderType' => 'localizationStateSelector',
+        ],
+    ];
+
+    /**
+     * Container objects give $nodeFactory down to other containers.
+     *
+     * @param NodeFactory $nodeFactory
+     * @param array $data
+     */
+    public function __construct(NodeFactory $nodeFactory, array $data)
+    {
+        parent::__construct($nodeFactory, $data);
+        $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
+    }
+
+    /**
+     * Entry method
+     *
+     * @return array As defined in initializeResultArray() of AbstractNode
+     */
+    public function render()
+    {
+        $languageService = $this->getLanguageService();
+
+        $this->fileReferenceData = $this->data['inlineData'];
+
+        $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
+        $this->inlineStackProcessor = $inlineStackProcessor;
+        $inlineStackProcessor->initializeByGivenStructure($this->data['inlineStructure']);
+
+        $table = $this->data['tableName'];
+        $row = $this->data['databaseRow'];
+        $field = $this->data['fieldName'];
+        $parameterArray = $this->data['parameterArray'];
+
+        $resultArray = $this->initializeResultArray();
+
+        $config = $parameterArray['fieldConf']['config'];
+        $isReadOnly = (bool)($config['readOnly'] ?? false);
+        $language = 0;
+        if (BackendUtility::isTableLocalizable($table)) {
+            $languageFieldName = $GLOBALS['TCA'][$table]['ctrl']['languageField'] ?? '';
+            $language = isset($row[$languageFieldName][0]) ? (int)$row[$languageFieldName][0] : (int)$row[$languageFieldName];
+        }
+
+        // Add the current inline job to the structure stack
+        $newStructureItem = [
+            'table' => $table,
+            'uid' => $row['uid'],
+            'field' => $field,
+            'config' => $config,
+        ];
+
+        // Extract FlexForm parts (if any) from element name, e.g. array('vDEF', 'lDEF', 'FlexField', 'vDEF')
+        $itemName = (string)$parameterArray['itemFormElName'];
+        if ($itemName !== '') {
+            $flexFormParts = $this->extractFlexFormParts($itemName);
+            if ($flexFormParts !== null) {
+                $newStructureItem['flexform'] = $flexFormParts;
+                if ($flexFormParts !== []
+                    && isset($this->data['processedTca']['columns'][$field]['config']['dataStructureIdentifier'])
+                ) {
+                    // Transport the flexform DS identifier fields to the FormFilesAjaxController
+                    $config['dataStructureIdentifier'] = $this->data['processedTca']['columns'][$field]['config']['dataStructureIdentifier'];
+                }
+            }
+        }
+
+        $inlineStackProcessor->pushStableStructureItem($newStructureItem);
+
+        // Hand over original returnUrl to FormFilesAjaxController. Needed if opening for instance a
+        // nested element in a new view to then go back to the original returnUrl and not the url of
+        // the inline ajax controller
+        $config['originalReturnUrl'] = $this->data['returnUrl'];
+
+        // e.g. data[<table>][<uid>][<field>]
+        $formFieldName = $inlineStackProcessor->getCurrentStructureFormPrefix();
+        // e.g. data-<pid>-<table1>-<uid1>-<field1>-<table2>-<uid2>-<field2>
+        $formFieldIdentifier = $inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']);
+
+        $config['inline']['first'] = false;
+
+        $firstChild = reset($this->data['parameterArray']['fieldConf']['children']);
+        if (isset($firstChild['databaseRow']['uid'])) {
+            $config['inline']['first'] = $firstChild['databaseRow']['uid'];
+        }
+        $config['inline']['last'] = false;
+        $lastChild = end($this->data['parameterArray']['fieldConf']['children']);
+        if (isset($lastChild['databaseRow']['uid'])) {
+            $config['inline']['last'] = $lastChild['databaseRow']['uid'];
+        }
+
+        $top = $inlineStackProcessor->getStructureLevel(0);
+
+        $this->fileReferenceData['config'][$formFieldIdentifier] = [
+            'table' => self::FILE_REFERENCE_TABLE,
+        ];
+        $configJson = (string)json_encode($config);
+        $this->fileReferenceData['config'][$formFieldIdentifier . '-' . self::FILE_REFERENCE_TABLE] = [
+            'min' => $config['minitems'],
+            'max' => $config['maxitems'],
+            'sortable' => $config['appearance']['useSortable'] ?? false,
+            'top' => [
+                'table' => $top['table'],
+                'uid' => $top['uid'],
+            ],
+            'context' => [
+                'config' => $configJson,
+                'hmac' => GeneralUtility::hmac($configJson, 'FilesContext'),
+            ],
+        ];
+        $this->fileReferenceData['nested'][$formFieldIdentifier] = $this->data['tabAndInlineStack'];
+
+        $resultArray['inlineData'] = $this->fileReferenceData;
+
+        // @todo: It might be a good idea to have something like "isLocalizedRecord" or similar set by a data provider
+        $uidOfDefaultRecord = $row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'] ?? null] ?? 0;
+        $isLocalizedParent = $language > 0
+            && ($uidOfDefaultRecord[0] ?? $uidOfDefaultRecord) > 0
+            && MathUtility::canBeInterpretedAsInteger($row['uid']);
+        $numberOfFullLocalizedChildren = 0;
+        $numberOfNotYetLocalizedChildren = 0;
+        foreach ($this->data['parameterArray']['fieldConf']['children'] as $child) {
+            if (!$child['isInlineDefaultLanguageRecordInLocalizedParentContext']) {
+                $numberOfFullLocalizedChildren++;
+            }
+            if ($isLocalizedParent && $child['isInlineDefaultLanguageRecordInLocalizedParentContext']) {
+                $numberOfNotYetLocalizedChildren++;
+            }
+        }
+
+        if ($isReadOnly || $numberOfFullLocalizedChildren >= ($config['maxitems'] ?? 0)) {
+            $config['inline']['showNewFileReferenceButton'] = false;
+            $config['inline']['showCreateNewRelationButton'] = false;
+            $config['inline']['showOnlineMediaAddButtonStyle'] = false;
+        }
+
+        $fieldInformationResult = $this->renderFieldInformation();
+        $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false);
+
+        $fieldWizardResult = $this->renderFieldWizard();
+        $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldWizardResult, false);
+
+        $sortableRecordUids = $fileReferencesHtml = [];
+        foreach ($this->data['parameterArray']['fieldConf']['children'] as $options) {
+            $options['inlineParentUid'] = $row['uid'];
+            $options['inlineFirstPid'] = $this->data['inlineFirstPid'];
+            $options['inlineParentConfig'] = $config;
+            $options['inlineData'] = $this->fileReferenceData;
+            $options['inlineStructure'] = $inlineStackProcessor->getStructure();
+            $options['inlineExpandCollapseStateArray'] = $this->data['inlineExpandCollapseStateArray'];
+            $options['renderType'] = FileReferenceContainer::NODE_TYPE_IDENTIFIER;
+            $fileReference = $this->nodeFactory->create($options)->render();
+            $fileReferencesHtml[] = $fileReference['html'];
+            $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fileReference, false);
+            if (!$options['isInlineDefaultLanguageRecordInLocalizedParentContext'] && isset($options['databaseRow']['uid'])) {
+                // Don't add record to list of "valid" uids if it is only the default
+                // language record of a not yet localized child
+                $sortableRecordUids[] = $options['databaseRow']['uid'];
+            }
+        }
+
+        // @todo: It's unfortunate we're using Typo3Fluid TemplateView directly here. We can't
+        //        inject BackendViewFactory here since __construct() is polluted by NodeInterface.
+        //        Remove __construct() from NodeInterface to have DI, then use BackendViewFactory here.
+        $view = GeneralUtility::makeInstance(TemplateView::class);
+        $templatePaths = $view->getRenderingContext()->getTemplatePaths();
+        $templatePaths->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates')]);
+        $view->assignMultiple([
+            'formFieldIdentifier' => $formFieldIdentifier,
+            'formFieldName' => $formFieldName,
+            'formGroupAttributes' => GeneralUtility::implodeAttributes([
+                'class' => 'form-group',
+                'id' => $formFieldIdentifier,
+                'data-uid' => (string)$row['uid'],
+                'data-local-table' => (string)$top['table'],
+                'data-local-field' => (string)$top['field'],
+                'data-foreign-table' => self::FILE_REFERENCE_TABLE,
+                'data-object-group' => $formFieldIdentifier . '-' . self::FILE_REFERENCE_TABLE,
+                'data-form-field' => $formFieldName,
+                'data-appearance' => (string)json_encode($config['appearance'] ?? ''),
+            ], true),
+            'fieldInformation' => $fieldInformationResult['html'],
+            'fieldWizard' => $fieldWizardResult['html'],
+            'fileReferences' => [
+                'id' => $formFieldIdentifier . '_records',
+                'title' => $languageService->sL(trim($parameterArray['fieldConf']['label'] ?? '')),
+                'records' => implode(LF, $fileReferencesHtml),
+            ],
+            'sortableRecordUids' => implode(',', $sortableRecordUids),
+            'validationRules' => $this->getValidationDataAsJsonString([
+                'type' => 'inline',
+                'minitems' => $config['minitems'] ?? null,
+                'maxitems' => $config['maxitems'] ?? null,
+            ]),
+        ]);
+
+        if (!$isReadOnly && ($config['appearance']['showFileSelectors'] ?? true) !== false) {
+            $allowedFileTypes = GeneralUtility::trimExplode(',', (string)($config['allowed'] ?? ''), true);
+            $view->assign('fileSelectors', $this->getFileSelectors($config, $allowedFileTypes));
+            $view->assign('allowedFileTypes', $allowedFileTypes);
+            // Render the localization buttons if needed
+            if ($numberOfNotYetLocalizedChildren) {
+                $view->assignMultiple([
+                    'showAllLocalizationLink' => !empty($config['appearance']['showAllLocalizationLink']),
+                    'showSynchronizationLink' => !empty($config['appearance']['showSynchronizationLink']),
+                ]);
+            }
+        }
+
+        $controls = GeneralUtility::makeInstance(EventDispatcherInterface::class)->dispatch(
+            new CustomFileControlsEvent($resultArray, $table, $field, $row, $config, $formFieldIdentifier, $formFieldName)
+        )->getControls();
+
+        if ($controls !== []) {
+            $view->assign('customControls', [
+                'id' => $formFieldIdentifier . '_customControls',
+                'controls' => implode("\n", $controls),
+            ]);
+        }
+
+        $resultArray['html'] = $view->render('Form/FilesControlContainer');
+        $resultArray['requireJsModules'] = array_merge($resultArray['requireJsModules'], $this->requireJsModules);
+        $resultArray['requireJsModules'][] = JavaScriptModuleInstruction::create('@typo3/backend/form-engine/container/files-control-container.js');
+
+        return $resultArray;
+    }
+
+    /**
+     * Generate buttons to select, reference and upload files.
+     */
+    protected function getFileSelectors(array $inlineConfiguration, array $allowedFileTypes): array
+    {
+        $languageService = $this->getLanguageService();
+        $backendUser = $this->getBackendUserAuthentication();
+
+        $currentStructureDomObjectIdPrefix = $this->inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']);
+        $objectPrefix = $currentStructureDomObjectIdPrefix . '-' . self::FILE_REFERENCE_TABLE;
+
+        $controls = [];
+        if ($inlineConfiguration['appearance']['elementBrowserEnabled'] ?? true) {
+            if ($inlineConfiguration['appearance']['createNewRelationLinkTitle'] ?? false) {
+                $createNewRelationLinkTitle = $languageService->sL($inlineConfiguration['appearance']['createNewRelationLinkTitle']);
+            } else {
+                $createNewRelationLinkTitle = $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.createNewRelation');
+            }
+            $attributes = [
+                'type' => 'button',
+                'class' => 'btn btn-default t3js-element-browser',
+                'style' => !($inlineConfiguration['inline']['showCreateNewRelationButton'] ?? true) ? 'display: none;' : '',
+                'title' => $createNewRelationLinkTitle,
+                'data-mode' => 'file',
+                'data-params' => '|||' . implode(',', $allowedFileTypes) . '|' . $objectPrefix,
+            ];
+            $controls[] = '
+                <button ' . GeneralUtility::implodeAttributes($attributes, true) . '>
+				    ' . $this->iconFactory->getIcon('actions-insert-record', Icon::SIZE_SMALL)->render() . '
+				    ' . htmlspecialchars($createNewRelationLinkTitle) . '
+			    </button>';
+        }
+
+        $onlineMediaAllowed = GeneralUtility::makeInstance(OnlineMediaHelperRegistry::class)->getSupportedFileExtensions();
+        if ($allowedFileTypes !== []) {
+            $onlineMediaAllowed = array_intersect($allowedFileTypes, $onlineMediaAllowed);
+        }
+
+        $showUpload = (bool)($inlineConfiguration['appearance']['fileUploadAllowed'] ?? true);
+        $showByUrl = ($inlineConfiguration['appearance']['fileByUrlAllowed'] ?? true) && $onlineMediaAllowed !== [];
+
+        if (($showUpload || $showByUrl) && ($backendUser->uc['edit_docModuleUpload'] ?? false)) {
+            $folder = $backendUser->getDefaultUploadFolder(
+                $this->data['tableName'] === 'pages' ? $this->data['vanillaUid'] : ($this->data['parentPageRow']['uid'] ?? 0),
+                $this->data['tableName'],
+                $this->data['fieldName']
+            );
+            if (
+                $folder instanceof Folder
+                && $folder->getStorage()->checkUserActionPermission('add', 'File')
+            ) {
+                if ($showUpload) {
+                    $attributes = [
+                        'type' => 'button',
+                        'class' => 'btn btn-default t3js-drag-uploader',
+                        'style' => !($inlineConfiguration['inline']['showCreateNewRelationButton'] ?? true) ? 'display: none;' : '',
+                        'data-dropzone-target' => '#' . StringUtility::escapeCssSelector($currentStructureDomObjectIdPrefix),
+                        'data-insert-dropzone-before' => '1',
+                        'data-file-irre-object' => $objectPrefix,
+                        'data-file-allowed' => implode(',', $allowedFileTypes),
+                        'data-target-folder' => $folder->getCombinedIdentifier(),
+                        'data-max-file-size' => (string)(GeneralUtility::getMaxUploadFileSize() * 1024),
+                    ];
+                    $controls[] = '
+                        <button ' . GeneralUtility::implodeAttributes($attributes, true) . '>
+					        ' . $this->iconFactory->getIcon('actions-upload', Icon::SIZE_SMALL)->render() . '
+                            ' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_upload.select-and-submit')) . '
+                        </button>';
+
+                    $this->requireJsModules[] = JavaScriptModuleInstruction::create('@typo3/backend/drag-uploader.js');
+                }
+                if ($showByUrl) {
+                    $buttonText = $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.button');
+                    $attributes = [
+                        'type' => 'button',
+                        'class' => 'btn btn-default t3js-online-media-add-btn',
+                        'title' => $buttonText,
+                        'style' => !($inlineConfiguration['inline']['showOnlineMediaAddButtonStyle'] ?? true) ? 'display: none;' : '',
+                        'data-target-folder' => $folder->getCombinedIdentifier(),
+                        'data-file-irre-object' => $objectPrefix,
+                        'data-online-media-allowed' => implode(',', $onlineMediaAllowed),
+                        'data-btn-submit' => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.placeholder'),
+                        'data-placeholder' => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.placeholder'),
+                        'data-online-media-allowed-help-text' => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.allowEmbedSources'),
+                    ];
+
+                    // @todo Should be implemented as web component
+                    $controls[] = '
+                        <button ' . GeneralUtility::implodeAttributes($attributes, true) . '>
+							' . $this->iconFactory->getIcon('actions-online-media-add', Icon::SIZE_SMALL)->render() . '
+							' . htmlspecialchars($buttonText) . '
+                        </button>';
+
+                    $this->requireJsModules[] = JavaScriptModuleInstruction::create('@typo3/backend/online-media.js');
+                }
+            }
+        }
+
+        return $controls;
+    }
+
+    /**
+     * Extracts FlexForm parts of a form element name like
+     * data[table][uid][field][sDEF][lDEF][FlexForm][vDEF]
+     */
+    protected function extractFlexFormParts(string $formElementName): ?array
+    {
+        $flexFormParts = null;
+        $matches = [];
+        if (preg_match('#^data(?:\[[^]]+\]){3}(\[data\](?:\[[^]]+\]){4,})$#', $formElementName, $matches)) {
+            $flexFormParts = GeneralUtility::trimExplode(
+                '][',
+                trim($matches[1], '[]')
+            );
+        }
+        return $flexFormParts;
+    }
+
+    protected function getBackendUserAuthentication(): BackendUserAuthentication
+    {
+        return $GLOBALS['BE_USER'];
+    }
+
+    protected function getLanguageService(): LanguageService
+    {
+        return $GLOBALS['LANG'];
+    }
+}
diff --git a/typo3/sysext/backend/Classes/Form/Container/InlineControlContainer.php b/typo3/sysext/backend/Classes/Form/Container/InlineControlContainer.php
index 0b240fb5154d..7c104fc40a8a 100644
--- a/typo3/sysext/backend/Classes/Form/Container/InlineControlContainer.php
+++ b/typo3/sysext/backend/Classes/Form/Container/InlineControlContainer.php
@@ -23,11 +23,8 @@ use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Core\Localization\LanguageService;
 use TYPO3\CMS\Core\Page\JavaScriptModuleInstruction;
-use TYPO3\CMS\Core\Resource\Folder;
-use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\MathUtility;
-use TYPO3\CMS\Core\Utility\StringUtility;
 
 /**
  * Inline element entry container.
@@ -122,9 +119,9 @@ class InlineControlContainer extends AbstractContainer
         $foreign_table = $config['foreign_table'];
         $isReadOnly = isset($config['readOnly']) && $config['readOnly'];
         $language = 0;
-        $languageFieldName = $GLOBALS['TCA'][$table]['ctrl']['languageField'] ?? '';
         if (BackendUtility::isTableLocalizable($table)) {
-            $language = isset($row[$languageFieldName][0]) ? (int)$row[$languageFieldName][0] : (int)$row[$languageFieldName];
+            $languageFieldName = $GLOBALS['TCA'][$table]['ctrl']['languageField'] ?? '';
+            $language = isset($row[$languageFieldName][0]) ? (int)$row[$languageFieldName][0] : (int)($row[$languageFieldName] ?? 0);
         }
 
         // Add the current inline job to the structure stack
@@ -279,8 +276,6 @@ class InlineControlContainer extends AbstractContainer
         // Define how to show the "Create new record" button - if there are more than maxitems, hide it
         if ($isReadOnly || $numberOfFullLocalizedChildren >= ($config['maxitems'] ?? 0) || ($uniqueMax > 0 && $numberOfFullLocalizedChildren >= $uniqueMax)) {
             $config['inline']['inlineNewButtonStyle'] = 'display: none;';
-            $config['inline']['inlineNewRelationButtonStyle'] = 'display: none;';
-            $config['inline']['inlineOnlineMediaAddButtonStyle'] = 'display: none;';
         }
 
         // Render the "new record" level button:
@@ -475,136 +470,47 @@ class InlineControlContainer extends AbstractContainer
      * @param array $inlineConfiguration TCA inline configuration of the parent(!) field
      * @return string A HTML button that opens an element browser in a new window
      */
-    protected function renderPossibleRecordsSelectorTypeGroupDB(array $inlineConfiguration)
+    protected function renderPossibleRecordsSelectorTypeGroupDB(array $inlineConfiguration): string
     {
-        $backendUser = $this->getBackendUserAuthentication();
         $languageService = $this->getLanguageService();
-
         $groupFieldConfiguration = $inlineConfiguration['selectorOrUniqueConfiguration']['config'];
-
-        $foreign_table = $inlineConfiguration['foreign_table'];
-        $allowed = $groupFieldConfiguration['allowed'];
-        $currentStructureDomObjectIdPrefix = $this->inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']);
-        $objectPrefix = $currentStructureDomObjectIdPrefix . '-' . $foreign_table;
-        $mode = 'db';
-        $showUpload = false;
-        $showByUrl = false;
+        $objectPrefix = $this->inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']) . '-' . $inlineConfiguration['foreign_table'];
         $elementBrowserEnabled = true;
-        if (!empty($inlineConfiguration['appearance']['createNewRelationLinkTitle'])) {
-            $createNewRelationText = htmlspecialchars($languageService->sL($inlineConfiguration['appearance']['createNewRelationLinkTitle']));
-        } else {
-            $createNewRelationText = htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.createNewRelation'));
-        }
-        if (is_array($groupFieldConfiguration['appearance'] ?? null)) {
-            if (isset($groupFieldConfiguration['appearance']['elementBrowserType'])) {
-                $mode = $groupFieldConfiguration['appearance']['elementBrowserType'];
-            }
-            if ($mode === 'file') {
-                $showUpload = true;
-                $showByUrl = true;
-            }
-            if (isset($inlineConfiguration['appearance']['fileUploadAllowed'])) {
-                $showUpload = (bool)$inlineConfiguration['appearance']['fileUploadAllowed'];
-            }
-            if (isset($inlineConfiguration['appearance']['fileByUrlAllowed'])) {
-                $showByUrl = (bool)$inlineConfiguration['appearance']['fileByUrlAllowed'];
-            }
-            if (isset($groupFieldConfiguration['appearance']['elementBrowserAllowed'])) {
-                $allowed = $groupFieldConfiguration['appearance']['elementBrowserAllowed'];
-            }
-            if (isset($inlineConfiguration['appearance']['elementBrowserEnabled'])) {
-                $elementBrowserEnabled = (bool)$inlineConfiguration['appearance']['elementBrowserEnabled'];
-            }
+        if (is_array($groupFieldConfiguration['appearance'] ?? null)
+            && isset($inlineConfiguration['appearance']['elementBrowserEnabled'])
+        ) {
+            $elementBrowserEnabled = (bool)$inlineConfiguration['appearance']['elementBrowserEnabled'];
         }
         // Remove any white-spaces from the allowed extension lists
-        $allowed = implode(',', GeneralUtility::trimExplode(',', $allowed, true));
-        $browserParams = '|||' . $allowed . '|' . $objectPrefix;
+        $allowed = GeneralUtility::trimExplode(',', (string)($groupFieldConfiguration['allowed'] ?? ''), true);
         $buttonStyle = '';
         if (isset($inlineConfiguration['inline']['inlineNewRelationButtonStyle'])) {
             $buttonStyle = ' style="' . $inlineConfiguration['inline']['inlineNewRelationButtonStyle'] . '"';
         }
         $item = '';
         if ($elementBrowserEnabled) {
-            $item .= '
-			<button type="button" class="btn btn-default t3js-element-browser" data-mode="' . htmlspecialchars($mode) . '" data-params="' . htmlspecialchars($browserParams) . '"
-				' . $buttonStyle . ' title="' . $createNewRelationText . '">
-				' . $this->iconFactory->getIcon('actions-insert-record', Icon::SIZE_SMALL)->render() . '
-				' . $createNewRelationText . '
-			</button>';
-        }
-
-        $isDirectFileUploadEnabled = (bool)$backendUser->uc['edit_docModuleUpload'];
-        $allowedArray = GeneralUtility::trimExplode(',', $allowed, true);
-        $onlineMediaAllowed = GeneralUtility::makeInstance(OnlineMediaHelperRegistry::class)->getSupportedFileExtensions();
-        if (!empty($allowedArray)) {
-            $onlineMediaAllowed = array_intersect($allowedArray, $onlineMediaAllowed);
-        }
-        if (($showUpload || $showByUrl) && $isDirectFileUploadEnabled) {
-            $folder = $backendUser->getDefaultUploadFolder(
-                $this->data['tableName'] === 'pages' ? $this->data['vanillaUid'] : ($this->data['parentPageRow']['uid'] ?? 0),
-                $this->data['tableName'],
-                $this->data['fieldName']
-            );
-            if (
-                $folder instanceof Folder
-                && $folder->getStorage()->checkUserActionPermission('add', 'File')
-            ) {
-                if ($showUpload) {
-                    $maxFileSize = GeneralUtility::getMaxUploadFileSize() * 1024;
-                    $item .= ' <button type="button" class="btn btn-default t3js-drag-uploader inlineNewFileUploadButton"
-					' . $buttonStyle . '
-					data-dropzone-target="#' . htmlspecialchars(StringUtility::escapeCssSelector($currentStructureDomObjectIdPrefix)) . '"
-					data-insert-dropzone-before="1"
-					data-file-irre-object="' . htmlspecialchars($objectPrefix) . '"
-					data-file-allowed="' . htmlspecialchars($allowed) . '"
-					data-target-folder="' . htmlspecialchars($folder->getCombinedIdentifier()) . '"
-					data-max-file-size="' . htmlspecialchars((string)$maxFileSize) . '"
-					>';
-                    $item .= $this->iconFactory->getIcon('actions-upload', Icon::SIZE_SMALL)->render() . ' ';
-                    $item .= htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:file_upload.select-and-submit'));
-                    $item .= '</button>';
-
-                    $this->requireJsModules[] = JavaScriptModuleInstruction::create('@typo3/backend/drag-uploader.js');
-                }
-                if (!empty($onlineMediaAllowed) && $showByUrl) {
-                    $buttonStyle = '';
-                    if (isset($inlineConfiguration['inline']['inlineOnlineMediaAddButtonStyle'])) {
-                        $buttonStyle = ' style="' . $inlineConfiguration['inline']['inlineOnlineMediaAddButtonStyle'] . '"';
-                    }
-                    $this->requireJsModules[] = JavaScriptModuleInstruction::create('@typo3/backend/online-media.js');
-                    $buttonText = htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.button'));
-                    $placeholder = htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.placeholder'));
-                    $buttonSubmit = htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:online_media.new_media.submit'));
-                    $allowedMediaUrl = htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.allowEmbedSources'));
-                    $item .= '
-						<button type="button" class="btn btn-default t3js-online-media-add-btn"
-							' . $buttonStyle . '
-							data-file-irre-object="' . htmlspecialchars($objectPrefix) . '"
-							data-online-media-allowed="' . htmlspecialchars(implode(',', $onlineMediaAllowed)) . '"
-							data-online-media-allowed-help-text="' . $allowedMediaUrl . '"
-							data-target-folder="' . htmlspecialchars($folder->getCombinedIdentifier()) . '"
-							title="' . $buttonText . '"
-							data-btn-submit="' . $buttonSubmit . '"
-							data-placeholder="' . $placeholder . '"
-							>
-							' . $this->iconFactory->getIcon('actions-online-media-add', Icon::SIZE_SMALL)->render() . '
-							' . $buttonText . '</button>';
-                }
+            if (!empty($inlineConfiguration['appearance']['createNewRelationLinkTitle'])) {
+                $createNewRelationText = htmlspecialchars($languageService->sL($inlineConfiguration['appearance']['createNewRelationLinkTitle']));
+            } else {
+                $createNewRelationText = htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.createNewRelation'));
             }
+            $item .= '
+                <button type="button" class="btn btn-default t3js-element-browser" data-mode="db" data-params="' . htmlspecialchars('|||' . implode(',', $allowed) . '|' . $objectPrefix) . '"
+                    ' . $buttonStyle . ' title="' . $createNewRelationText . '">
+                    ' . $this->iconFactory->getIcon('actions-insert-record', Icon::SIZE_SMALL)->render() . '
+                    ' . $createNewRelationText . '
+                </button>';
         }
-
         $item = '<div class="form-control-wrap t3js-inline-controls">' . $item . '</div>';
-        $allowedList = '';
-        $allowedLabelKey = ($mode === 'file') ? 'allowedFileExtensions' : 'allowedRelations';
-        $allowedLabel = htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.' . $allowedLabelKey));
-        foreach ($allowedArray as $allowedItem) {
-            $allowedList .= '<span class="badge badge-success">' . strtoupper($allowedItem) . '</span> ';
-        }
-        if (!empty($allowedList)) {
-            $item .= '<div class="help-block">' . $allowedLabel . '<br>' . $allowedList . '</div>';
+        if (!empty($allowed)) {
+            $item .= '
+                <div class="help-block">
+                    ' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.allowedRelations')) . '
+                    <br>
+                    ' . implode(' ', array_map(static fn ($item) => '<span class="badge badge-success">' . strtoupper($item) . '</span>', $allowed)) . '
+                </div>';
         }
-        $item = '<div class="form-group t3js-formengine-validation-marker t3js-inline-controls-top-outer-container">' . $item . '</div>';
-        return $item;
+        return '<div class="form-group t3js-formengine-validation-marker t3js-inline-controls-top-outer-container">' . $item . '</div>';
     }
 
     /**
diff --git a/typo3/sysext/backend/Classes/Form/Container/InlineRecordContainer.php b/typo3/sysext/backend/Classes/Form/Container/InlineRecordContainer.php
index 3d272bf0aedc..36558bef81ac 100644
--- a/typo3/sysext/backend/Classes/Form/Container/InlineRecordContainer.php
+++ b/typo3/sysext/backend/Classes/Form/Container/InlineRecordContainer.php
@@ -21,16 +21,11 @@ use TYPO3\CMS\Backend\Form\Event\ModifyInlineElementEnabledControlsEvent;
 use TYPO3\CMS\Backend\Form\Exception\AccessDeniedContentEditException;
 use TYPO3\CMS\Backend\Form\InlineStackProcessor;
 use TYPO3\CMS\Backend\Form\NodeFactory;
-use TYPO3\CMS\Backend\Routing\UriBuilder;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
-use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
-use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection;
 use TYPO3\CMS\Core\Localization\LanguageService;
-use TYPO3\CMS\Core\Resource\ProcessedFile;
-use TYPO3\CMS\Core\Resource\ResourceFactory;
 use TYPO3\CMS\Core\Type\Bitmask\Permission;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\MathUtility;
@@ -324,24 +319,20 @@ class InlineRecordContainer extends AbstractContainer
      * @param string $ariaAttributesString HTML aria attributes for the collapse button
      * @return string The HTML code of the header
      */
-    protected function renderForeignRecordHeader(array $data, string $ariaAttributesString)
+    protected function renderForeignRecordHeader(array $data, string $ariaAttributesString): string
     {
-        $languageService = $this->getLanguageService();
-        $inlineConfig = $data['inlineParentConfig'];
-        $foreignTable = $inlineConfig['foreign_table'];
-        $rec = $data['databaseRow'];
-        // Init:
+        $record = $data['databaseRow'];
+        $recordTitle = $data['recordTitle'];
+        $foreignTable = $data['inlineParentConfig']['foreign_table'];
         $domObjectId = $this->inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($data['inlineFirstPid']);
-        $objectId = $domObjectId . '-' . $foreignTable . '-' . ($rec['uid'] ?? 0);
 
-        $recordTitle = $data['recordTitle'];
         if (!empty($recordTitle)) {
             // The user function may return HTML, therefore we can't escape it
             if (empty($data['processedTca']['ctrl']['formattedLabel_userFunc'])) {
                 $recordTitle = BackendUtility::getRecordTitlePrep($recordTitle);
             }
         } else {
-            $recordTitle = '<em>[' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.no_title')) . ']</em>';
+            $recordTitle = '<em>[' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.no_title')) . ']</em>';
         }
 
         // In case the record title is not generated by a formattedLabel_userFunc, which already
@@ -352,67 +343,19 @@ class InlineRecordContainer extends AbstractContainer
             $recordTitle .= ' <code class="m-0">[' . htmlspecialchars($foreignTable) . ']</code>';
         }
 
-        $altText = BackendUtility::getRecordIconAltText($rec, $foreignTable);
-
-        $iconImg = '<span title="' . $altText . '" id="' . htmlspecialchars($objectId) . '_icon">' . $this->iconFactory->getIconForRecord($foreignTable, $rec, Icon::SIZE_SMALL)->render() . '</span>';
-        $label = '<span id="' . $objectId . '_label">' . $recordTitle . '</span>';
-        $ctrl = $this->renderForeignRecordHeaderControl($data);
-        $thumbnail = false;
-
-        // Renders a thumbnail for the header
-        if (($GLOBALS['TYPO3_CONF_VARS']['GFX']['thumbnails'] ?? false) && !empty($inlineConfig['appearance']['headerThumbnail']['field'])) {
-            $fieldValue = $rec[$inlineConfig['appearance']['headerThumbnail']['field']];
-            $fileUid = $fieldValue[0]['uid'] ?? null;
-
-            if (!empty($fileUid)) {
-                try {
-                    $fileObject = GeneralUtility::makeInstance(ResourceFactory::class)->getFileObject($fileUid);
-                } catch (\InvalidArgumentException $e) {
-                    $fileObject = null;
-                }
-                if ($fileObject && $fileObject->isMissing()) {
-                    $thumbnail .= '<span class="badge badge-danger">'
-                        . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:warning.file_missing'))
-                        . '</span>&nbsp;' . htmlspecialchars($fileObject->getName()) . '<br />';
-                } elseif ($fileObject) {
-                    $imageSetup = $inlineConfig['appearance']['headerThumbnail'] ?? [];
-                    unset($imageSetup['field']);
-                    $cropVariantCollection = CropVariantCollection::create($rec['crop'] ?? '');
-                    if (!$cropVariantCollection->getCropArea()->isEmpty()) {
-                        $imageSetup['crop'] = $cropVariantCollection->getCropArea()->makeAbsoluteBasedOnFile($fileObject);
-                    }
-                    $imageSetup = array_merge(['maxWidth' => '145', 'maxHeight' => '45'], $imageSetup);
-
-                    if (($GLOBALS['TYPO3_CONF_VARS']['GFX']['thumbnails'] ?? false) && $fileObject->isImage()) {
-                        $processedImage = $fileObject->process(ProcessedFile::CONTEXT_IMAGECROPSCALEMASK, $imageSetup);
-                        // Only use a thumbnail if the processing process was successful by checking if image width is set
-                        if ($processedImage->getProperty('width')) {
-                            $imageUrl = $processedImage->getPublicUrl() ?? '';
-                            $thumbnail = '<img src="' . htmlspecialchars($imageUrl) . '" ' .
-                                'width="' . $processedImage->getProperty('width') . '" ' .
-                                'height="' . $processedImage->getProperty('height') . '" ' .
-                                'alt="' . htmlspecialchars($altText) . '" ' .
-                                'title="' . htmlspecialchars($altText) . '">';
-                        }
-                    } else {
-                        $thumbnail = '';
-                    }
-                }
-            }
-        }
-
-        if (!empty($inlineConfig['appearance']['headerThumbnail']['field']) && $thumbnail) {
-            $mediaContainer = '<div class="form-irre-header-thumbnail" id="' . $objectId . '_thumbnailcontainer">' . $thumbnail . '</div>';
-        } else {
-            $mediaContainer = '<div class="form-irre-header-icon" id="' . $objectId . '_iconcontainer">' . $iconImg . '</div>';
-        }
-        $header = '<button class="form-irre-header-cell form-irre-header-button" ' . $ariaAttributesString . '>' .
-            $mediaContainer .
-            '<div class="form-irre-header-body">' . $label . '</div>' .
-            '</button>' .
-            '<div class="form-irre-header-cell form-irre-header-control t3js-formengine-irre-control">' . $ctrl . '</div>';
-
-        return $header;
+        $objectId = htmlspecialchars($domObjectId . '-' . $foreignTable . '-' . ($record['uid'] ?? 0));
+        return '
+            <button class="form-irre-header-cell form-irre-header-button" ' . $ariaAttributesString . '>
+                <div class="form-irre-header-icon" id="' . $objectId . '_iconcontainer">
+                    <span title="' . BackendUtility::getRecordIconAltText($record, $foreignTable) . '" id="' . $objectId . '_icon">
+                        ' . $this->iconFactory->getIconForRecord($foreignTable, $record, Icon::SIZE_SMALL)->render() . '
+                    </span>
+                </div>
+                <div class="form-irre-header-body"><span id="' . $objectId . '_label">' . $recordTitle . '</span></div>
+            </button>
+            <div class="form-irre-header-cell form-irre-header-control t3js-formengine-irre-control">
+                ' . $this->renderForeignRecordHeaderControl($data) . '
+            </div>';
     }
 
     /**
@@ -428,7 +371,6 @@ class InlineRecordContainer extends AbstractContainer
         $rec = $data['databaseRow'];
         $rec += [
             'uid' => 0,
-            'table_local' => '',
         ];
         $inlineConfig = $data['inlineParentConfig'];
         $foreignTable = $inlineConfig['foreign_table'];
@@ -436,7 +378,6 @@ class InlineRecordContainer extends AbstractContainer
         $backendUser = $this->getBackendUserAuthentication();
         // Initialize:
         $cells = [
-            'edit' => '',
             'hide' => '',
             'delete' => '',
             'info' => '',
@@ -453,7 +394,6 @@ class InlineRecordContainer extends AbstractContainer
         $tcaTableCtrl = $GLOBALS['TCA'][$foreignTable]['ctrl'];
         $tcaTableCols = $GLOBALS['TCA'][$foreignTable]['columns'];
         $isPagesTable = $foreignTable === 'pages';
-        $isSysFileReferenceTable = $foreignTable === 'sys_file_reference';
         $enableManualSorting = ($tcaTableCtrl['sortby'] ?? false)
             || ($inlineConfig['MM'] ?? false)
             || (!($data['isOnSymmetricSide'] ?? false) && ($inlineConfig['foreign_sortby'] ?? false))
@@ -474,20 +414,12 @@ class InlineRecordContainer extends AbstractContainer
                 </span>';
         }
         // "Info": (All records)
-        // @todo: hardcoded sys_file!
-        if ($rec['table_local'] === 'sys_file') {
-            $uid = $rec['uid_local'][0]['uid'];
-            $table = '_FILE';
-        } else {
-            $uid = $rec['uid'];
-            $table = $foreignTable;
-        }
         if ($event->isControlEnabled('info')) {
             if ($isNewItem) {
                 $cells['info'] = '<span class="btn btn-default disabled">' . $this->iconFactory->getIcon('empty-empty', Icon::SIZE_SMALL)->render() . '</span>';
             } else {
                 $cells['info'] = '
-				<button type="button" class="btn btn-default" data-action="infowindow" data-info-table="' . htmlspecialchars($table) . '" data-info-uid="' . htmlspecialchars($uid) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:showInfo')) . '">
+				<button type="button" class="btn btn-default" data-action="infowindow" data-info-table="' . htmlspecialchars($foreignTable) . '" data-info-uid="' . htmlspecialchars($rec['uid']) . '" title="' . htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:showInfo')) . '">
 					' . $this->iconFactory->getIcon('actions-document-info', Icon::SIZE_SMALL)->render() . '
 				</button>';
             }
@@ -533,50 +465,12 @@ class InlineRecordContainer extends AbstractContainer
                         ' . $this->iconFactory->getIcon($icon, Icon::SIZE_SMALL)->render() . '
                     </button>';
             }
-            // "Edit" link:
-            if (($rec['table_local'] === 'sys_file')
-                && !$isNewItem
-                && ($languageField = ($GLOBALS['TCA']['sys_file_metadata']['ctrl']['languageField'] ?? false))
-                && $backendUser->check('tables_modify', 'sys_file_metadata')
-            ) {
-                $languageId = (int)(is_array($rec[$languageField] ?? null)
-                    ? ($rec[$languageField][0] ?? 0)
-                    : ($rec[$languageField] ?? 0));
-                $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
-                    ->getQueryBuilderForTable('sys_file_metadata');
-                $recordInDatabase = $queryBuilder
-                    ->select('uid')
-                    ->from('sys_file_metadata')
-                    ->where(
-                        $queryBuilder->expr()->eq(
-                            'file',
-                            $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
-                        ),
-                        $queryBuilder->expr()->eq(
-                            $languageField,
-                            $queryBuilder->createNamedParameter($languageId, \PDO::PARAM_INT)
-                        )
-                    )
-                    ->setMaxResults(1)
-                    ->executeQuery()
-                    ->fetchAssociative();
-                if (!empty($recordInDatabase)) {
-                    $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
-                    $url = (string)$uriBuilder->buildUriFromRoute('record_edit', [
-                        'edit[sys_file_metadata][' . (int)$recordInDatabase['uid'] . ']' => 'edit',
-                        'returnUrl' => $this->data['returnUrl'],
-                    ]);
-                    $title = $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.editMetadata');
-                    $cells['edit'] = '
-                        <a class="btn btn-default" href="' . htmlspecialchars($url) . '" title="' . htmlspecialchars($title) . '">
-                            ' . $this->iconFactory->getIcon('actions-open', Icon::SIZE_SMALL)->render() . '
-                        </a>';
-                }
-            }
             // "Delete" link:
-            if ($event->isControlEnabled('delete') && (($isPagesTable && $localCalcPerms->deletePagePermissionIsGranted())
+            if ($event->isControlEnabled('delete')
+                && (
+                    ($isPagesTable && $localCalcPerms->deletePagePermissionIsGranted())
                     || (!$isPagesTable && $calcPerms->editContentPermissionIsGranted())
-                    || ($isSysFileReferenceTable && $calcPerms->editPagePermissionIsGranted()))
+                )
             ) {
                 $title = htmlspecialchars($languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:delete'));
                 $icon = $this->iconFactory->getIcon('actions-edit-delete', Icon::SIZE_SMALL)->render();
@@ -641,9 +535,9 @@ class InlineRecordContainer extends AbstractContainer
         $cells = $this->eventDispatcher->dispatch(new ModifyInlineElementControlsEvent($cells, $data, $rec))->getControls();
 
         $out = '';
-        if (!empty($cells['edit']) || !empty($cells['hide']) || !empty($cells['delete'])) {
-            $out .= '<div class="btn-group btn-group-sm" role="group">' . $cells['edit'] . $cells['hide'] . $cells['delete'] . '</div>';
-            unset($cells['edit'], $cells['hide'], $cells['delete']);
+        if (!empty($cells['hide']) || !empty($cells['delete'])) {
+            $out .= '<div class="btn-group btn-group-sm" role="group">' . $cells['hide'] . $cells['delete'] . '</div>';
+            unset($cells['hide'], $cells['delete']);
         }
         if (!empty($cells['info']) || !empty($cells['new']) || !empty($cells['sort.up']) || !empty($cells['sort.down']) || !empty($cells['dragdrop'])) {
             $out .= '<div class="btn-group btn-group-sm" role="group">' . $cells['info'] . $cells['new'] . $cells['sort.up'] . $cells['sort.down'] . $cells['dragdrop'] . '</div>';
@@ -655,7 +549,7 @@ class InlineRecordContainer extends AbstractContainer
         }
         if (!empty($cells)) {
             $cellContent = trim(implode('', $cells));
-            $out .= $cellContent != '' ? ' <div class="btn-group btn-group-sm" role="group">' . $cellContent . '</div>': '';
+            $out .= $cellContent !== '' ? ' <div class="btn-group btn-group-sm" role="group">' . $cellContent . '</div>': '';
         }
         return $out;
     }
diff --git a/typo3/sysext/backend/Classes/Form/Event/CustomFileControlsEvent.php b/typo3/sysext/backend/Classes/Form/Event/CustomFileControlsEvent.php
new file mode 100644
index 000000000000..bec56fb4847f
--- /dev/null
+++ b/typo3/sysext/backend/Classes/Form/Event/CustomFileControlsEvent.php
@@ -0,0 +1,109 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * 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!
+ */
+
+namespace TYPO3\CMS\Backend\Form\Event;
+
+/**
+ * Listeners to this Event will be able to add custom controls to a TCA type="file" field in FormEngine
+ */
+final class CustomFileControlsEvent
+{
+    private array $controls = [];
+
+    public function __construct(
+        private array $resultArray,
+        private readonly string $tableName,
+        private readonly string $fieldName,
+        private readonly array $databaseRow,
+        private readonly array $fieldConfig,
+        private readonly string $formFieldIdentifier,
+        private readonly string $formFieldName,
+    ) {
+    }
+
+    public function getResultArray(): array
+    {
+        return $this->resultArray;
+    }
+
+    /**
+     * WARNING: Modifying the result array should be used with care. It mostly
+     * only exists to allow additional $resultArray['requireJsModules'].
+     */
+    public function setResultArray(array $resultArray): void
+    {
+        $this->resultArray = $resultArray;
+    }
+
+    public function getControls(): array
+    {
+        return $this->controls;
+    }
+
+    public function setControls(array $controls): void
+    {
+        $this->controls = $controls;
+    }
+
+    public function addControl(string $control, string $identifier = ''): void
+    {
+        if ($identifier !== '') {
+            $this->controls[$identifier] = $control;
+        } else {
+            $this->controls[] = $control;
+        }
+    }
+
+    public function removeControl(string $identifier): bool
+    {
+        if (!isset($this->controls[$identifier])) {
+            return false;
+        }
+        unset($this->controls[$identifier]);
+        return true;
+    }
+
+    public function getTableName(): string
+    {
+        return $this->tableName;
+    }
+
+    public function getFieldName(): string
+    {
+        return $this->fieldName;
+    }
+
+    public function getDatabaseRow(): array
+    {
+        return $this->databaseRow;
+    }
+
+    public function getFieldConfig(): array
+    {
+        return $this->fieldConfig;
+    }
+
+    public function getFormFieldIdentifier(): string
+    {
+        return $this->formFieldIdentifier;
+    }
+
+    public function getFormFieldName(): string
+    {
+        return $this->formFieldName;
+    }
+}
diff --git a/typo3/sysext/backend/Classes/Form/Event/ModifyFileReferenceControlsEvent.php b/typo3/sysext/backend/Classes/Form/Event/ModifyFileReferenceControlsEvent.php
new file mode 100644
index 000000000000..ca0832f6f624
--- /dev/null
+++ b/typo3/sysext/backend/Classes/Form/Event/ModifyFileReferenceControlsEvent.php
@@ -0,0 +1,136 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * 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!
+ */
+
+namespace TYPO3\CMS\Backend\Form\Event;
+
+/**
+ * Listeners to this Event will be able to modify the controls
+ * of a single file reference of a TCA type=file field.
+ */
+final class ModifyFileReferenceControlsEvent
+{
+    public function __construct(
+        private array $controls,
+        private readonly array $data,
+        private readonly array $record,
+    ) {
+    }
+
+    /**
+     * Returns all controls with their markup
+     */
+    public function getControls(): array
+    {
+        return $this->controls;
+    }
+
+    /**
+     * Overwrite the controls
+     */
+    public function setControls(array $controls): void
+    {
+        $this->controls = $controls;
+    }
+
+    /**
+     * Returns the markup for the requested control
+     */
+    public function getControl(string $identifier): string
+    {
+        return $this->controls[$identifier] ?? '';
+    }
+
+    /**
+     * Set a control with the given identifier and markup
+     * IMPORTANT: Overwrites an existing control with the same identifier
+     */
+    public function setControl(string $identifier, string $markup): void
+    {
+        $this->controls[$identifier] = $markup;
+    }
+
+    /**
+     * Returns whether a control exists for the given identifier
+     */
+    public function hasControl(string $identifier): bool
+    {
+        return isset($this->controls[$identifier]);
+    }
+
+    /**
+     * Removes a control from the file reference, if it exists
+     *
+     * @return bool Whether the control could be removed
+     */
+    public function removeControl(string $identifier): bool
+    {
+        if (!$this->hasControl($identifier)) {
+            return false;
+        }
+
+        unset($this->controls[$identifier]);
+        return true;
+    }
+
+    /**
+     * Returns the whole element data
+     */
+    public function getElementData(): array
+    {
+        return $this->data;
+    }
+
+    /**
+     * Returns the current record, the controls are created for
+     */
+    public function getRecord(): array
+    {
+        return $this->record;
+    }
+
+    /**
+     * Returns the uid of the parent (embedding) record (uid or NEW...)
+     */
+    public function getParentUid(): string
+    {
+        return (string)($this->data['inlineParentUid'] ?? '');
+    }
+
+    /**
+     * Returns the table (foreign_table) the controls are created for
+     */
+    public function getForeignTable(): string
+    {
+        return (string)($this->getFieldConfiguration()['foreign_table'] ?? 'sys_file_reference');
+    }
+
+    /**
+     * Returns the TCA configuration of the TCA type=file field
+     */
+    public function getFieldConfiguration(): array
+    {
+        return (array)($this->data['inlineParentConfig'] ?? []);
+    }
+
+    /**
+     * Returns whether the current records is only virtually shown and not physically part of the parent record
+     */
+    public function isVirtual(): bool
+    {
+        return (bool)($this->data['isInlineDefaultLanguageRecordInLocalizedParentContext'] ?? false);
+    }
+}
diff --git a/typo3/sysext/backend/Classes/Form/Event/ModifyFileReferenceEnabledControlsEvent.php b/typo3/sysext/backend/Classes/Form/Event/ModifyFileReferenceEnabledControlsEvent.php
new file mode 100644
index 000000000000..25ccbbe320d7
--- /dev/null
+++ b/typo3/sysext/backend/Classes/Form/Event/ModifyFileReferenceEnabledControlsEvent.php
@@ -0,0 +1,147 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * 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!
+ */
+
+namespace TYPO3\CMS\Backend\Form\Event;
+
+/**
+ * Listeners to this Event will be able to modify the state (enabled or disabled) for controls of a file reference
+ */
+final class ModifyFileReferenceEnabledControlsEvent
+{
+    /**
+     * @var array<string, bool>
+     */
+    private array $controlsState;
+
+    public function __construct(
+        private readonly array $data,
+        private readonly array $record,
+    ) {
+        $this->controlsState = (array)($data['inlineParentConfig']['appearance']['enabledControls'] ?? []);
+    }
+
+    /**
+     * Enable a control, if it exists
+     *
+     * @return bool Whether the control could be enabled
+     */
+    public function enableControl(string $identifier): bool
+    {
+        if (!$this->hasControl($identifier)) {
+            return false;
+        }
+
+        $this->controlsState[$identifier] = true;
+        return true;
+    }
+
+    /**
+     * Disable a control, if it exists
+     *
+     * @return bool Whether the control could be disabled
+     */
+    public function disableControl(string $identifier): bool
+    {
+        if (!$this->hasControl($identifier)) {
+            return false;
+        }
+
+        $this->controlsState[$identifier] = false;
+        return true;
+    }
+
+    /**
+     * Returns whether a control exists for the given identifier
+     */
+    public function hasControl(string $identifier): bool
+    {
+        return isset($this->controlsState[$identifier]);
+    }
+
+    /**
+     * Returns whether the control is enabled.
+     * Note: Will also return FALSE in case no control exists for the requested identifier
+     */
+    public function isControlEnabled(string $identifier): bool
+    {
+        return (bool)($this->controlsState[$identifier] ?? false);
+    }
+
+    /**
+     * Returns all controls with their state (enabled or disabled)
+     */
+    public function getControlsState(): array
+    {
+        return $this->controlsState;
+    }
+
+    /**
+     * Returns all enabled controls
+     */
+    public function getEnabledControls(): array
+    {
+        return array_filter($this->controlsState, static fn ($control) => (bool)$control === true);
+    }
+
+    /**
+     * Returns the whole element data
+     */
+    public function getElementData(): array
+    {
+        return $this->data;
+    }
+
+    /**
+     * Returns the current record of the controls are created for
+     */
+    public function getRecord(): array
+    {
+        return $this->record;
+    }
+
+    /**
+     * Returns the uid of the parent (embedding) record (uid or NEW...)
+     */
+    public function getParentUid(): string
+    {
+        return (string)($this->data['inlineParentUid'] ?? '');
+    }
+
+    /**
+     * Returns the table (foreign_table) the controls are created for
+     */
+    public function getForeignTable(): string
+    {
+        return (string)($this->getFieldConfiguration()['foreign_table'] ?? '');
+    }
+
+    /**
+     * Returns the TCA configuration of the TCA type=file field
+     */
+    public function getFieldConfiguration(): array
+    {
+        return (array)($this->data['inlineParentConfig'] ?? []);
+    }
+
+    /**
+     * Returns whether the current records is only virtually shown and not physically part of the parent record
+     */
+    public function isVirtual(): bool
+    {
+        return (bool)($this->data['isInlineDefaultLanguageRecordInLocalizedParentContext'] ?? false);
+    }
+}
diff --git a/typo3/sysext/backend/Classes/Form/FieldControl/ElementBrowser.php b/typo3/sysext/backend/Classes/Form/FieldControl/ElementBrowser.php
index d99501c5e68f..8f3276c6d01f 100644
--- a/typo3/sysext/backend/Classes/Form/FieldControl/ElementBrowser.php
+++ b/typo3/sysext/backend/Classes/Form/FieldControl/ElementBrowser.php
@@ -42,7 +42,9 @@ class ElementBrowser extends AbstractNode
         $elementName = $parameterArray['itemFormElName'];
         $config = $parameterArray['fieldConf']['config'];
         $type = $config['type'];
-        $allowed = $config['allowed'] ?? '';
+
+        // Remove any white-spaces from the allowed extension lists
+        $allowed = implode(',', GeneralUtility::trimExplode(',', (string)($config['allowed'] ?? ''), true));
 
         if (isset($config['readOnly']) && $config['readOnly']) {
             return [];
@@ -67,23 +69,24 @@ class ElementBrowser extends AbstractNode
         ) {
             $objectPrefix = $inlineStackProcessor->getCurrentStructureDomObjectIdPrefix($this->data['inlineFirstPid']) . '-' . $table;
         }
-        $elementBrowserType = $type === 'group' ? 'db' : 'folder';
-        if (is_array($config['appearance'] ?? null)) {
-            if (isset($config['appearance']['elementBrowserType'])) {
-                $elementBrowserType = $config['appearance']['elementBrowserType'];
-            }
-            if (isset($config['appearance']['elementBrowserAllowed'])) {
-                $allowed = $config['appearance']['elementBrowserAllowed'];
+
+        if ($type === 'group') {
+            if (($this->data['inlineParentConfig']['type'] ?? '') === 'file') {
+                $elementBrowserType = 'file';
+                // Remove any white-spaces from the allowed extension lists
+                $allowed = implode(',', GeneralUtility::trimExplode(',', (string)($this->data['inlineParentConfig']['allowed'] ?? ''), true));
+            } else {
+                $elementBrowserType = 'db';
             }
+        } else {
+            $elementBrowserType = 'folder';
         }
-        // Remove any white-spaces from the allowed extension lists
-        $elementBrowserAllowed = implode(',', GeneralUtility::trimExplode(',', $allowed, true));
 
         // Initialize link attributes
         $linkAttributes = [
             'class' => 't3js-element-browser',
             'data-mode' => htmlspecialchars($elementBrowserType),
-            'data-params' => htmlspecialchars($elementName . '|||' . $elementBrowserAllowed . '|' . $objectPrefix),
+            'data-params' => htmlspecialchars($elementName . '|||' . $allowed . '|' . $objectPrefix),
         ];
 
         // Add the default entry point - if found
diff --git a/typo3/sysext/backend/Classes/Form/FieldWizard/DefaultLanguageDifferences.php b/typo3/sysext/backend/Classes/Form/FieldWizard/DefaultLanguageDifferences.php
index 3d7f9d29add9..ffcc4a6655d4 100644
--- a/typo3/sysext/backend/Classes/Form/FieldWizard/DefaultLanguageDifferences.php
+++ b/typo3/sysext/backend/Classes/Form/FieldWizard/DefaultLanguageDifferences.php
@@ -53,6 +53,7 @@ class DefaultLanguageDifferences extends AbstractNode
             || GeneralUtility::inList($l10nDisplay, 'defaultAsReadonly')
             || !isset($defaultLanguageDiffRow[$fieldName])
             || $fieldConfig['config']['type'] === 'inline'
+            || $fieldConfig['config']['type'] === 'file'
             || $fieldConfig['config']['type'] === 'flex'
         ) {
             // Early return if there is no diff row or if display is disabled
diff --git a/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageContent.php b/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageContent.php
index ed26b35203c9..0c84cfca8f46 100644
--- a/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageContent.php
+++ b/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageContent.php
@@ -48,6 +48,7 @@ class OtherLanguageContent extends AbstractNode
             || GeneralUtility::inList($l10nDisplay, 'hideDiff')
             || GeneralUtility::inList($l10nDisplay, 'defaultAsReadonly')
             || $fieldType === 'inline'
+            || $fieldType === 'file'
             || $fieldType === 'flex'
             || (in_array($fieldType, ['select', 'category', 'group'], true) && isset($fieldConfig['config']['MM']))
         ) {
diff --git a/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageThumbnails.php b/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageThumbnails.php
index 3f776388c620..ffba2a1c2772 100644
--- a/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageThumbnails.php
+++ b/typo3/sysext/backend/Classes/Form/FieldWizard/OtherLanguageThumbnails.php
@@ -66,7 +66,7 @@ class OtherLanguageThumbnails extends AbstractNode
             $file = null;
             $fileUid = (int)($languageRow['uid_local'] ?? 0);
 
-            if (!$fileUid || $languageRow['table_local'] !== 'sys_file') {
+            if (!$fileUid) {
                 continue;
             }
 
diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php
index f26027e3f285..870ad1c0a4e6 100644
--- a/typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php
+++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php
@@ -302,18 +302,15 @@ abstract class AbstractItemProvider
                 // If the foreign table sets selicon_field, this field can contain an image
                 // that represents this specific row.
                 $iconFieldName = '';
-                $isReferenceField = false;
+                $isFileReference = false;
                 if (!empty($GLOBALS['TCA'][$foreignTable]['ctrl']['selicon_field'])) {
                     $iconFieldName = $GLOBALS['TCA'][$foreignTable]['ctrl']['selicon_field'];
-                    if (isset($GLOBALS['TCA'][$foreignTable]['columns'][$iconFieldName]['config']['type'])
-                        && $GLOBALS['TCA'][$foreignTable]['columns'][$iconFieldName]['config']['type'] === 'inline'
-                        && $GLOBALS['TCA'][$foreignTable]['columns'][$iconFieldName]['config']['foreign_table'] === 'sys_file_reference'
-                    ) {
-                        $isReferenceField = true;
+                    if (($GLOBALS['TCA'][$foreignTable]['columns'][$iconFieldName]['config']['type'] ?? '') === 'file') {
+                        $isFileReference = true;
                     }
                 }
                 $icon = '';
-                if ($isReferenceField) {
+                if ($isFileReference) {
                     $references = $fileRepository->findByRelation($foreignTable, $iconFieldName, $foreignRow['uid']);
                     if (is_array($references) && !empty($references)) {
                         $icon = reset($references);
diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFiles.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFiles.php
new file mode 100644
index 000000000000..1cad32ec58ce
--- /dev/null
+++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFiles.php
@@ -0,0 +1,352 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * 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!
+ */
+
+namespace TYPO3\CMS\Backend\Form\FormDataProvider;
+
+use TYPO3\CMS\Backend\Form\Exception\DatabaseRecordException;
+use TYPO3\CMS\Backend\Form\FormDataCompiler;
+use TYPO3\CMS\Backend\Form\FormDataGroup\TcaDatabaseRecord;
+use TYPO3\CMS\Backend\Form\FormDataProviderInterface;
+use TYPO3\CMS\Backend\Form\InlineStackProcessor;
+use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\Database\RelationHandler;
+use TYPO3\CMS\Core\Localization\LanguageService;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\MathUtility;
+use TYPO3\CMS\Core\Versioning\VersionState;
+
+/**
+ * Resolve and prepare files data.
+ */
+class TcaFiles extends AbstractDatabaseRecordProvider implements FormDataProviderInterface
+{
+    private const FILE_REFERENCE_TABLE = 'sys_file_reference';
+    private const FOREIGN_SELECTOR = 'uid_local';
+
+    public function addData(array $result): array
+    {
+        // inlineFirstPid is currently resolved by TcaInline
+        // @todo check if duplicating the functionality makes sense to resolve dependencies
+
+        foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfig) {
+            if (($fieldConfig['config']['type'] ?? '') !== 'file') {
+                continue;
+            }
+
+            if (!$this->getBackendUser()->check('tables_modify', self::FILE_REFERENCE_TABLE)) {
+                // Early return if user is not allowed to modify the file reference table
+                continue;
+            }
+
+            if (!($GLOBALS['TCA'][self::FILE_REFERENCE_TABLE] ?? false)) {
+                throw new \RuntimeException('Table ' . self::FILE_REFERENCE_TABLE . ' does not exists', 1664364262);
+            }
+
+            $childConfiguration = $GLOBALS['TCA'][self::FILE_REFERENCE_TABLE]['columns'][self::FOREIGN_SELECTOR]['config'] ?? [];
+            if (($childConfiguration['type'] ?? '') !== 'group' || !($childConfiguration['allowed'] ?? false)) {
+                throw new \UnexpectedValueException(
+                    'Table ' . $result['tableName'] . ' field ' . $fieldName . ' points to field '
+                    . self::FOREIGN_SELECTOR . ' of table ' . self::FILE_REFERENCE_TABLE . ', but this field '
+                    . 'is either not defined, is not of type "group" or does not define the "allowed" option.',
+                    1664364263
+                );
+            }
+
+            $result['processedTca']['columns'][$fieldName]['children'] = [];
+
+            $result = $this->initializeMinMaxItems($result, $fieldName);
+            $result = $this->initializeParentSysLanguageUid($result, $fieldName);
+            $result = $this->initializeAppearance($result, $fieldName);
+
+            // If field is set to readOnly, set all fields of the relation to readOnly as well
+            if ($result['inlineParentConfig']['readOnly'] ?? false) {
+                foreach ($result['processedTca']['columns'] as $columnName => $columnConfiguration) {
+                    $result['processedTca']['columns'][$columnName]['config']['readOnly'] = true;
+                }
+            }
+
+            // Resolve existing file references - this is usually always done except on ajax calls
+            if ($result['inlineResolveExistingChildren']) {
+                $result = $this->resolveFileReferences($result, $fieldName);
+                if (!empty($fieldConfig['config']['selectorOrUniqueConfiguration'])) {
+                    throw new \RuntimeException('selectorOrUniqueConfiguration not implemented for TCA type "file"', 1664380909);
+                }
+            }
+        }
+
+        return $result;
+    }
+
+    protected function initializeMinMaxItems(array $result, string $fieldName): array
+    {
+        $config = $result['processedTca']['columns'][$fieldName]['config'];
+        $config['minitems'] = isset($config['minitems']) ? MathUtility::forceIntegerInRange($config['minitems'], 0) : 0;
+        $config['maxitems'] = isset($config['maxitems']) ? MathUtility::forceIntegerInRange($config['maxitems'], 1) : 99999;
+        $result['processedTca']['columns'][$fieldName]['config'] = $config;
+
+        return $result;
+    }
+
+    protected function initializeParentSysLanguageUid(array $result, string $fieldName): array
+    {
+        if (($parentLanguageFieldName = (string)($result['processedTca']['ctrl']['languageField'] ?? '')) === ''
+            || !($GLOBALS['TCA'][self::FILE_REFERENCE_TABLE]['ctrl']['languageField'] ?? false)
+            || isset($result['processedTca']['columns'][$fieldName]['config']['inline']['parentSysLanguageUid'])
+            || !isset($result['databaseRow'][$parentLanguageFieldName])
+        ) {
+            return $result;
+        }
+
+        $result['processedTca']['columns'][$fieldName]['config']['inline']['parentSysLanguageUid'] =
+            is_array($result['databaseRow'][$parentLanguageFieldName])
+                ? (int)($result['databaseRow'][$parentLanguageFieldName][0] ?? 0)
+                : (int)$result['databaseRow'][$parentLanguageFieldName];
+
+        return $result;
+    }
+
+    protected function initializeAppearance(array $result, string $fieldName): array
+    {
+        $result['processedTca']['columns'][$fieldName]['config']['appearance'] = array_replace_recursive(
+            [
+                'useSortable' => true,
+                'headerThumbnail' => [
+                    'height' => '45m',
+                ],
+                'enabledControls' => [
+                    'edit' => true,
+                    'info' => true,
+                    'dragdrop' => true,
+                    'sort' => false,
+                    'hide' => true,
+                    'delete' => true,
+                    'localize' => true,
+                ],
+            ],
+            $result['processedTca']['columns'][$fieldName]['config']['appearance'] ?? []
+        );
+
+        return $result;
+    }
+
+    /**
+     * Substitute the value in databaseRow of this inline field with an array
+     * that contains the databaseRows of currently connected records and some meta information.
+     */
+    protected function resolveFileReferences(array $result, string $fieldName): array
+    {
+        if ($result['defaultLanguageRow'] !== null) {
+            return $this->resolveFileReferenceOverlays($result, $fieldName);
+        }
+
+        $fileReferenceUidsOfDefaultLanguageRecord = $this->resolveFileReferenceUids(
+            $result['processedTca']['columns'][$fieldName]['config'],
+            $result['tableName'],
+            $result['databaseRow']['uid'],
+            $result['databaseRow'][$fieldName]
+        );
+        $result['databaseRow'][$fieldName] = implode(',', $fileReferenceUidsOfDefaultLanguageRecord);
+
+        if ($result['inlineCompileExistingChildren']) {
+            foreach ($this->getSubstitutedWorkspacedUids($fileReferenceUidsOfDefaultLanguageRecord) as $uid) {
+                try {
+                    $compiledFileReference = $this->compileFileReference($result, $fieldName, $uid);
+                    $result['processedTca']['columns'][$fieldName]['children'][] = $compiledFileReference;
+                } catch (DatabaseRecordException $e) {
+                    // Nothing to do here, missing file reference is just not being rendered.
+                }
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * Substitute the value in databaseRow of this file field with an array
+     * that contains the databaseRows of currently connected file references
+     * and some meta information.
+     */
+    protected function resolveFileReferenceOverlays(array $result, string $fieldName): array
+    {
+        $fileReferenceUidsOfLocalizedOverlay = [];
+        $fieldConfig = $result['processedTca']['columns'][$fieldName]['config'];
+        if ($result['command'] === 'edit') {
+            $fileReferenceUidsOfLocalizedOverlay = $this->resolveFileReferenceUids(
+                $fieldConfig,
+                $result['tableName'],
+                $result['databaseRow']['uid'],
+                $result['databaseRow'][$fieldName]
+            );
+        }
+        $result['databaseRow'][$fieldName] = implode(',', $fileReferenceUidsOfLocalizedOverlay);
+        $fileReferenceUidsOfLocalizedOverlay = $this->getSubstitutedWorkspacedUids($fileReferenceUidsOfLocalizedOverlay);
+        if ($result['inlineCompileExistingChildren']) {
+            $tableNameWithDefaultRecords = $result['tableName'];
+            $fileReferenceUidsOfDefaultLanguageRecord = $this->getSubstitutedWorkspacedUids(
+                $this->resolveFileReferenceUids(
+                    $fieldConfig,
+                    $tableNameWithDefaultRecords,
+                    $result['defaultLanguageRow']['uid'],
+                    $result['defaultLanguageRow'][$fieldName]
+                )
+            );
+
+            // Find which records are localized, which records are not localized and which are
+            // localized but miss default language record
+            $fieldNameWithDefaultLanguageUid = (string)($GLOBALS['TCA'][self::FILE_REFERENCE_TABLE]['ctrl']['transOrigPointerField'] ?? '');
+            foreach ($fileReferenceUidsOfLocalizedOverlay as $localizedUid) {
+                try {
+                    $localizedRecord = $this->getRecordFromDatabase(self::FILE_REFERENCE_TABLE, $localizedUid);
+                } catch (DatabaseRecordException $e) {
+                    // The child could not be compiled, probably it was deleted and a dangling mm record exists
+                    $this->logger->warning(
+                        $e->getMessage(),
+                        [
+                            'table' => self::FILE_REFERENCE_TABLE,
+                            'uid' => $localizedUid,
+                            'exception' => $e,
+                        ]
+                    );
+                    continue;
+                }
+                $uidOfDefaultLanguageRecord = (int)$localizedRecord[$fieldNameWithDefaultLanguageUid];
+                if (in_array($uidOfDefaultLanguageRecord, $fileReferenceUidsOfDefaultLanguageRecord, true)) {
+                    // This localized child has a default language record. Remove this record from list of default language records
+                    $fileReferenceUidsOfDefaultLanguageRecord = array_diff($fileReferenceUidsOfDefaultLanguageRecord, [$uidOfDefaultLanguageRecord]);
+                }
+                // Compile localized record
+                $compiledFileReference = $this->compileFileReference($result, $fieldName, $localizedUid);
+                $result['processedTca']['columns'][$fieldName]['children'][] = $compiledFileReference;
+            }
+            if ($fieldConfig['appearance']['showPossibleLocalizationRecords'] ?? false) {
+                foreach ($fileReferenceUidsOfDefaultLanguageRecord as $defaultLanguageUid) {
+                    // If there are still uids in $connectedUidsOfDefaultLanguageRecord, these are records that
+                    // exist in default language, but are not localized yet. Compile and mark those
+                    try {
+                        $compiledFileReference = $this->compileFileReference($result, $fieldName, $defaultLanguageUid);
+                    } catch (DatabaseRecordException $e) {
+                        // The child could not be compiled, probably it was deleted and a dangling mm record exists
+                        $this->logger->warning(
+                            $e->getMessage(),
+                            [
+                                'table' => self::FILE_REFERENCE_TABLE,
+                                'uid' => $defaultLanguageUid,
+                                'exception' => $e,
+                            ]
+                        );
+                        continue;
+                    }
+                    $compiledFileReference['isInlineDefaultLanguageRecordInLocalizedParentContext'] = true;
+                    $result['processedTca']['columns'][$fieldName]['children'][] = $compiledFileReference;
+                }
+            }
+        }
+
+        return $result;
+    }
+
+    protected function compileFileReference(array $result, string $parentFieldName, int $childUid): array
+    {
+        $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
+        $inlineStackProcessor->initializeByGivenStructure($result['inlineStructure']);
+        $inlineTopMostParent = $inlineStackProcessor->getStructureLevel(0) ?: [];
+
+        return GeneralUtility::makeInstance(FormDataCompiler::class, GeneralUtility::makeInstance(TcaDatabaseRecord::class))->compile([
+            'command' => 'edit',
+            'tableName' => self::FILE_REFERENCE_TABLE,
+            'vanillaUid' => $childUid,
+            'returnUrl' => $result['returnUrl'],
+            'isInlineChild' => true,
+            'inlineStructure' => $result['inlineStructure'],
+            'inlineExpandCollapseStateArray' => $result['inlineExpandCollapseStateArray'],
+            'inlineFirstPid' => $result['inlineFirstPid'],
+            'inlineParentConfig' => $result['processedTca']['columns'][$parentFieldName]['config'],
+            'inlineParentUid' => $result['databaseRow']['uid'],
+            'inlineParentTableName' => $result['tableName'],
+            'inlineParentFieldName' => $parentFieldName,
+            'inlineTopMostParentUid' => $result['inlineTopMostParentUid'] ?: $inlineTopMostParent['uid'] ?? '',
+            'inlineTopMostParentTableName' => $result['inlineTopMostParentTableName'] ?: $inlineTopMostParent['table'] ?? '',
+            'inlineTopMostParentFieldName' => $result['inlineTopMostParentFieldName'] ?: $inlineTopMostParent['field'] ?? '',
+        ]);
+    }
+
+    /**
+     * Substitute given list of uids with corresponding workspace uids - if needed
+     *
+     * @param int[] $connectedUids List of file reference uids
+     * @return int[] List of substituted uids
+     */
+    protected function getSubstitutedWorkspacedUids(array $connectedUids): array
+    {
+        $workspace = $this->getBackendUser()->workspace;
+        if ($workspace === 0 || !BackendUtility::isTableWorkspaceEnabled(self::FILE_REFERENCE_TABLE)) {
+            return $connectedUids;
+        }
+
+        $substitutedUids = [];
+        foreach ($connectedUids as $uid) {
+            $workspaceVersion = BackendUtility::getWorkspaceVersionOfRecord(
+                $workspace,
+                self::FILE_REFERENCE_TABLE,
+                $uid,
+                'uid,t3ver_state'
+            );
+            if (!empty($workspaceVersion)) {
+                $versionState = VersionState::cast($workspaceVersion['t3ver_state']);
+                if ($versionState->equals(VersionState::DELETE_PLACEHOLDER)) {
+                    continue;
+                }
+                $uid = $workspaceVersion['uid'];
+            }
+            $substitutedUids[] = (int)$uid;
+        }
+        return $substitutedUids;
+    }
+
+    /**
+     * Resolve file reference uids using the RelationHandler
+     *
+     * @return int[]
+     */
+    protected function resolveFileReferenceUids(
+        array $parentConfig,
+        $parentTableName,
+        $parentUid,
+        $parentFieldValue
+    ): array {
+        $relationHandler = GeneralUtility::makeInstance(RelationHandler::class);
+        $relationHandler->start(
+            $parentFieldValue,
+            self::FILE_REFERENCE_TABLE,
+            '',
+            BackendUtility::getLiveVersionIdOfRecord($parentTableName, $parentUid) ?? $parentUid,
+            $parentTableName,
+            $parentConfig
+        );
+        return array_map('intval', $relationHandler->getValueArray());
+    }
+
+    protected function getBackendUser(): BackendUserAuthentication
+    {
+        return $GLOBALS['BE_USER'];
+    }
+
+    protected function getLanguageService(): LanguageService
+    {
+        return $GLOBALS['LANG'];
+    }
+}
diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php
index 210b40ebd1bc..e2972e63913d 100644
--- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php
+++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php
@@ -153,6 +153,11 @@ class TcaFlexPrepare implements FormDataProviderInterface
     /**
      * Recursively migrate flex form TCA
      *
+     * @todo This is already partially done in FlexFormTools and should be harmonized. Therefore,
+     *       all migration / preparation should go into FlexFormTools, because DataHandler also
+     *       needs the migrated / prepared config and does not call this FormEngine specific
+     *       FormDataProvider.
+     *
      * @param array $structure Given hierarchy
      * @param string $table
      * @param string $fieldName
diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexProcess.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexProcess.php
index f0bb1db2866b..ba1a33de45e6 100644
--- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexProcess.php
+++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexProcess.php
@@ -99,13 +99,23 @@ class TcaFlexProcess implements FormDataProviderInterface
                             if (isset($containerConfiguration['el']) && is_array($containerConfiguration['el'])) {
                                 foreach ($containerConfiguration['el'] as $singleFieldName => $singleFieldConfiguration) {
                                     // Nesting type=inline in container sections is not supported. Throw an exception if configured.
-                                    if (isset($singleFieldConfiguration['config']['type']) && $singleFieldConfiguration['config']['type'] === 'inline') {
-                                        throw new \UnexpectedValueException(
-                                            'Invalid flex form data structure on field name "' . $fieldName . '" with element "' . $singleFieldName . '"'
-                                            . ' in section container "' . $containerName . '": Nesting inline elements in flex form'
-                                            . ' sections is not allowed.',
-                                            1458745468
-                                        );
+                                    if (isset($singleFieldConfiguration['config']['type'])) {
+                                        if ($singleFieldConfiguration['config']['type'] === 'inline') {
+                                            throw new \UnexpectedValueException(
+                                                'Invalid flex form data structure on field name "' . $fieldName . '" with element "' . $singleFieldName . '"'
+                                                . ' in section container "' . $containerName . '": Nesting inline elements in flex form'
+                                                . ' sections is not allowed.',
+                                                1458745468
+                                            );
+                                        }
+                                        if ($singleFieldConfiguration['config']['type'] === 'file') {
+                                            throw new \UnexpectedValueException(
+                                                'Invalid flex form data structure on field name "' . $fieldName . '" with element "' . $singleFieldName . '"'
+                                                . ' in section container "' . $containerName . '": Nesting file elements in flex form'
+                                                . ' sections is not allowed.',
+                                                1664473929
+                                            );
+                                        }
                                     }
 
                                     // Nesting sections is not supported. Throw an exception if configured.
diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInline.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInline.php
index 4a91cc870ab4..673fba181077 100644
--- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInline.php
+++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInline.php
@@ -457,7 +457,6 @@ class TcaInline extends AbstractDatabaseRecordProvider implements FormDataProvid
             $parentUid = $this->getLiveDefaultId($parentTableName, $parentUid);
         }
         $relationHandler = GeneralUtility::makeInstance(RelationHandler::class);
-        $relationHandler->registerNonTableValues = (bool)($parentConfig['allowedIdValues'] ?? false);
         $relationHandler->start($parentFieldValue, $parentConfig['foreign_table'] ?? '', $parentConfig['MM'] ?? '', $parentUid, $parentTableName, $parentConfig);
         $foreignRecordUids = $relationHandler->getValueArray();
         $resolvedForeignRecordUids = [];
diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInputPlaceholders.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInputPlaceholders.php
index aedad2f6ed10..583d7b81e60d 100644
--- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInputPlaceholders.php
+++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInputPlaceholders.php
@@ -127,6 +127,7 @@ class TcaInputPlaceholders implements FormDataProviderInterface
                 $foreignTableName = $this->getAllowedTableForGroupField($fieldConfig);
                 break;
             case 'inline':
+            case 'file':
                 $possibleUids = array_filter(GeneralUtility::trimExplode(',', $value, true));
                 $foreignTableName = $fieldConfig['foreign_table'];
                 break;
diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaRecordTitle.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaRecordTitle.php
index ef6a74828250..1673ecc9ed00 100644
--- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaRecordTitle.php
+++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaRecordTitle.php
@@ -156,6 +156,7 @@ class TcaRecordTitle implements FormDataProviderInterface
                 $recordTitle = $this->getRecordTitleForRadioType($rawValue, $fieldConfig);
                 break;
             case 'inline':
+            case 'file':
                 $recordTitle = $this->getRecordTitleForInlineType(
                     $rawValue,
                     $result['processedTca']['columns'][$fieldName]['children']
diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSiteLanguage.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSiteLanguage.php
index aafee70c532b..075185acffd2 100644
--- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSiteLanguage.php
+++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSiteLanguage.php
@@ -108,7 +108,7 @@ class TcaSiteLanguage extends AbstractDatabaseRecordProvider implements FormData
         }
         $config['appearance']['showPossibleLocalizationRecords'] = false;
         $config['appearance']['collapseAll'] = true;
-        $config['appearance']['expandSignle'] = false;
+        $config['appearance']['expandSingle'] = false;
         $config['appearance']['enabledControls'] = [
             'info' => false,
             'new' => false,
diff --git a/typo3/sysext/backend/Classes/Form/NodeFactory.php b/typo3/sysext/backend/Classes/Form/NodeFactory.php
index c8de41c4a307..92bdadbd402c 100644
--- a/typo3/sysext/backend/Classes/Form/NodeFactory.php
+++ b/typo3/sysext/backend/Classes/Form/NodeFactory.php
@@ -15,6 +15,7 @@
 
 namespace TYPO3\CMS\Backend\Form;
 
+use TYPO3\CMS\Backend\Form\Container\FilesControlContainer;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -58,8 +59,10 @@ class NodeFactory
         'flexFormTabsContainer' => Container\FlexFormTabsContainer::class,
         'fullRecordContainer' => Container\FullRecordContainer::class,
         'inline' => Container\InlineControlContainer::class,
-        'siteLanguage' => Container\SiteLanguageContainer::class,
         'inlineRecordContainer' => Container\InlineRecordContainer::class,
+        FilesControlContainer::NODE_TYPE_IDENTIFIER => Container\FilesControlContainer::class,
+        Container\FileReferenceContainer::NODE_TYPE_IDENTIFIER => Container\FileReferenceContainer::class,
+        'siteLanguage' => Container\SiteLanguageContainer::class,
         'listOfFieldsContainer' => Container\ListOfFieldsContainer::class,
         'noTabsContainer' => Container\NoTabsContainer::class,
         'outerWrapContainer' => Container\OuterWrapContainer::class,
diff --git a/typo3/sysext/backend/Classes/Form/Utility/FormEngineUtility.php b/typo3/sysext/backend/Classes/Form/Utility/FormEngineUtility.php
index 057a7a7d28dc..bd962e305013 100644
--- a/typo3/sysext/backend/Classes/Form/Utility/FormEngineUtility.php
+++ b/typo3/sysext/backend/Classes/Form/Utility/FormEngineUtility.php
@@ -57,6 +57,7 @@ class FormEngineUtility
         'group' => ['size', 'autoSizeMax', 'maxitems', 'minitems', 'readOnly', 'elementBrowserEntryPoints'],
         'folder' => ['size', 'autoSizeMax', 'maxitems', 'minitems', 'readOnly', 'elementBrowserEntryPoints'],
         'inline' => ['appearance', 'behaviour', 'foreign_label', 'foreign_selector', 'foreign_unique', 'maxitems', 'minitems', 'size', 'autoSizeMax', 'symmetric_label', 'readOnly'],
+        'file' => ['appearance', 'behaviour', 'maxitems', 'minitems', 'readOnly'],
         'imageManipulation' => ['ratios', 'cropVariants'],
     ];
 
diff --git a/typo3/sysext/backend/Classes/RecordList/ElementBrowserRecordList.php b/typo3/sysext/backend/Classes/RecordList/ElementBrowserRecordList.php
index aca436be6fcf..35fd3585d1b6 100644
--- a/typo3/sysext/backend/Classes/RecordList/ElementBrowserRecordList.php
+++ b/typo3/sysext/backend/Classes/RecordList/ElementBrowserRecordList.php
@@ -17,6 +17,7 @@ namespace TYPO3\CMS\Backend\RecordList;
 
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Imaging\Icon;
+use TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -92,6 +93,17 @@ class ElementBrowserRecordList extends DatabaseRecordList
                     }
                 }
             }
+            if (($tcaFieldConfig['type'] ?? '') === 'file') {
+                $valueArray = GeneralUtility::makeInstance(FileExtensionFilter::class)->filter(
+                    [$table . '_' . $row['uid']],
+                    (string)($tcaFieldConfig['allowed'] ?? ''),
+                    (string)($tcaFieldConfig['disallowed'] ?? ''),
+                    $this
+                );
+                if (empty($valueArray)) {
+                    $returnValue = false;
+                }
+            }
         }
         return $returnValue;
     }
diff --git a/typo3/sysext/backend/Classes/Utility/BackendUtility.php b/typo3/sysext/backend/Classes/Utility/BackendUtility.php
index ffd2b34b675e..cf04665c9850 100644
--- a/typo3/sysext/backend/Classes/Utility/BackendUtility.php
+++ b/typo3/sysext/backend/Classes/Utility/BackendUtility.php
@@ -914,9 +914,7 @@ class BackendUtility
             return null;
         }
         $configuration = $GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config'];
-        if (empty($configuration['type']) || $configuration['type'] !== 'inline'
-            || empty($configuration['foreign_table']) || $configuration['foreign_table'] !== 'sys_file_reference'
-        ) {
+        if (($configuration['type'] ?? '') !== 'file') {
             return null;
         }
 
@@ -1554,6 +1552,7 @@ class BackendUtility
                 $l = $lang->sL($l);
                 break;
             case 'inline':
+            case 'file':
                 if ($uid) {
                     $finalValues = static::resolveRelationLabels($theColConf, $table, $uid, $value, $noRecordLookup);
                     $l = implode(', ', $finalValues);
diff --git a/typo3/sysext/backend/Configuration/Backend/AjaxRoutes.php b/typo3/sysext/backend/Configuration/Backend/AjaxRoutes.php
index 97fddae3bdba..3fbb138a86bf 100644
--- a/typo3/sysext/backend/Configuration/Backend/AjaxRoutes.php
+++ b/typo3/sysext/backend/Configuration/Backend/AjaxRoutes.php
@@ -23,6 +23,33 @@ return [
         'target' => Controller\File\FileController::class . '::fileExistsInFolderAction',
     ],
 
+    // Get details of a file reference in FormEngine
+    'file_reference_details' => [
+        'path' => '/file/reference/details',
+        'target' => Controller\FormFilesAjaxController::class . '::detailsAction',
+    ],
+
+    // Create a new file reference in FormEngine
+    'file_reference_create' => [
+        'path' => '/file/reference/create',
+        'methods' => ['POST'],
+        'target' => Controller\FormFilesAjaxController::class . '::createAction',
+    ],
+
+    // Synchronize localization of a file reference in FormEngine
+    'file_reference_synchronizelocalize' => [
+        'path' => '/file/reference/synchronizelocalize',
+        'methods' => ['POST'],
+        'target' => Controller\FormFilesAjaxController::class . '::synchronizeLocalizeAction',
+    ],
+
+    // Expand / Collapse a file reference in FormEngine
+    'file_reference_expandcollapse' => [
+        'path' => '/file/reference/expandcollapse',
+        'methods' => ['POST'],
+        'target' => Controller\FormFilesAjaxController::class . '::expandOrCollapseAction',
+    ],
+
     // Get record details of a child record in IRRE
     'record_inline_details' => [
         'path' => '/record/inline/details',
diff --git a/typo3/sysext/backend/Configuration/Services.yaml b/typo3/sysext/backend/Configuration/Services.yaml
index 13ece77f5b5e..7c57fbccb53b 100644
--- a/typo3/sysext/backend/Configuration/Services.yaml
+++ b/typo3/sysext/backend/Configuration/Services.yaml
@@ -95,6 +95,9 @@ services:
   TYPO3\CMS\Backend\Controller\ElementBrowserController:
     tags: ['backend.controller']
 
+  TYPO3\CMS\Backend\Controller\FormFilesAjaxController:
+    tags: ['backend.controller']
+
   TYPO3\CMS\Backend\Controller\FormSlugAjaxController:
     tags: ['backend.controller']
 
diff --git a/typo3/sysext/backend/Resources/Private/Templates/Form/FilesControlContainer.html b/typo3/sysext/backend/Resources/Private/Templates/Form/FilesControlContainer.html
new file mode 100644
index 000000000000..4f9c92b7236c
--- /dev/null
+++ b/typo3/sysext/backend/Resources/Private/Templates/Form/FilesControlContainer.html
@@ -0,0 +1,52 @@
+<html
+    xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
+    xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers"
+    data-namespace-typo3-fluid="true"
+>
+<typo3-formengine-container-files identifier="{formFieldIdentifier}">
+    <div {formGroupAttributes -> f:format.raw()}>
+        <f:format.raw>{fieldInformation}</f:format.raw>
+        <div class="form-group t3js-formengine-validation-marker">
+            <div class="form-control-wrap t3js-file-controls">
+                <f:for each="{fileSelectors}" as="fileSelector">
+                    {fileSelector -> f:format.raw()}
+                </f:for>
+            </div>
+            <f:if condition="{allowedFileTypes}">
+                <div class="help-block">
+                    <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:cm.allowedFileExtensions"/><br>
+                    <f:for each="{allowedFileTypes}" as="allowedFileType">
+                        <span class="badge badge-success">{allowedFileType}</span>
+                    </f:for>
+                </div>
+            </f:if>
+        </div>
+        <f:if condition="{showAllLocalizationLink}">
+            <div class="typo3-localizationLink" title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:localizeAllRecords')}">
+                <button type="button" class="btn btn-default t3js-synchronizelocalize-button" data-type="localize">
+                    <core:icon identifier="actions-document-localize" size="small" />
+                    <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:localizeAllRecords" />
+                </button>
+            </div>
+        </f:if>
+        <f:if condition="{showSynchronizationLink}">
+            <div class="typo3-synchronizationLink" title="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:synchronizeWithOriginalLanguage')}">
+                <button type="button" class="btn btn-default t3js-synchronizelocalize-button" data-type="synchronize">
+                    <core:icon identifier="actions-document-synchronize" size="small" />
+                    <f:translate key="LLL:EXT:core/Resources/Private/Language/locallang_misc.xlf:synchronizeWithOriginalLanguage" />
+                </button>
+            </div>
+        </f:if>
+        <div class="panel-group panel-hover {f:if(condition: '{showAllLocalizationLink} || {showSynchronizationLink}', then: 'mt-3')}" id="{fileReferences.id}" data-title="{fileReferences.title}">
+            <f:format.raw>{fileReferences.records}</f:format.raw>
+        </div>
+        <f:format.raw>{fieldWizard}</f:format.raw>
+        <f:if condition="{customControls}">
+            <div id="{customControls.id}">
+                <f:format.raw>{customControls.controls}</f:format.raw>
+            </div>
+        </f:if>
+        <input type="hidden" class="inlineRecord" name="{formFieldName}" value="{sortableRecordUids}" data-formengine-validation-rules="{validationRules}" />
+    </div>
+</typo3-formengine-container-files>
+</html>
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/form-engine-validation.js b/typo3/sysext/backend/Resources/Public/JavaScript/form-engine-validation.js
index 8ca52deb0a70..bd80d9853a4a 100644
--- a/typo3/sysext/backend/Resources/Public/JavaScript/form-engine-validation.js
+++ b/typo3/sysext/backend/Resources/Public/JavaScript/form-engine-validation.js
@@ -10,4 +10,4 @@
  *
  * The TYPO3 project - inspiring people to share!
  */
-import $ from"jquery";import moment from"moment";import Md5 from"@typo3/backend/hashing/md5.js";import DocumentSaveActions from"@typo3/backend/document-save-actions.js";import Modal from"@typo3/backend/modal.js";import Severity from"@typo3/backend/severity.js";export default(function(){const FormEngineValidation={rulesSelector:"[data-formengine-validation-rules]",inputSelector:"[data-formengine-input-params]",markerSelector:".t3js-formengine-validation-marker",groupFieldHiddenElement:".t3js-formengine-field-group input[type=hidden]",relatedFieldSelector:"[data-relatedfieldname]",errorClass:"has-error",lastYear:0,lastDate:0,lastTime:0,passwordDummy:"********"},customEvaluations=new Map;return FormEngineValidation.initialize=function(){$(document).find("."+FormEngineValidation.errorClass).removeClass(FormEngineValidation.errorClass),FormEngineValidation.initializeInputFields().promise().done((function(){$(document).on("change",FormEngineValidation.rulesSelector,(e=>{FormEngineValidation.validateField(e.currentTarget),FormEngineValidation.markFieldAsChanged(e.currentTarget)})),FormEngineValidation.registerSubmitCallback()}));const e=new Date;FormEngineValidation.lastYear=FormEngineValidation.getYear(e),FormEngineValidation.lastDate=FormEngineValidation.getDate(e),FormEngineValidation.lastTime=0,FormEngineValidation.validate()},FormEngineValidation.initializeInputFields=function(){return $(document).find(FormEngineValidation.inputSelector).each((function(e,n){const t=$(n).data("formengine-input-params"),a=t.field,i=$('[name="'+a+'"]');void 0===i.data("main-field")&&(i.data("main-field",a),i.data("config",t),FormEngineValidation.initializeInputField(a))}))},FormEngineValidation.initializeInputField=function(e){const n=$('[name="'+e+'"]'),t=$('[data-formengine-input-name="'+e+'"]');let a=$('[name="'+n.data("main-field")+'"]');0===a.length&&(a=n);const i=a.data("config");if(void 0!==i){const e=FormEngineValidation.trimExplode(",",i.evalList);let a=n.val();for(let n=0;n<e.length;n++)a=FormEngineValidation.formatValue(e[n],a,i);a.length&&t.val(a)}t.data("main-field",e),t.data("config",i),t.on("change",(function(){FormEngineValidation.updateInputField(t.attr("data-formengine-input-name"))})),t.attr("data-formengine-input-initialized","true")},FormEngineValidation.registerCustomEvaluation=function(e,n){customEvaluations.has(e)||customEvaluations.set(e,n)},FormEngineValidation.formatValue=function(e,n,t){let a,i,o="";switch(e){case"date":if(n.toString().indexOf("-")>0){o=moment.utc(n).format("DD-MM-YYYY")}else{if(a=1*n,!a)return"";i=new Date(1e3*a);o=i.getUTCDate().toString(10).padStart(2,"0")+"-"+(i.getUTCMonth()+1).toString(10).padStart(2,"0")+"-"+this.getYear(i)}break;case"datetime":if(n.toString().indexOf("-")<=0&&!("number"==typeof n?n:parseInt(n)))return"";o=FormEngineValidation.formatValue("time",n,t)+" "+FormEngineValidation.formatValue("date",n,t);break;case"time":case"timesec":let r;if(n.toString().indexOf("-")>0)r=moment.utc(n);else{if(a="number"==typeof n?n:parseInt(n),!a&&"0"!==n.toString())return"";r=moment.unix(a).utc()}o="timesec"===e?r.format("HH:mm:ss"):r.format("HH:mm");break;case"password":o=n?FormEngineValidation.passwordDummy:"";break;default:o=n}return o},FormEngineValidation.updateInputField=function(e){const n=$('[name="'+e+'"]');let t=$('[name="'+n.data("main-field")+'"]');0===t.length&&(t=n);const a=$('[data-formengine-input-name="'+t.attr("name")+'"]'),i=t.data("config");if(void 0!==i){const e=FormEngineValidation.trimExplode(",",i.evalList);let n=a.val();for(let t=0;t<e.length;t++)n=FormEngineValidation.processValue(e[t],n,i);let o=n;for(let n=0;n<e.length;n++)o=FormEngineValidation.formatValue(e[n],o,i);t.val(n),t.get(0).dispatchEvent(new Event("change")),a.val(o)}},FormEngineValidation.validateField=function(e,n){const t=e instanceof $?e.get(0):e;if(n=n||t.value||"",void 0===t.dataset.formengineValidationRules)return n;const a=JSON.parse(t.dataset.formengineValidationRules);let i,o,r,l=!1,s=0,m=n;$.isArray(n)||(n=FormEngineValidation.ltrim(n)),$.each(a,(function(e,a){if(l)return!1;switch(a.type){case"required":""===n&&(l=!0,t.closest(FormEngineValidation.markerSelector).classList.add(FormEngineValidation.errorClass));break;case"range":if(""!==n){if((a.minItems||a.maxItems)&&(i=$(document).find('[name="'+t.dataset.relatedfieldname+'"]'),s=i.length?FormEngineValidation.trimExplode(",",i.val()).length:t.value,void 0!==a.minItems&&(o=1*a.minItems,!isNaN(o)&&s<o&&(l=!0)),void 0!==a.maxItems&&(r=1*a.maxItems,!isNaN(r)&&s>r&&(l=!0))),void 0!==a.lower){const e=1*a.lower;!isNaN(e)&&n<e&&(l=!0)}if(void 0!==a.upper){const e=1*a.upper;!isNaN(e)&&n>e&&(l=!0)}}break;case"select":case"category":(a.minItems||a.maxItems)&&(i=$(document).find('[name="'+t.dataset.relatedfieldname+'"]'),s=i.length?FormEngineValidation.trimExplode(",",i.val()).length:t instanceof HTMLSelectElement?t.querySelectorAll("option:checked").length:t.querySelectorAll("input[value]:checked").length,void 0!==a.minItems&&(o=1*a.minItems,!isNaN(o)&&s<o&&(l=!0)),void 0!==a.maxItems&&(r=1*a.maxItems,!isNaN(r)&&s>r&&(l=!0)));break;case"group":case"inline":(a.minItems||a.maxItems)&&(s=FormEngineValidation.trimExplode(",",t.value).length,void 0!==a.minItems&&(o=1*a.minItems,!isNaN(o)&&s<o&&(l=!0)),void 0!==a.maxItems&&(r=1*a.maxItems,!isNaN(r)&&s>r&&(l=!0)));break;case"min":(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement)&&t.value.length>0&&t.value.length<t.minLength&&(l=!0)}}));const d=!l,g=t.closest(FormEngineValidation.markerSelector);return null!==g&&g.classList.toggle(FormEngineValidation.errorClass,!d),FormEngineValidation.markParentTab($(t),d),$(document).trigger("t3-formengine-postfieldvalidation"),m},FormEngineValidation.processValue=function(e,n,t){let a="",i="",o="",r=0,l=n;switch(e){case"alpha":case"num":case"alphanum":case"alphanum_x":for(a="",r=0;r<n.length;r++){const t=n.substr(r,1);let i="_"===t||"-"===t,o=t>="a"&&t<="z"||t>="A"&&t<="Z",l=t>="0"&&t<="9";switch(e){case"alphanum":i=!1;break;case"alpha":l=!1,i=!1;break;case"num":o=!1,i=!1}(o||l||i)&&(a+=t)}a!==n&&(l=a);break;case"is_in":if(t.is_in){i=""+n,t.is_in=t.is_in.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&");const e=new RegExp("[^"+t.is_in+"]+","g");a=i.replace(e,"")}else a=i;l=a;break;case"nospace":l=(""+n).replace(/ /g,"");break;case"md5":""!==n&&(l=Md5.hash(n));break;case"upper":l=n.toUpperCase();break;case"lower":l=n.toLowerCase();break;case"integer":""!==n&&(l=FormEngineValidation.parseInt(n));break;case"decimal":""!==n&&(l=FormEngineValidation.parseDouble(n));break;case"trim":l=String(n).trim();break;case"datetime":""!==n&&(o=n.substr(0,1),l=FormEngineValidation.parseDateTime(n));break;case"date":""!==n&&(o=n.substr(0,1),l=FormEngineValidation.parseDate(n));break;case"time":case"timesec":""!==n&&(o=n.substr(0,1),l=FormEngineValidation.parseTime(n,e));break;case"year":""!==n&&(o=n.substr(0,1),l=FormEngineValidation.parseYear(n));break;case"null":case"password":break;default:customEvaluations.has(e)?l=customEvaluations.get(e).call(null,n):"object"==typeof TBE_EDITOR&&void 0!==TBE_EDITOR.customEvalFunctions&&"function"==typeof TBE_EDITOR.customEvalFunctions[e]&&(l=TBE_EDITOR.customEvalFunctions[e](n))}return l},FormEngineValidation.validate=function(e){(void 0===e||e instanceof Document)&&$(document).find(FormEngineValidation.markerSelector+", .t3js-tabmenu-item").removeClass(FormEngineValidation.errorClass).removeClass("has-validation-error");const n=e||document;$(n).find(FormEngineValidation.rulesSelector).each(((e,n)=>{const t=$(n);if(!t.closest(".t3js-flex-section-deleted, .t3js-inline-record-deleted").length){let e=!1;const n=t.val(),a=FormEngineValidation.validateField(t,n);if($.isArray(a)&&$.isArray(n)){if(a.length!==n.length)e=!0;else for(let t=0;t<a.length;t++)if(a[t]!==n[t]){e=!0;break}}else a.length&&n!==a&&(e=!0);e&&t.val(a)}}))},FormEngineValidation.markFieldAsChanged=function(e){if(e instanceof $&&(e=e.get(0)),!(e instanceof HTMLElement))return;const n=e.closest(".t3js-formengine-palette-field");null!==n&&n.classList.add("has-change")},FormEngineValidation.trimExplode=function(e,n){const t=[],a=n.split(e);for(let e=0;e<a.length;e++){const n=a[e].trim();n.length>0&&t.push(n)}return t},FormEngineValidation.parseInt=function(e){let n;return e?(n=parseInt(""+e,10),isNaN(n)?0:n):0},FormEngineValidation.parseDouble=function(e,n=2){let t=""+e;t=t.replace(/[^0-9,\.-]/g,"");const a="-"===t.substring(0,1);t=t.replace(/-/g,""),t=t.replace(/,/g,"."),-1===t.indexOf(".")&&(t+=".0");const i=t.split("."),o=i.pop();let r=Number(i.join("")+"."+o);return a&&(r*=-1),t=r.toFixed(n),t},FormEngineValidation.ltrim=function(e){return e?(""+e).replace(/^\s+/,""):""},FormEngineValidation.btrim=function(e){return e?(""+e).replace(/\s+$/,""):""},FormEngineValidation.parseDateTime=function(e){const n=e.indexOf(" ");if(-1!==n){const t=FormEngineValidation.parseDate(e.substr(n,e.length));FormEngineValidation.lastTime=t+FormEngineValidation.parseTime(e.substr(0,n),"time")}else FormEngineValidation.lastTime=FormEngineValidation.parseDate(e);return FormEngineValidation.lastTime},FormEngineValidation.parseDate=function(e){const n=new Date;let t=FormEngineValidation.split(e);if(t.values[1]&&t.values[1].length>2){const e=t.values[1];t=FormEngineValidation.splitSingle(e)}const a=t.values[3]?FormEngineValidation.parseInt(t.values[3]):FormEngineValidation.getYear(n),i=t.values[2]?FormEngineValidation.parseInt(t.values[2]):n.getUTCMonth()+1,o=t.values[1]?FormEngineValidation.parseInt(t.values[1]):n.getUTCDate(),r=moment.utc();return r.year(parseInt(a)).month(parseInt(i)-1).date(parseInt(o)).hour(0).minute(0).second(0),FormEngineValidation.lastDate=r.unix(),FormEngineValidation.lastDate},FormEngineValidation.parseTime=function(e,n){const t=new Date;let a=FormEngineValidation.split(e);if(a.values[1]&&a.values[1].length>2){const e=a.values[1];a=FormEngineValidation.splitSingle(e)}const i=a.values[3]?FormEngineValidation.parseInt(a.values[3]):t.getUTCSeconds(),o=a.values[2]?FormEngineValidation.parseInt(a.values[2]):t.getUTCMinutes(),r=a.values[1]?FormEngineValidation.parseInt(a.values[1]):t.getUTCHours(),l=moment.utc();return l.year(1970).month(0).date(1).hour(r).minute(o).second("timesec"===n?i:0),FormEngineValidation.lastTime=l.unix(),FormEngineValidation.lastTime<0&&(FormEngineValidation.lastTime+=86400),FormEngineValidation.lastTime},FormEngineValidation.parseYear=function(e){const n=new Date,t=FormEngineValidation.split(e);return FormEngineValidation.lastYear=t.values[1]?FormEngineValidation.parseInt(t.values[1]):FormEngineValidation.getYear(n),FormEngineValidation.lastYear},FormEngineValidation.getYear=function(e){return null===e?null:e.getUTCFullYear()},FormEngineValidation.getDate=function(e){const n=new Date(FormEngineValidation.getYear(e),e.getUTCMonth(),e.getUTCDate());return FormEngineValidation.getTimestamp(n)},FormEngineValidation.pol=function(foreign,value){return eval(("-"==foreign?"-":"")+value)},FormEngineValidation.convertClientTimestampToUTC=function(e,n){const t=new Date(1e3*e);return t.setTime(1e3*(e-60*t.getTimezoneOffset())),n?FormEngineValidation.getTime(t):FormEngineValidation.getTimestamp(t)},FormEngineValidation.getTimestamp=function(e){return Date.parse(e instanceof Date?e.toISOString():e)/1e3},FormEngineValidation.getTime=function(e){return 60*e.getUTCHours()*60+60*e.getUTCMinutes()+FormEngineValidation.getSecs(e)},FormEngineValidation.getSecs=function(e){return e.getUTCSeconds()},FormEngineValidation.getTimeSecs=function(e){return 60*e.getHours()*60+60*e.getMinutes()+e.getSeconds()},FormEngineValidation.markParentTab=function(e,n){e.parents(".tab-pane").each((function(e,t){const a=$(t);n&&(n=0===a.find(".has-error").length);const i=a.attr("id");$(document).find('a[href="#'+i+'"]').closest(".t3js-tabmenu-item").toggleClass("has-validation-error",!n)}))},FormEngineValidation.splitSingle=function(e){const n=""+e,t={values:[],pointer:3};return t.values[1]=n.substr(0,2),t.values[2]=n.substr(2,2),t.values[3]=n.substr(4,10),t},FormEngineValidation.splitStr=function(e,n,t){const a=""+e,i=n.length;let o=-i;t<1&&(t=1);for(let e=1;e<t;e++)if(o=a.indexOf(n,o+i),-1==o)return null;let r=a.indexOf(n,o+i);return-1==r&&(r=a.length),a.substring(o+i,r)},FormEngineValidation.split=function(e){const n={values:[],valPol:[],pointer:0,numberMode:0,theVal:""};e+=" ";for(let t=0;t<e.length;t++){const a=e.substr(t,1);a<"0"||a>"9"?(n.numberMode&&(n.pointer++,n.values[n.pointer]=n.theVal,n.theVal="",n.numberMode=0),"+"!=a&&"-"!=a||(n.valPol[n.pointer+1]=a)):(n.theVal+=a,n.numberMode=1)}return n},FormEngineValidation.registerSubmitCallback=function(){DocumentSaveActions.getInstance().addPreSubmitCallback((function(e){if($("."+FormEngineValidation.errorClass).length>0){const n=Modal.confirm(TYPO3.lang.alert||"Alert",TYPO3.lang["FormEngine.fieldsMissing"],Severity.error,[{text:TYPO3.lang["button.ok"]||"OK",active:!0,btnClass:"btn-default",name:"ok"}]);n.addEventListener("button.clicked",(()=>n.hideModal())),e.stopImmediatePropagation()}}))},FormEngineValidation}());
\ No newline at end of file
+import $ from"jquery";import moment from"moment";import Md5 from"@typo3/backend/hashing/md5.js";import DocumentSaveActions from"@typo3/backend/document-save-actions.js";import Modal from"@typo3/backend/modal.js";import Severity from"@typo3/backend/severity.js";export default(function(){const FormEngineValidation={rulesSelector:"[data-formengine-validation-rules]",inputSelector:"[data-formengine-input-params]",markerSelector:".t3js-formengine-validation-marker",groupFieldHiddenElement:".t3js-formengine-field-group input[type=hidden]",relatedFieldSelector:"[data-relatedfieldname]",errorClass:"has-error",lastYear:0,lastDate:0,lastTime:0,passwordDummy:"********"},customEvaluations=new Map;return FormEngineValidation.initialize=function(){$(document).find("."+FormEngineValidation.errorClass).removeClass(FormEngineValidation.errorClass),FormEngineValidation.initializeInputFields().promise().done((function(){$(document).on("change",FormEngineValidation.rulesSelector,(e=>{FormEngineValidation.validateField(e.currentTarget),FormEngineValidation.markFieldAsChanged(e.currentTarget)})),FormEngineValidation.registerSubmitCallback()}));const e=new Date;FormEngineValidation.lastYear=FormEngineValidation.getYear(e),FormEngineValidation.lastDate=FormEngineValidation.getDate(e),FormEngineValidation.lastTime=0,FormEngineValidation.validate()},FormEngineValidation.initializeInputFields=function(){return $(document).find(FormEngineValidation.inputSelector).each((function(e,n){const t=$(n).data("formengine-input-params"),a=t.field,i=$('[name="'+a+'"]');void 0===i.data("main-field")&&(i.data("main-field",a),i.data("config",t),FormEngineValidation.initializeInputField(a))}))},FormEngineValidation.initializeInputField=function(e){const n=$('[name="'+e+'"]'),t=$('[data-formengine-input-name="'+e+'"]');let a=$('[name="'+n.data("main-field")+'"]');0===a.length&&(a=n);const i=a.data("config");if(void 0!==i){const e=FormEngineValidation.trimExplode(",",i.evalList);let a=n.val();for(let n=0;n<e.length;n++)a=FormEngineValidation.formatValue(e[n],a,i);a.length&&t.val(a)}t.data("main-field",e),t.data("config",i),t.on("change",(function(){FormEngineValidation.updateInputField(t.attr("data-formengine-input-name"))})),t.attr("data-formengine-input-initialized","true")},FormEngineValidation.registerCustomEvaluation=function(e,n){customEvaluations.has(e)||customEvaluations.set(e,n)},FormEngineValidation.formatValue=function(e,n,t){let a,i,o="";switch(e){case"date":if(n.toString().indexOf("-")>0){o=moment.utc(n).format("DD-MM-YYYY")}else{if(a=1*n,!a)return"";i=new Date(1e3*a);o=i.getUTCDate().toString(10).padStart(2,"0")+"-"+(i.getUTCMonth()+1).toString(10).padStart(2,"0")+"-"+this.getYear(i)}break;case"datetime":if(n.toString().indexOf("-")<=0&&!("number"==typeof n?n:parseInt(n)))return"";o=FormEngineValidation.formatValue("time",n,t)+" "+FormEngineValidation.formatValue("date",n,t);break;case"time":case"timesec":let r;if(n.toString().indexOf("-")>0)r=moment.utc(n);else{if(a="number"==typeof n?n:parseInt(n),!a&&"0"!==n.toString())return"";r=moment.unix(a).utc()}o="timesec"===e?r.format("HH:mm:ss"):r.format("HH:mm");break;case"password":o=n?FormEngineValidation.passwordDummy:"";break;default:o=n}return o},FormEngineValidation.updateInputField=function(e){const n=$('[name="'+e+'"]');let t=$('[name="'+n.data("main-field")+'"]');0===t.length&&(t=n);const a=$('[data-formengine-input-name="'+t.attr("name")+'"]'),i=t.data("config");if(void 0!==i){const e=FormEngineValidation.trimExplode(",",i.evalList);let n=a.val();for(let t=0;t<e.length;t++)n=FormEngineValidation.processValue(e[t],n,i);let o=n;for(let n=0;n<e.length;n++)o=FormEngineValidation.formatValue(e[n],o,i);t.val(n),t.get(0).dispatchEvent(new Event("change")),a.val(o)}},FormEngineValidation.validateField=function(e,n){const t=e instanceof $?e.get(0):e;if(n=n||t.value||"",void 0===t.dataset.formengineValidationRules)return n;const a=JSON.parse(t.dataset.formengineValidationRules);let i,o,r,l=!1,s=0,m=n;$.isArray(n)||(n=FormEngineValidation.ltrim(n)),$.each(a,(function(e,a){if(l)return!1;switch(a.type){case"required":""===n&&(l=!0,t.closest(FormEngineValidation.markerSelector).classList.add(FormEngineValidation.errorClass));break;case"range":if(""!==n){if((a.minItems||a.maxItems)&&(i=$(document).find('[name="'+t.dataset.relatedfieldname+'"]'),s=i.length?FormEngineValidation.trimExplode(",",i.val()).length:t.value,void 0!==a.minItems&&(o=1*a.minItems,!isNaN(o)&&s<o&&(l=!0)),void 0!==a.maxItems&&(r=1*a.maxItems,!isNaN(r)&&s>r&&(l=!0))),void 0!==a.lower){const e=1*a.lower;!isNaN(e)&&n<e&&(l=!0)}if(void 0!==a.upper){const e=1*a.upper;!isNaN(e)&&n>e&&(l=!0)}}break;case"select":case"category":(a.minItems||a.maxItems)&&(i=$(document).find('[name="'+t.dataset.relatedfieldname+'"]'),s=i.length?FormEngineValidation.trimExplode(",",i.val()).length:t instanceof HTMLSelectElement?t.querySelectorAll("option:checked").length:t.querySelectorAll("input[value]:checked").length,void 0!==a.minItems&&(o=1*a.minItems,!isNaN(o)&&s<o&&(l=!0)),void 0!==a.maxItems&&(r=1*a.maxItems,!isNaN(r)&&s>r&&(l=!0)));break;case"group":case"inline":(a.minItems||a.maxItems)&&(s=FormEngineValidation.trimExplode(",",t.value).length,void 0!==a.minItems&&(o=1*a.minItems,!isNaN(o)&&s<o&&(l=!0)),void 0!==a.maxItems&&(r=1*a.maxItems,!isNaN(r)&&s>r&&(l=!0)));break;case"min":(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement)&&t.value.length>0&&t.value.length<t.minLength&&(l=!0)}}));const d=!l,g=t.closest(FormEngineValidation.markerSelector);return null!==g&&g.classList.toggle(FormEngineValidation.errorClass,!d),FormEngineValidation.markParentTab($(t),d),$(document).trigger("t3-formengine-postfieldvalidation"),m},FormEngineValidation.processValue=function(e,n,t){let a="",i="",o="",r=0,l=n;switch(e){case"alpha":case"num":case"alphanum":case"alphanum_x":for(a="",r=0;r<n.length;r++){const t=n.substr(r,1);let i="_"===t||"-"===t,o=t>="a"&&t<="z"||t>="A"&&t<="Z",l=t>="0"&&t<="9";switch(e){case"alphanum":i=!1;break;case"alpha":l=!1,i=!1;break;case"num":o=!1,i=!1}(o||l||i)&&(a+=t)}a!==n&&(l=a);break;case"is_in":if(t.is_in){i=""+n,t.is_in=t.is_in.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&");const e=new RegExp("[^"+t.is_in+"]+","g");a=i.replace(e,"")}else a=i;l=a;break;case"nospace":l=(""+n).replace(/ /g,"");break;case"md5":""!==n&&(l=Md5.hash(n));break;case"upper":l=n.toUpperCase();break;case"lower":l=n.toLowerCase();break;case"integer":""!==n&&(l=FormEngineValidation.parseInt(n));break;case"decimal":""!==n&&(l=FormEngineValidation.parseDouble(n));break;case"trim":l=String(n).trim();break;case"datetime":""!==n&&(o=n.substr(0,1),l=FormEngineValidation.parseDateTime(n));break;case"date":""!==n&&(o=n.substr(0,1),l=FormEngineValidation.parseDate(n));break;case"time":case"timesec":""!==n&&(o=n.substr(0,1),l=FormEngineValidation.parseTime(n,e));break;case"year":""!==n&&(o=n.substr(0,1),l=FormEngineValidation.parseYear(n));break;case"null":case"password":break;default:customEvaluations.has(e)?l=customEvaluations.get(e).call(null,n):"object"==typeof TBE_EDITOR&&void 0!==TBE_EDITOR.customEvalFunctions&&"function"==typeof TBE_EDITOR.customEvalFunctions[e]&&(l=TBE_EDITOR.customEvalFunctions[e](n))}return l},FormEngineValidation.validate=function(e){(void 0===e||e instanceof Document)&&$(document).find(FormEngineValidation.markerSelector+", .t3js-tabmenu-item").removeClass(FormEngineValidation.errorClass).removeClass("has-validation-error");const n=e||document;$(n).find(FormEngineValidation.rulesSelector).each(((e,n)=>{const t=$(n);if(!t.closest(".t3js-flex-section-deleted, .t3js-inline-record-deleted, .t3js-file-reference-deleted").length){let e=!1;const n=t.val(),a=FormEngineValidation.validateField(t,n);if($.isArray(a)&&$.isArray(n)){if(a.length!==n.length)e=!0;else for(let t=0;t<a.length;t++)if(a[t]!==n[t]){e=!0;break}}else a.length&&n!==a&&(e=!0);e&&t.val(a)}}))},FormEngineValidation.markFieldAsChanged=function(e){if(e instanceof $&&(e=e.get(0)),!(e instanceof HTMLElement))return;const n=e.closest(".t3js-formengine-palette-field");null!==n&&n.classList.add("has-change")},FormEngineValidation.trimExplode=function(e,n){const t=[],a=n.split(e);for(let e=0;e<a.length;e++){const n=a[e].trim();n.length>0&&t.push(n)}return t},FormEngineValidation.parseInt=function(e){let n;return e?(n=parseInt(""+e,10),isNaN(n)?0:n):0},FormEngineValidation.parseDouble=function(e,n=2){let t=""+e;t=t.replace(/[^0-9,\.-]/g,"");const a="-"===t.substring(0,1);t=t.replace(/-/g,""),t=t.replace(/,/g,"."),-1===t.indexOf(".")&&(t+=".0");const i=t.split("."),o=i.pop();let r=Number(i.join("")+"."+o);return a&&(r*=-1),t=r.toFixed(n),t},FormEngineValidation.ltrim=function(e){return e?(""+e).replace(/^\s+/,""):""},FormEngineValidation.btrim=function(e){return e?(""+e).replace(/\s+$/,""):""},FormEngineValidation.parseDateTime=function(e){const n=e.indexOf(" ");if(-1!==n){const t=FormEngineValidation.parseDate(e.substr(n,e.length));FormEngineValidation.lastTime=t+FormEngineValidation.parseTime(e.substr(0,n),"time")}else FormEngineValidation.lastTime=FormEngineValidation.parseDate(e);return FormEngineValidation.lastTime},FormEngineValidation.parseDate=function(e){const n=new Date;let t=FormEngineValidation.split(e);if(t.values[1]&&t.values[1].length>2){const e=t.values[1];t=FormEngineValidation.splitSingle(e)}const a=t.values[3]?FormEngineValidation.parseInt(t.values[3]):FormEngineValidation.getYear(n),i=t.values[2]?FormEngineValidation.parseInt(t.values[2]):n.getUTCMonth()+1,o=t.values[1]?FormEngineValidation.parseInt(t.values[1]):n.getUTCDate(),r=moment.utc();return r.year(parseInt(a)).month(parseInt(i)-1).date(parseInt(o)).hour(0).minute(0).second(0),FormEngineValidation.lastDate=r.unix(),FormEngineValidation.lastDate},FormEngineValidation.parseTime=function(e,n){const t=new Date;let a=FormEngineValidation.split(e);if(a.values[1]&&a.values[1].length>2){const e=a.values[1];a=FormEngineValidation.splitSingle(e)}const i=a.values[3]?FormEngineValidation.parseInt(a.values[3]):t.getUTCSeconds(),o=a.values[2]?FormEngineValidation.parseInt(a.values[2]):t.getUTCMinutes(),r=a.values[1]?FormEngineValidation.parseInt(a.values[1]):t.getUTCHours(),l=moment.utc();return l.year(1970).month(0).date(1).hour(r).minute(o).second("timesec"===n?i:0),FormEngineValidation.lastTime=l.unix(),FormEngineValidation.lastTime<0&&(FormEngineValidation.lastTime+=86400),FormEngineValidation.lastTime},FormEngineValidation.parseYear=function(e){const n=new Date,t=FormEngineValidation.split(e);return FormEngineValidation.lastYear=t.values[1]?FormEngineValidation.parseInt(t.values[1]):FormEngineValidation.getYear(n),FormEngineValidation.lastYear},FormEngineValidation.getYear=function(e){return null===e?null:e.getUTCFullYear()},FormEngineValidation.getDate=function(e){const n=new Date(FormEngineValidation.getYear(e),e.getUTCMonth(),e.getUTCDate());return FormEngineValidation.getTimestamp(n)},FormEngineValidation.pol=function(foreign,value){return eval(("-"==foreign?"-":"")+value)},FormEngineValidation.convertClientTimestampToUTC=function(e,n){const t=new Date(1e3*e);return t.setTime(1e3*(e-60*t.getTimezoneOffset())),n?FormEngineValidation.getTime(t):FormEngineValidation.getTimestamp(t)},FormEngineValidation.getTimestamp=function(e){return Date.parse(e instanceof Date?e.toISOString():e)/1e3},FormEngineValidation.getTime=function(e){return 60*e.getUTCHours()*60+60*e.getUTCMinutes()+FormEngineValidation.getSecs(e)},FormEngineValidation.getSecs=function(e){return e.getUTCSeconds()},FormEngineValidation.getTimeSecs=function(e){return 60*e.getHours()*60+60*e.getMinutes()+e.getSeconds()},FormEngineValidation.markParentTab=function(e,n){e.parents(".tab-pane").each((function(e,t){const a=$(t);n&&(n=0===a.find(".has-error").length);const i=a.attr("id");$(document).find('a[href="#'+i+'"]').closest(".t3js-tabmenu-item").toggleClass("has-validation-error",!n)}))},FormEngineValidation.splitSingle=function(e){const n=""+e,t={values:[],pointer:3};return t.values[1]=n.substr(0,2),t.values[2]=n.substr(2,2),t.values[3]=n.substr(4,10),t},FormEngineValidation.splitStr=function(e,n,t){const a=""+e,i=n.length;let o=-i;t<1&&(t=1);for(let e=1;e<t;e++)if(o=a.indexOf(n,o+i),-1==o)return null;let r=a.indexOf(n,o+i);return-1==r&&(r=a.length),a.substring(o+i,r)},FormEngineValidation.split=function(e){const n={values:[],valPol:[],pointer:0,numberMode:0,theVal:""};e+=" ";for(let t=0;t<e.length;t++){const a=e.substr(t,1);a<"0"||a>"9"?(n.numberMode&&(n.pointer++,n.values[n.pointer]=n.theVal,n.theVal="",n.numberMode=0),"+"!=a&&"-"!=a||(n.valPol[n.pointer+1]=a)):(n.theVal+=a,n.numberMode=1)}return n},FormEngineValidation.registerSubmitCallback=function(){DocumentSaveActions.getInstance().addPreSubmitCallback((function(e){if($("."+FormEngineValidation.errorClass).length>0){const n=Modal.confirm(TYPO3.lang.alert||"Alert",TYPO3.lang["FormEngine.fieldsMissing"],Severity.error,[{text:TYPO3.lang["button.ok"]||"OK",active:!0,btnClass:"btn-default",name:"ok"}]);n.addEventListener("button.clicked",(()=>n.hideModal())),e.stopImmediatePropagation()}}))},FormEngineValidation}());
\ No newline at end of file
diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/container/files-control-container.js b/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/container/files-control-container.js
new file mode 100644
index 000000000000..d3579e1785a2
--- /dev/null
+++ b/typo3/sysext/backend/Resources/Public/JavaScript/form-engine/container/files-control-container.js
@@ -0,0 +1,13 @@
+/*
+ * 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!
+ */
+import{MessageUtility}from"@typo3/backend/utility/message-utility.js";import{AjaxDispatcher}from"@typo3/backend/form-engine/inline-relation/ajax-dispatcher.js";import NProgress from"nprogress";import Sortable from"sortablejs";import FormEngine from"@typo3/backend/form-engine.js";import FormEngineValidation from"@typo3/backend/form-engine-validation.js";import Icons from"@typo3/backend/icons.js";import InfoWindow from"@typo3/backend/info-window.js";import Modal from"@typo3/backend/modal.js";import RegularEvent from"@typo3/core/event/regular-event.js";import Severity from"@typo3/backend/severity.js";import Utility from"@typo3/backend/utility.js";var Selectors,States,Separators,SortDirections;!function(e){e.toggleSelector='[data-bs-toggle="formengine-file"]',e.controlSectionSelector=".t3js-formengine-file-header-control",e.deleteRecordButtonSelector=".t3js-editform-delete-file-reference",e.enableDisableRecordButtonSelector=".t3js-toggle-visibility-button",e.infoWindowButton='[data-action="infowindow"]',e.synchronizeLocalizeRecordButtonSelector=".t3js-synchronizelocalize-button",e.controlContainer=".t3js-file-controls"}(Selectors||(Selectors={})),function(e){e.new="isNewFileReference",e.visible="panel-visible",e.collapsed="panel-collapsed",e.notLoaded="t3js-not-loaded"}(States||(States={})),function(e){e.structureSeparator="-"}(Separators||(Separators={})),function(e){e.DOWN="down",e.UP="up"}(SortDirections||(SortDirections={}));class FilesControlContainer extends HTMLElement{constructor(){super(...arguments),this.container=null,this.ajaxDispatcher=null,this.appearance=null,this.requestQueue={},this.progessQueue={},this.noTitleString=TYPO3.lang?TYPO3.lang["FormEngine.noRecordTitle"]:"[No title]",this.handlePostMessage=e=>{if(!MessageUtility.verifyOrigin(e.origin))throw"Denied message sent by "+e.origin;if("typo3:foreignRelation:insert"===e.data.actionName){if(void 0===e.data.objectGroup)throw"No object group defined for message";if(e.data.objectGroup!==this.container.dataset.objectGroup)return;this.importRecord([e.data.objectGroup,e.data.uid]).then((()=>{if(e.source){const t={actionName:"typo3:foreignRelation:inserted",objectGroup:e.data.objectId,table:e.data.table,uid:e.data.uid};MessageUtility.send(t,e.source)}}))}}}static getFileReferenceContainer(e){return document.querySelector('[data-object-id="'+e+'"]')}static getCollapseButton(e){return document.querySelector('[aria-controls="'+e+'_fields"]')}static toggleElement(e){const t=FilesControlContainer.getFileReferenceContainer(e);t.classList.contains(States.collapsed)?FilesControlContainer.expandElement(t,e):FilesControlContainer.collapseElement(t,e)}static collapseElement(e,t){const n=FilesControlContainer.getCollapseButton(t);e.classList.remove(States.visible),e.classList.add(States.collapsed),n.setAttribute("aria-expanded","false")}static expandElement(e,t){const n=FilesControlContainer.getCollapseButton(t);e.classList.remove(States.collapsed),e.classList.add(States.visible),n.setAttribute("aria-expanded","true")}static isNewRecord(e){return FilesControlContainer.getFileReferenceContainer(e).classList.contains(States.new)}static updateExpandedCollapsedStateLocally(e,t){const n=FilesControlContainer.getFileReferenceContainer(e),o=document.getElementsByName("uc[inlineView]["+n.dataset.topmostParentTable+"]["+n.dataset.topmostParentUid+"]"+n.dataset.fieldName);o.length&&(o[0].value=t?"1":"0")}connectedCallback(){const e=this.getAttribute("identifier")||"";this.container=this.querySelector("#"+e),null!==this.container&&(this.ajaxDispatcher=new AjaxDispatcher(this.container.dataset.objectGroup),this.registerEvents())}registerEvents(){if(this.registerInfoButton(),this.registerSort(),this.registerEnableDisableButton(),this.registerDeleteButton(),this.registerSynchronizeLocalize(),this.registerToggle(),new RegularEvent("message",this.handlePostMessage).bindTo(window),this.getAppearance().useSortable){const e=document.getElementById(this.container.getAttribute("id")+"_records");new Sortable(e,{group:e.getAttribute("id"),handle:".sortableHandle",onSort:()=>{this.updateSorting()}})}}registerToggle(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation(),e.loadRecordDetails(this.closest(Selectors.toggleSelector).parentElement.dataset.objectId)})).delegateTo(this.container,`${Selectors.toggleSelector} .form-irre-header-cell:not(${Selectors.controlSectionSelector}`)}registerSort(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation(),e.changeSortingByButton(this.closest("[data-object-id]").dataset.objectId,this.dataset.direction)})).delegateTo(this.container,Selectors.controlSectionSelector+' [data-action="sort"]')}createRecord(e,t,n=null,o=null){let i=this.container.dataset.objectGroup;null!==n&&(i+=Separators.structureSeparator+n),null!==n?(FilesControlContainer.getFileReferenceContainer(i).insertAdjacentHTML("afterend",t),this.memorizeAddRecord(e,n,o)):(document.getElementById(this.container.getAttribute("id")+"_records").insertAdjacentHTML("beforeend",t),this.memorizeAddRecord(e,null,o))}async importRecord(e,t){return this.ajaxDispatcher.send(this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("file_reference_create")),e).then((async e=>{this.isBelowMax()&&this.createRecord(e.compilerInput.uid,e.data,void 0!==t?t:null,void 0!==e.compilerInput.childChildUid?e.compilerInput.childChildUid:null)}))}registerEnableDisableButton(){new RegularEvent("click",((e,t)=>{e.preventDefault(),e.stopImmediatePropagation();const n=t.closest("[data-object-id]").dataset.objectId,o=FilesControlContainer.getFileReferenceContainer(n),i="data"+o.dataset.fieldName+"["+t.dataset.hiddenField+"]",r=document.querySelector('[data-formengine-input-name="'+i+'"'),a=document.querySelector('[name="'+i+'"');null!==r&&null!==a&&(r.checked=!r.checked,a.value=r.checked?"1":"0",FormEngineValidation.markFieldAsChanged(r));const s="t3-form-field-container-inline-hidden";let l;o.classList.contains(s)?(l="actions-edit-hide",o.classList.remove(s)):(l="actions-edit-unhide",o.classList.add(s)),Icons.getIcon(l,Icons.sizes.small).then((e=>{t.replaceChild(document.createRange().createContextualFragment(e),t.querySelector(".t3js-icon"))}))})).delegateTo(this.container,Selectors.enableDisableRecordButtonSelector)}registerInfoButton(){new RegularEvent("click",(function(e){e.preventDefault(),e.stopImmediatePropagation(),InfoWindow.showItem(this.dataset.infoTable,this.dataset.infoUid)})).delegateTo(this.container,Selectors.infoWindowButton)}registerDeleteButton(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation();const n=TYPO3.lang["label.confirm.delete_record.title"]||"Delete this record?",o=TYPO3.lang["label.confirm.delete_record.content"]||"Are you sure you want to delete this record?";Modal.confirm(n,o,Severity.warning,[{text:TYPO3.lang["buttons.confirm.delete_record.no"]||"Cancel",active:!0,btnClass:"btn-default",name:"no",trigger:(e,t)=>t.hideModal()},{text:TYPO3.lang["buttons.confirm.delete_record.yes"]||"Yes, delete this record",btnClass:"btn-warning",name:"yes",trigger:(t,n)=>{e.deleteRecord(this.closest("[data-object-id]").dataset.objectId),n.hideModal()}}])})).delegateTo(this.container,Selectors.deleteRecordButtonSelector)}registerSynchronizeLocalize(){const e=this;new RegularEvent("click",(function(t){t.preventDefault(),t.stopImmediatePropagation(),e.ajaxDispatcher.send(e.ajaxDispatcher.newRequest(e.ajaxDispatcher.getEndpoint("file_reference_synchronizelocalize")),[e.container.dataset.objectGroup,this.dataset.type]).then((async t=>{document.getElementById(e.container.getAttribute("id")+"_records").insertAdjacentHTML("beforeend",t.data);const n=e.container.dataset.objectGroup+Separators.structureSeparator;for(let o of t.compilerInput.delete)e.deleteRecord(n+o,!0);for(let o of Object.values(t.compilerInput.localize)){if(void 0!==o.remove){const e=FilesControlContainer.getFileReferenceContainer(n+o.remove);e.parentElement.removeChild(e)}e.memorizeAddRecord(o.uid,null,o.selectedValue)}}))})).delegateTo(this.container,Selectors.synchronizeLocalizeRecordButtonSelector)}loadRecordDetails(e){const t=document.getElementById(e+"_fields"),n=FilesControlContainer.getFileReferenceContainer(e),o=void 0!==this.requestQueue[e];if(null!==t&&!n.classList.contains(States.notLoaded))this.collapseExpandRecord(e);else{const i=this.getProgress(e,n.dataset.objectIdHash);if(o)this.requestQueue[e].abort(),delete this.requestQueue[e],delete this.progessQueue[e],i.done();else{const o=this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("file_reference_details"));this.ajaxDispatcher.send(o,[e]).then((async o=>{delete this.requestQueue[e],delete this.progessQueue[e],n.classList.remove(States.notLoaded),t.innerHTML=o.data,this.collapseExpandRecord(e),i.done(),FormEngine.reinitialize(),FormEngineValidation.initializeInputFields(),FormEngineValidation.validate(this.container)})),this.requestQueue[e]=o,i.start()}}}collapseExpandRecord(e){const t=FilesControlContainer.getFileReferenceContainer(e),n=!0===this.getAppearance().expandSingle,o=t.classList.contains(States.collapsed);let i=[];const r=[];n&&o&&(i=this.collapseAllRecords(t.dataset.objectUid)),FilesControlContainer.toggleElement(e),FilesControlContainer.isNewRecord(e)?FilesControlContainer.updateExpandedCollapsedStateLocally(e,o):o?r.push(t.dataset.objectUid):o||i.push(t.dataset.objectUid),this.ajaxDispatcher.send(this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("file_reference_expandcollapse")),[e,r.join(","),i.join(",")])}memorizeAddRecord(e,t=null,n=null){const o=this.getFormFieldForElements();if(null===o)return;let i=Utility.trimExplode(",",o.value);if(t){const n=[];for(let o=0;o<i.length;o++)i[o].length&&n.push(i[o]),t===i[o]&&n.push(e);i=n}else i.push(e);o.value=i.join(","),o.classList.add("has-change"),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,i),this.isBelowMax()||this.toggleContainerControls(!1),FormEngine.reinitialize(),FormEngineValidation.initializeInputFields(),FormEngineValidation.validate(this.container)}memorizeRemoveRecord(e){const t=this.getFormFieldForElements();if(null===t)return[];let n=Utility.trimExplode(",",t.value);const o=n.indexOf(e);return o>-1&&(delete n[o],t.value=n.join(","),t.classList.add("has-change"),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,n)),n}changeSortingByButton(e,t){const n=FilesControlContainer.getFileReferenceContainer(e),o=n.dataset.objectUid,i=document.getElementById(this.container.getAttribute("id")+"_records"),r=Array.from(i.children).map((e=>e.dataset.objectUid));let a=r.indexOf(o),s=!1;if(t===SortDirections.UP&&a>0?(r[a]=r[a-1],r[a-1]=o,s=!0):t===SortDirections.DOWN&&a<r.length-1&&(r[a]=r[a+1],r[a+1]=o,s=!0),s){const e=this.container.dataset.objectGroup+Separators.structureSeparator,o=t===SortDirections.UP?1:0;n.parentElement.insertBefore(FilesControlContainer.getFileReferenceContainer(e+r[a-o]),FilesControlContainer.getFileReferenceContainer(e+r[a+1-o])),this.updateSorting()}}updateSorting(){const e=this.getFormFieldForElements();if(null===e)return;const t=document.getElementById(this.container.getAttribute("id")+"_records"),n=Array.from(t.querySelectorAll('[data-object-parent-group="'+this.container.dataset.objectGroup+'"][data-placeholder-record="0"]')).map((e=>e.dataset.objectUid));e.value=n.join(","),e.classList.add("has-change"),document.dispatchEvent(new Event("formengine:files:sorting-changed")),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,n)}deleteRecord(e,t=!1){const n=FilesControlContainer.getFileReferenceContainer(e),o=n.dataset.objectUid;if(n.classList.add("t3js-file-reference-deleted"),!FilesControlContainer.isNewRecord(e)&&!t){const e=this.container.querySelector('[name="cmd'+n.dataset.fieldName+'[delete]"]');e.removeAttribute("disabled"),n.parentElement.insertAdjacentElement("afterbegin",e)}new RegularEvent("transitionend",(()=>{n.parentElement.removeChild(n),FormEngineValidation.validate(this.container)})).bindTo(n),this.memorizeRemoveRecord(o),n.classList.add("form-irre-object--deleted"),this.isBelowMax()&&this.toggleContainerControls(!0)}toggleContainerControls(e){const t=this.container.querySelector(Selectors.controlContainer);if(null===t)return;t.querySelectorAll("button, a").forEach((t=>{t.style.display=e?null:"none"}))}getProgress(e,t){const n="#"+t+"_header";let o;return void 0!==this.progessQueue[e]?o=this.progessQueue[e]:(o=NProgress,o.configure({parent:n,showSpinner:!1}),this.progessQueue[e]=o),o}collapseAllRecords(e){const t=this.getFormFieldForElements(),n=[];if(null!==t){const o=Utility.trimExplode(",",t.value);for(let t of o){if(t===e)continue;const o=this.container.dataset.objectGroup+Separators.structureSeparator+t,i=FilesControlContainer.getFileReferenceContainer(o);i.classList.contains(States.visible)&&(FilesControlContainer.collapseElement(i,o),FilesControlContainer.isNewRecord(o)?FilesControlContainer.updateExpandedCollapsedStateLocally(o,!1):n.push(t))}}return n}getFormFieldForElements(){const e=document.getElementsByName(this.container.dataset.formField);return e.length>0?e[0]:null}redrawSortingButtons(e,t=[]){if(0===t.length){const e=this.getFormFieldForElements();null!==e&&(t=Utility.trimExplode(",",e.value))}0!==t.length&&t.forEach(((n,o)=>{const i=FilesControlContainer.getFileReferenceContainer(e+Separators.structureSeparator+n).dataset.objectIdHash+"_header",r=document.getElementById(i),a=r.querySelector('[data-action="sort"][data-direction="'+SortDirections.UP+'"]');if(null!==a){let e="actions-move-up";0===o?(a.classList.add("disabled"),e="empty-empty"):a.classList.remove("disabled"),Icons.getIcon(e,Icons.sizes.small).then((e=>{a.replaceChild(document.createRange().createContextualFragment(e),a.querySelector(".t3js-icon"))}))}const s=r.querySelector('[data-action="sort"][data-direction="'+SortDirections.DOWN+'"]');if(null!==s){let e="actions-move-down";o===t.length-1?(s.classList.add("disabled"),e="empty-empty"):s.classList.remove("disabled"),Icons.getIcon(e,Icons.sizes.small).then((e=>{s.replaceChild(document.createRange().createContextualFragment(e),s.querySelector(".t3js-icon"))}))}}))}isBelowMax(){const e=this.getFormFieldForElements();if(null===e)return!0;if(void 0!==TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup]){if(Utility.trimExplode(",",e.value).length>=TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup].max)return!1}return!0}getAppearance(){if(null===this.appearance&&(this.appearance={},"string"==typeof this.container.dataset.appearance))try{this.appearance=JSON.parse(this.container.dataset.appearance)}catch(e){console.error(e)}return this.appearance}}window.customElements.define("typo3-formengine-container-files",FilesControlContainer);
\ No newline at end of file
diff --git a/typo3/sysext/backend/Tests/Unit/Form/FieldControl/ElementBrowserTest.php b/typo3/sysext/backend/Tests/Unit/Form/FieldControl/ElementBrowserTest.php
index f9c078dbc8c2..a270e717efbd 100644
--- a/typo3/sysext/backend/Tests/Unit/Form/FieldControl/ElementBrowserTest.php
+++ b/typo3/sysext/backend/Tests/Unit/Form/FieldControl/ElementBrowserTest.php
@@ -56,7 +56,7 @@ class ElementBrowserTest extends UnitTestCase
     /**
      * @test
      */
-    public function renderTrimsAllowedValuesFromAppearanceSection(): void
+    public function renderTrimsAllowedValues(): void
     {
         $nodeFactory = $this->prophesize(NodeFactory::class);
         $elementBrowser = new ElementBrowser($nodeFactory->reveal(), [
@@ -68,16 +68,14 @@ class ElementBrowserTest extends UnitTestCase
                 'itemFormElName' => '',
                 'fieldConf' => [
                     'config' => [
-                        'type' => 'group',
-                        'appearance' => [
-                            'elementBrowserAllowed' => 'be_users, be_groups',
-                        ],
+                        'type' => 'file',
+                        'allowed' => 'jpg, png',
                     ],
                 ],
             ],
         ]);
         $result = $elementBrowser->render();
-        self::assertSame($result['linkAttributes']['data-params'], '|||be_users,be_groups|');
+        self::assertSame($result['linkAttributes']['data-params'], '|||jpg,png|');
     }
 
     /**
diff --git a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/InlineOverrideChildTcaTest.php b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/InlineOverrideChildTcaTest.php
index fc294383b58a..706db951ab25 100644
--- a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/InlineOverrideChildTcaTest.php
+++ b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/InlineOverrideChildTcaTest.php
@@ -119,8 +119,8 @@ class InlineOverrideChildTcaTest extends UnitTestCase
                                 'aGivenSetting' => 'overrideValue',
                                 'aNewSetting' => 'anotherNewValue',
                                 'appearance' => [
-                                    'elementBrowserType' => 'file',
-                                    'elementBrowserAllowed' => 'jpg,png',
+                                    'useSortable' => true,
+                                    'showPossibleLocalizationRecords' => false,
                                 ],
                             ],
                         ],
@@ -135,7 +135,7 @@ class InlineOverrideChildTcaTest extends UnitTestCase
                             'aGivenSetting' => 'aValue',
                             'doNotChangeMe' => 'doNotChangeMe',
                             'appearance' => [
-                                'elementBrowserType' => 'db',
+                                'useSortable' => false,
                             ],
                         ],
                     ],
@@ -150,8 +150,8 @@ class InlineOverrideChildTcaTest extends UnitTestCase
                 'aGivenSetting' => 'overrideValue',
                 'doNotChangeMe' => 'doNotChangeMe',
                 'appearance' => [
-                    'elementBrowserType' => 'file',
-                    'elementBrowserAllowed' => 'jpg,png',
+                    'useSortable' => true,
+                    'showPossibleLocalizationRecords' => false,
                 ],
                 'aNewSetting' => 'anotherNewValue',
             ],
diff --git a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaInlineConfigurationTest.php b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaInlineConfigurationTest.php
index 81496b5a5a8f..1e4e3851275d 100644
--- a/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaInlineConfigurationTest.php
+++ b/typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaInlineConfigurationTest.php
@@ -572,8 +572,7 @@ class TcaInlineConfigurationTest extends UnitTestCase
                                             'aGivenSetting' => 'aOverrideValue',
                                             'aNewSetting' => 'aNewSetting',
                                             'appearance' => [
-                                                'elementBrowserType' => 'file',
-                                                'elementBrowserAllowed' => 'jpg,png',
+                                                'useSortable' => true,
                                             ],
                                         ],
                                     ],
@@ -602,8 +601,7 @@ class TcaInlineConfigurationTest extends UnitTestCase
                 'aGivenSetting' => 'aOverrideValue',
                 'aNewSetting' => 'aNewSetting',
                 'appearance' => [
-                    'elementBrowserType' => 'file',
-                    'elementBrowserAllowed' => 'jpg,png',
+                    'useSortable' => true,
                 ],
             ],
         ];
@@ -619,8 +617,7 @@ class TcaInlineConfigurationTest extends UnitTestCase
                 'aGivenSetting' => 'aOverrideValue',
                 'aNewSetting' => 'aNewSetting',
                 'appearance' => [
-                    'elementBrowserType' => 'file',
-                    'elementBrowserAllowed' => 'jpg,png',
+                    'useSortable' => true,
                 ],
             ],
             'foreignTable' => 'anotherForeignTableName',
diff --git a/typo3/sysext/backend/Tests/Unit/Utility/BackendUtilityTest.php b/typo3/sysext/backend/Tests/Unit/Utility/BackendUtilityTest.php
index a7d29c556d9b..51a761c25c0c 100644
--- a/typo3/sysext/backend/Tests/Unit/Utility/BackendUtilityTest.php
+++ b/typo3/sysext/backend/Tests/Unit/Utility/BackendUtilityTest.php
@@ -1201,14 +1201,14 @@ class BackendUtilityTest extends UnitTestCase
             '',
             42,
             $tableName,
-            ['type' => 'inline', 'foreign_table' => 'sys_file_reference']
+            ['type' => 'file', 'foreign_table' => 'sys_file_reference']
         )->shouldBeCalled();
         $relationHandlerProphecy->processDeletePlaceholder()->shouldBeCalled();
         $relationHandler = $relationHandlerProphecy->reveal();
         $relationHandler->tableArray = ['sys_file_reference' => []];
         GeneralUtility::addInstance(RelationHandler::class, $relationHandler);
         $GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config'] = [
-            'type' => 'inline',
+            'type' => 'file',
             'foreign_table' => 'sys_file_reference',
         ];
         $elementData = [
diff --git a/typo3/sysext/core/Classes/Configuration/FlexForm/FlexFormTools.php b/typo3/sysext/core/Classes/Configuration/FlexForm/FlexFormTools.php
index 1bd0d8c9e0d3..0f1ef2368ed4 100644
--- a/typo3/sysext/core/Classes/Configuration/FlexForm/FlexFormTools.php
+++ b/typo3/sysext/core/Classes/Configuration/FlexForm/FlexFormTools.php
@@ -33,6 +33,7 @@ use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidSinglePointerFieldExc
 use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidTcaException;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
+use TYPO3\CMS\Core\Preparations\TcaPreparation;
 use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\MathUtility;
@@ -716,7 +717,9 @@ class FlexFormTools
                 $dataStructure = $this->removeElementTceFormsRecursive($dataStructure);
 
                 if (is_array($dataStructure['sheets'][$sheetName])) {
+                    // @todo Use TcaMigration and TcaPreparation instead of duplicating the code
                     $dataStructure['sheets'][$sheetName] = $this->prepareCategoryFields($dataStructure['sheets'][$sheetName]);
+                    $dataStructure['sheets'][$sheetName] = $this->prepareFileFields($dataStructure['sheets'][$sheetName]);
                 }
             }
         }
@@ -999,6 +1002,57 @@ class FlexFormTools
         return $dataStructurSheets;
     }
 
+    /**
+     * Prepare type=file fields if given.
+     *
+     * @param array $dataStructurSheets
+     * @return array The processed $dataStructureSheets
+     */
+    protected function prepareFileFields(array $dataStructurSheets): array
+    {
+        if ($dataStructurSheets === []) {
+            // Early return in case the no sheets are given
+            return $dataStructurSheets;
+        }
+
+        foreach ($dataStructurSheets as &$structure) {
+            if (!is_array($structure['el'] ?? false) || $structure['el'] === []) {
+                // Skip if no elements (fields) are defined
+                continue;
+            }
+            foreach ($structure['el'] as $fieldName => &$fieldConfig) {
+                if (($fieldConfig['config']['type'] ?? '') !== 'file') {
+                    // Skip if type is not "file"
+                    continue;
+                }
+
+                $fieldConfig['config'] = array_replace_recursive(
+                    $fieldConfig['config'],
+                    [
+                        'foreign_table' => 'sys_file_reference',
+                        'foreign_field' => 'uid_foreign',
+                        'foreign_sortby' => 'sorting_foreign',
+                        'foreign_table_field' => 'tablenames',
+                        'foreign_match_fields' => [
+                            'fieldname' => $fieldName,
+                        ],
+                        'foreign_label' => 'uid_local',
+                        'foreign_selector' => 'uid_local',
+                    ]
+                );
+
+                if (!empty(($allowed = ($fieldConfig['config']['allowed'] ?? null)))) {
+                    $fieldConfig['config']['allowed'] = TcaPreparation::prepareFileExtensions($allowed);
+                }
+                if (!empty(($disallowed = ($fieldConfig['config']['disallowed'] ?? null)))) {
+                    $fieldConfig['config']['disallowed'] = TcaPreparation::prepareFileExtensions($disallowed);
+                }
+            }
+        }
+
+        return $dataStructurSheets;
+    }
+
     /**
      * Remove "TCEforms" key from all elements in data structure to simplify further parsing.
      *
diff --git a/typo3/sysext/core/Classes/DataHandling/DataHandler.php b/typo3/sysext/core/Classes/DataHandling/DataHandler.php
index f09884b08e29..98d9687a3b20 100644
--- a/typo3/sysext/core/Classes/DataHandling/DataHandler.php
+++ b/typo3/sysext/core/Classes/DataHandling/DataHandler.php
@@ -54,6 +54,7 @@ use TYPO3\CMS\Core\Localization\LanguageService;
 use TYPO3\CMS\Core\Log\LogDataTrait;
 use TYPO3\CMS\Core\Messaging\FlashMessage;
 use TYPO3\CMS\Core\Messaging\FlashMessageService;
+use TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter;
 use TYPO3\CMS\Core\Resource\ResourceFactory;
 use TYPO3\CMS\Core\Service\OpcodeCacheService;
 use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
@@ -1497,6 +1498,7 @@ class DataHandler implements LoggerAwareInterface
             'email' => $this->checkValueForEmail((string)$value, $tcaFieldConf, $table, $id, (int)$realPid, $checkField),
             'flex' => $field ? $this->checkValueForFlex($res, $value, $tcaFieldConf, $table, $id, $curValue, $status, $realPid, $recFID, $tscPID, $field) : [],
             'inline' => $this->checkValueForInline($res, $value, $tcaFieldConf, $table, $id, $status, $field, $additionalData) ?: [],
+            'file' => $this->checkValueForFile($res, (string)$value, $tcaFieldConf, $table, $id, $field, $additionalData),
             'input' => $this->checkValueForInput($value, $tcaFieldConf, $table, $id, $realPid, $field),
             'language' => $this->checkValueForLanguage((int)$value, $table, $field),
             'link' => $this->checkValueForLink((string)$value, $tcaFieldConf, $table, $id, $checkField),
@@ -2614,6 +2616,36 @@ class DataHandler implements LoggerAwareInterface
         return $res;
     }
 
+    /**
+     * Evaluates 'file' type values.
+     */
+    public function checkValueForFile(
+        array $res,
+        string $value,
+        array $tcaFieldConf,
+        string $table,
+        int|string $id,
+        string $field,
+        ?array $additionalData = null
+    ): array {
+        $valueArray = array_unique(GeneralUtility::trimExplode(',', $value));
+        if ($value !== '' && (str_contains($value, 'NEW') || !MathUtility::canBeInterpretedAsInteger($id))) {
+            $this->remapStackRecords[$table][$id] = ['remapStackIndex' => count($this->remapStack)];
+            $this->addNewValuesToRemapStackChildIds($valueArray);
+            $this->remapStack[] = [
+                'func' => 'checkValue_file_processDBdata',
+                'args' => [$valueArray, $tcaFieldConf, $id, $table],
+                'pos' => ['valueArray' => 0, 'tcaFieldConf' => 1, 'id' => 2, 'table' => 3],
+                'additionalData' => $additionalData,
+                'field' => $field,
+            ];
+            unset($res['value']);
+        } elseif ($value !== '' || MathUtility::canBeInterpretedAsInteger($id)) {
+            $res['value'] = $this->checkValue_file_processDBdata($valueArray, $tcaFieldConf, $id, $table);
+        }
+        return $res;
+    }
+
     /**
      * Checks if a fields has more items than defined via TCA in maxitems.
      * If there are more items than allowed, the item list is truncated to the defined number.
@@ -3247,7 +3279,7 @@ class DataHandler implements LoggerAwareInterface
             // update record in intermediate table (sorting & pointer uid to parent record)
             $dbAnalysis->writeForeignField($tcaFieldConf, $id, 0);
             $newValue = $dbAnalysis->countItems(false);
-        } elseif ($this->getInlineFieldType($tcaFieldConf) === 'mm') {
+        } elseif ($this->getRelationFieldType($tcaFieldConf) === 'mm') {
             // In order to fully support all the MM stuff, directly call checkValue_group_select_processDBdata instead of repeating the needed code here
             $valueArray = $this->checkValue_group_select_processDBdata($valueArray, $tcaFieldConf, $id, $status, 'select', $table, $field);
             $newValue = $valueArray[0];
@@ -3260,6 +3292,24 @@ class DataHandler implements LoggerAwareInterface
         return $newValue;
     }
 
+    /**
+     * Returns data for file fields.
+     */
+    protected function checkValue_file_processDBdata($valueArray, $tcaFieldConf, $id, $table): mixed
+    {
+        $valueArray = GeneralUtility::makeInstance(FileExtensionFilter::class)->filter(
+            $valueArray,
+            (string)($tcaFieldConf['allowed'] ?? ''),
+            (string)($tcaFieldConf['disallowed'] ?? ''),
+            $this
+        );
+
+        $dbAnalysis = $this->createRelationHandlerInstance();
+        $dbAnalysis->start(implode(',', $valueArray), $tcaFieldConf['foreign_table'], '', 0, $table, $tcaFieldConf);
+        $dbAnalysis->writeForeignField($tcaFieldConf, $id);
+        return $dbAnalysis->countItems(false);
+    }
+
     /*********************************************
      *
      * PROCESSING COMMANDS
@@ -3910,13 +3960,13 @@ class DataHandler implements LoggerAwareInterface
      */
     public function copyRecord_procBasedOnFieldType($table, $uid, $field, $value, $row, $conf, $realDestPid, $language = 0, array $workspaceOptions = [])
     {
-        $inlineSubType = $this->getInlineFieldType($conf);
+        $relationFieldType = $this->getRelationFieldType($conf);
         // Get the localization mode for the current (parent) record (keep|select):
         // Register if there are references to take care of or MM is used on an inline field (no change to value):
-        if ($this->isReferenceField($conf) || $inlineSubType === 'mm') {
+        if ($this->isReferenceField($conf) || $relationFieldType === 'mm') {
             $value = $this->copyRecord_processManyToMany($table, $uid, $field, $value, $conf, $language);
-        } elseif ($inlineSubType !== false) {
-            $value = $this->copyRecord_processInline($table, $uid, $field, $value, $row, $conf, $realDestPid, $language, $workspaceOptions);
+        } elseif ($relationFieldType !== false) {
+            $value = $this->copyRecord_processRelation($table, $uid, $field, $value, $row, $conf, $realDestPid, $language, $workspaceOptions);
         }
         // For "flex" fieldtypes we need to traverse the structure for two reasons: If there are file references they have to be prepended with absolute paths and if there are database reference they MIGHT need to be remapped (still done in remapListedDBRecords())
         if (isset($conf['type']) && $conf['type'] === 'flex') {
@@ -4001,7 +4051,7 @@ class DataHandler implements LoggerAwareInterface
     }
 
     /**
-     * Processes child records in an inline (IRRE) element when the parent record is copied.
+     * Processes relations in an inline (IRRE) or file element when the parent record is copied.
      *
      * @param string $table
      * @param int $uid
@@ -4014,7 +4064,7 @@ class DataHandler implements LoggerAwareInterface
      * @param array $workspaceOptions
      * @return string
      */
-    protected function copyRecord_processInline(
+    protected function copyRecord_processRelation(
         $table,
         $uid,
         $field,
@@ -4110,7 +4160,7 @@ class DataHandler implements LoggerAwareInterface
         // Extract parameters:
         [$table, $uid, $field, $realDestPid] = $pParams;
         // If references are set for this field, set flag so they can be corrected later (in ->remapListedDBRecords())
-        if (($this->isReferenceField($dsConf) || $this->getInlineFieldType($dsConf) !== false) && (string)$dataValue !== '') {
+        if (($this->isReferenceField($dsConf) || $this->getRelationFieldType($dsConf) !== false) && (string)$dataValue !== '') {
             $dataValue = $this->copyRecord_procBasedOnFieldType($table, $uid, $field, $dataValue, [], $dsConf, $realDestPid, 0, $workspaceOptions);
             $this->registerDBList[$table][$uid][$field] = 'FlexForm_reference';
         }
@@ -4531,32 +4581,26 @@ class DataHandler implements LoggerAwareInterface
      * @param array $conf TCA configuration of current field
      * @internal should only be used from within DataHandler
      */
-    public function moveRecord_procBasedOnFieldType($table, $uid, $destPid, $value, $conf)
+    public function moveRecord_procBasedOnFieldType($table, $uid, $destPid, $value, $conf): void
     {
-        $dbAnalysis = null;
-        if (!empty($conf['type']) && $conf['type'] === 'inline') {
-            $foreign_table = $conf['foreign_table'];
-            $moveChildrenWithParent = !isset($conf['behaviour']['disableMovingChildrenWithParent']) || !$conf['behaviour']['disableMovingChildrenWithParent'];
-            if ($foreign_table && $moveChildrenWithParent) {
-                $inlineType = $this->getInlineFieldType($conf);
-                if ($inlineType === 'list' || $inlineType === 'field') {
-                    if ($table === 'pages') {
-                        // If the inline elements are related to a page record,
-                        // make sure they reside at that page and not at its parent
-                        $destPid = $uid;
-                    }
-                    $dbAnalysis = $this->createRelationHandlerInstance();
-                    $dbAnalysis->start($value, $conf['foreign_table'], '', $uid, $table, $conf);
-                }
-            }
+        if (($conf['behaviour']['disableMovingChildrenWithParent'] ?? false)
+            || !in_array($this->getRelationFieldType($conf), ['list', 'field'], true)
+        ) {
+            return;
         }
-        // Move the records
-        if (isset($dbAnalysis)) {
-            // Moving records to a positive destination will insert each
-            // record at the beginning, thus the order is reversed here:
-            foreach (array_reverse($dbAnalysis->itemArray) as $v) {
-                $this->moveRecord($v['table'], $v['id'], $destPid);
-            }
+
+        if ($table === 'pages') {
+            // If the relations are related to a page record, make sure they reside at that page and not at its parent
+            $destPid = $uid;
+        }
+
+        $dbAnalysis = $this->createRelationHandlerInstance();
+        $dbAnalysis->start($value, $conf['foreign_table'], '', $uid, $table, $conf);
+
+        // Moving records to a positive destination will insert each
+        // record at the beginning, thus the order is reversed here:
+        foreach (array_reverse($dbAnalysis->itemArray) as $item) {
+            $this->moveRecord($item['table'], $item['id'], $destPid);
         }
     }
 
@@ -4872,15 +4916,15 @@ class DataHandler implements LoggerAwareInterface
             return;
         }
 
-        $inlineSubType = $this->getInlineFieldType($config);
-        if ($inlineSubType === false) {
+        $relationFieldType = $this->getRelationFieldType($config);
+        if ($relationFieldType === false) {
             return;
         }
 
         $transOrigRecord = BackendUtility::getRecordWSOL($table, $transOrigPointer);
 
         $removeArray = [];
-        $mmTable = $inlineSubType === 'mm' && isset($config['MM']) && $config['MM'] ? $config['MM'] : '';
+        $mmTable = $relationFieldType === 'mm' && isset($config['MM']) && $config['MM'] ? $config['MM'] : '';
         // Fetch children from original language parent:
         $dbAnalysisOriginal = $this->createRelationHandlerInstance();
         $dbAnalysisOriginal->start($transOrigRecord[$field], $foreignTable, $mmTable, $transOrigRecord['uid'], $table, $config);
@@ -4948,12 +4992,12 @@ class DataHandler implements LoggerAwareInterface
         }
         $updateFields = [];
         // Handle, reorder and store relations:
-        if ($inlineSubType === 'list') {
+        if ($relationFieldType === 'list') {
             $updateFields = [$field => $value];
-        } elseif ($inlineSubType === 'field') {
+        } elseif ($relationFieldType === 'field') {
             $dbAnalysisCurrent->writeForeignField($config, $id);
             $updateFields = [$field => $dbAnalysisCurrent->countItems(false)];
-        } elseif ($inlineSubType === 'mm') {
+        } elseif ($relationFieldType === 'mm') {
             $dbAnalysisCurrent->writeMM($config['MM'], $id);
             $updateFields = [$field => $dbAnalysisCurrent->countItems(false)];
         }
@@ -5492,26 +5536,20 @@ class DataHandler implements LoggerAwareInterface
         if (!isset($conf['type'])) {
             return;
         }
-        if ($conf['type'] === 'inline') {
-            $foreign_table = $conf['foreign_table'];
-            if ($foreign_table) {
-                $inlineType = $this->getInlineFieldType($conf);
-                if ($inlineType === 'list' || $inlineType === 'field') {
-                    $dbAnalysis = $this->createRelationHandlerInstance();
-                    $dbAnalysis->start($value, $conf['foreign_table'], '', $uid, $table, $conf);
-                    $dbAnalysis->undeleteRecord = true;
 
-                    $enableCascadingDelete = true;
-                    // non type save comparison is intended!
-                    if (isset($conf['behaviour']['enableCascadingDelete']) && $conf['behaviour']['enableCascadingDelete'] == false) {
-                        $enableCascadingDelete = false;
-                    }
+        if ($conf['type'] === 'inline' || $conf['type'] === 'file') {
+            if (in_array($this->getRelationFieldType($conf), ['list', 'field'], true)) {
+                $dbAnalysis = $this->createRelationHandlerInstance();
+                $dbAnalysis->start($value, $conf['foreign_table'], '', $uid, $table, $conf);
+                $dbAnalysis->undeleteRecord = true;
 
+                // non type save comparison is intended!
+                if (!isset($conf['behaviour']['enableCascadingDelete'])
+                    || $conf['behaviour']['enableCascadingDelete'] != false
+                ) {
                     // Walk through the items and remove them
                     foreach ($dbAnalysis->itemArray as $v) {
-                        if ($enableCascadingDelete) {
-                            $this->deleteAction($v['table'], $v['id']);
-                        }
+                        $this->deleteAction($v['table'], $v['id']);
                     }
                 }
             }
@@ -5715,11 +5753,9 @@ class DataHandler implements LoggerAwareInterface
                 continue;
             }
             $foreignTable = (string)($fieldConfig['foreign_table'] ?? '');
-            if ($fieldType === 'inline') {
+            if ($fieldType === 'inline' || $fieldType === 'file') {
                 // @todo: Inline MM not handled here, and what about group / select?
-                if ($foreignTable === ''
-                    || !in_array($this->getInlineFieldType($fieldConfig), ['list', 'field'], true)
-                ) {
+                if (!in_array($this->getRelationFieldType($fieldConfig), ['list', 'field'], true)) {
                     continue;
                 }
                 $relationHandler = $this->createRelationHandlerInstance();
@@ -5928,16 +5964,15 @@ class DataHandler implements LoggerAwareInterface
             if (!isset($fieldConfig['type'])) {
                 continue;
             }
-            if ($fieldConfig['type'] === 'inline') {
-                $foreignTable = $fieldConfig['foreign_table'] ?? null;
-                if (!$foreignTable
+            if ($fieldConfig['type'] === 'inline' || $fieldConfig['type'] === 'file') {
+                $foreignTable = (string)($fieldConfig['foreign_table'] ?? '');
+                if ($foreignTable === ''
                      || (isset($fieldConfig['behaviour']['enableCascadingDelete'])
                         && (bool)$fieldConfig['behaviour']['enableCascadingDelete'] === false)
                 ) {
                     continue;
                 }
-                $inlineType = $this->getInlineFieldType($fieldConfig);
-                if ($inlineType === 'list' || $inlineType === 'field') {
+                if (in_array($this->getRelationFieldType($fieldConfig), ['list', 'field'], true)) {
                     $dbAnalysis = $this->createRelationHandlerInstance();
                     $dbAnalysis->start($value, $fieldConfig['foreign_table'], '', (int)$record['uid'], $table, $fieldConfig);
                     $dbAnalysis->undeleteRecord = true;
@@ -6413,6 +6448,9 @@ class DataHandler implements LoggerAwareInterface
                             case 'inline':
                                 $this->remapListedDBRecords_procInline($conf, $value, $uid, $table);
                                 break;
+                            case 'file':
+                                $this->remapListedDBRecords_procFile($conf, $value, $uid, $table);
+                                break;
                             default:
                                 $this->logger->debug('Field type should not appear here: {type}', ['type' => $conf['type']]);
                         }
@@ -6534,10 +6572,10 @@ class DataHandler implements LoggerAwareInterface
     {
         $theUidToUpdate = $this->copyMappingArray_merged[$table][$uid] ?? null;
         if ($conf['foreign_table']) {
-            $inlineType = $this->getInlineFieldType($conf);
-            if ($inlineType === 'mm') {
+            $relationFieldType = $this->getRelationFieldType($conf);
+            if ($relationFieldType === 'mm') {
                 $this->remapListedDBRecords_procDBRefs($conf, $value, $theUidToUpdate, $table);
-            } elseif ($inlineType !== false) {
+            } elseif ($relationFieldType !== false) {
                 $dbAnalysis = $this->createRelationHandlerInstance();
                 $dbAnalysis->start($value, $conf['foreign_table'], '', 0, $table, $conf);
 
@@ -6553,7 +6591,7 @@ class DataHandler implements LoggerAwareInterface
                 }
 
                 // Update child records if using pointer fields ('foreign_field'):
-                if ($inlineType === 'field') {
+                if ($relationFieldType === 'field') {
                     $dbAnalysis->writeForeignField($conf, $uid, $theUidToUpdate);
                 }
                 $thePidToUpdate = null;
@@ -6577,7 +6615,7 @@ class DataHandler implements LoggerAwareInterface
                     }
                     $updateValues = ['pid' => $thePidToUpdate];
                     foreach ($updatePidForRecords as $tableName => $uids) {
-                        if (empty($tableName) || empty($uids)) {
+                        if (empty($tableName)) {
                             continue;
                         }
                         $conn = GeneralUtility::makeInstance(ConnectionPool::class)
@@ -6591,6 +6629,58 @@ class DataHandler implements LoggerAwareInterface
         }
     }
 
+    /**
+     * Performs remapping of old UID values to NEW uid values for an file field.
+     *
+     * @internal should only be used from within DataHandler
+     */
+    public function remapListedDBRecords_procFile($conf, $value, $uid, $table)
+    {
+        $thePidToUpdate = null;
+        $updatePidForRecords = [];
+        $theUidToUpdate = $this->copyMappingArray_merged[$table][$uid] ?? null;
+
+        $dbAnalysis = $this->createRelationHandlerInstance();
+        $dbAnalysis->start($value, $conf['foreign_table'], '', 0, $table, $conf);
+
+        foreach ($dbAnalysis->itemArray as &$item) {
+            $updatePidForRecords[$item['table']][] = $item['id'];
+            $versionedId = $this->getAutoVersionId($item['table'], $item['id']);
+            if ($versionedId !== null) {
+                $updatePidForRecords[$item['table']][] = $versionedId;
+                $item['id'] = $versionedId;
+            }
+        }
+        unset($item);
+
+        $dbAnalysis->writeForeignField($conf, $uid, $theUidToUpdate);
+
+        if ($table === 'pages') {
+            $thePidToUpdate = $theUidToUpdate;
+        } elseif (isset($this->registerDBPids[$table][$uid])) {
+            $thePidToUpdate = $this->registerDBPids[$table][$uid];
+            $thePidToUpdate = $this->copyMappingArray_merged['pages'][$thePidToUpdate];
+        }
+
+        if ($thePidToUpdate && $updatePidForRecords !== []) {
+            $thePidToUpdate = $this->getDefaultLanguagePageId($thePidToUpdate);
+            $liveId = BackendUtility::getLiveVersionIdOfRecord('pages', $theUidToUpdate);
+            if ($liveId !== null) {
+                $thePidToUpdate = $liveId;
+            }
+            $updateValues = ['pid' => $thePidToUpdate];
+            foreach ($updatePidForRecords as $tableName => $uids) {
+                if (empty($tableName)) {
+                    continue;
+                }
+                $conn = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($tableName);
+                foreach ($uids as $updateUid) {
+                    $conn->update($tableName, $updateValues, ['uid' => $updateUid]);
+                }
+            }
+        }
+    }
+
     /**
      * Processes the $this->remapStack at the end of copying, inserting, etc. actions.
      * The remapStack takes care about the correct mapping of new and old uids in case of relational data.
@@ -8658,16 +8748,20 @@ class DataHandler implements LoggerAwareInterface
     }
 
     /**
-     * Returns the subtype as a string of an inline field.
-     * If it's not an inline field at all, it returns FALSE.
+     * Returns the subtype as a string of a relation (inline / file) field.
+     * If it's not a relation field at all, it returns FALSE.
      *
      * @param array $conf Config array for TCA/columns field
      * @return string|bool string Inline subtype (field|mm|list), boolean: FALSE
      * @internal should only be used from within DataHandler
      */
-    public function getInlineFieldType($conf)
+    public function getRelationFieldType($conf): bool|string
     {
-        if (empty($conf['type']) || $conf['type'] !== 'inline' || empty($conf['foreign_table'])) {
+        if (
+            empty($conf['foreign_table'])
+            || !in_array($conf['type'] ?? '', ['inline', 'file'], true)
+            || ($conf['type'] === 'file' && !($conf['foreign_field'] ?? false))
+        ) {
             return false;
         }
         if ($conf['foreign_field'] ?? false) {
@@ -9294,7 +9388,7 @@ class DataHandler implements LoggerAwareInterface
         foreach ($fieldArray as $field => $value) {
             if (!MathUtility::canBeInterpretedAsInteger($value)
                 && isset($GLOBALS['TCA'][$table]['columns'][$field]['config']['type'])
-                && $GLOBALS['TCA'][$table]['columns'][$field]['config']['type'] === 'inline'
+                && in_array($GLOBALS['TCA'][$table]['columns'][$field]['config']['type'], ['inline', 'file'], true)
                 && ($GLOBALS['TCA'][$table]['columns'][$field]['config']['foreign_field'] ?? false)
             ) {
                 $result[$field] = count(GeneralUtility::trimExplode(',', $value, true));
diff --git a/typo3/sysext/core/Classes/DataHandling/Localization/DataMapProcessor.php b/typo3/sysext/core/Classes/DataHandling/Localization/DataMapProcessor.php
index 75009f4658c5..9060487c3c25 100644
--- a/typo3/sysext/core/Classes/DataHandling/Localization/DataMapProcessor.php
+++ b/typo3/sysext/core/Classes/DataHandling/Localization/DataMapProcessor.php
@@ -448,12 +448,12 @@ class DataMapProcessor
                 $item->getId(),
                 [$fieldName => $fromValue]
             );
-        } elseif (!$this->isInlineRelationField($item->getTableName(), $fieldName)) {
+        } elseif (!$this->isReferenceField($item->getTableName(), $fieldName)) {
             // direct relational values
             $this->synchronizeDirectRelations($item, $fieldName, $fromRecord);
         } else {
-            // inline relational values
-            $this->synchronizeInlineRelations($item, $fieldName, $fromRecord, $forRecord);
+            // reference values
+            $this->synchronizeReferences($item, $fieldName, $fromRecord, $forRecord);
         }
     }
 
@@ -518,10 +518,11 @@ class DataMapProcessor
     }
 
     /**
-     * Handle synchronization of inline relations.
-     * Inline Relational Record Editing ("IRRE") always is modelled as 1:n composite relation - which means that
-     * direct(!) children cannot exist without their parent. Removing a relative parent results in cascaded removal
-     * of all direct(!) children as well.
+     * Handle synchronization of references (inline or file).
+     * References are always modelled as 1:n composite relation - which
+     * means that direct(!) children cannot exist without their parent.
+     * Removing a relative parent results in cascaded removal of all direct(!)
+     * children as well.
      *
      * @param DataMapItem $item
      * @param string $fieldName
@@ -529,7 +530,7 @@ class DataMapProcessor
      * @param array $forRecord
      * @throws \RuntimeException
      */
-    protected function synchronizeInlineRelations(DataMapItem $item, string $fieldName, array $fromRecord, array $forRecord)
+    protected function synchronizeReferences(DataMapItem $item, string $fieldName, array $fromRecord, array $forRecord)
     {
         $configuration = $GLOBALS['TCA'][$item->getTableName()]['columns'][$fieldName];
         $isLocalizationModeExclude = ($configuration['l10n_mode'] ?? null) === 'exclude';
@@ -1509,18 +1510,18 @@ class DataMapProcessor
                 && !empty($configuration['foreign_table'])
                 && !empty($GLOBALS['TCA'][$configuration['foreign_table']])
             )
-            || $this->isInlineRelationField($tableName, $fieldName)
+            || $this->isReferenceField($tableName, $fieldName)
         ;
     }
 
     /**
-     * True if we're dealing with an inline field
+     * True if we're dealing with a reference field (either "inline" or "file")
      *
      * @param string $tableName
      * @param string $fieldName
      * @return bool TRUE if field is of type inline with foreign_table set
      */
-    protected function isInlineRelationField(string $tableName, string $fieldName): bool
+    protected function isReferenceField(string $tableName, string $fieldName): bool
     {
         if (empty($GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config']['type'])) {
             return false;
@@ -1529,7 +1530,7 @@ class DataMapProcessor
         $configuration = $GLOBALS['TCA'][$tableName]['columns'][$fieldName]['config'];
 
         return
-            $configuration['type'] === 'inline'
+            ($configuration['type'] === 'inline' || $configuration['type'] === 'file')
             && !empty($configuration['foreign_table'])
             && !empty($GLOBALS['TCA'][$configuration['foreign_table']])
         ;
diff --git a/typo3/sysext/core/Classes/DataHandling/TableColumnType.php b/typo3/sysext/core/Classes/DataHandling/TableColumnType.php
index 45e184e2dbd1..86c2be2fe6e5 100644
--- a/typo3/sysext/core/Classes/DataHandling/TableColumnType.php
+++ b/typo3/sysext/core/Classes/DataHandling/TableColumnType.php
@@ -49,6 +49,7 @@ final class TableColumnType extends Enumeration
     const DATETIME = 'DATETIME';
     const COLOR = 'COLOR';
     const NUMBER = 'NUMBER';
+    const FILE = 'FILE';
 
     /**
      * @param mixed $type
diff --git a/typo3/sysext/core/Classes/Database/ReferenceIndex.php b/typo3/sysext/core/Classes/Database/ReferenceIndex.php
index 5d8a33643ad6..e1198823ff24 100644
--- a/typo3/sysext/core/Classes/Database/ReferenceIndex.php
+++ b/typo3/sysext/core/Classes/Database/ReferenceIndex.php
@@ -581,7 +581,7 @@ class ReferenceIndex implements LoggerAwareInterface
         if (empty($conf)) {
             return false;
         }
-        if ($conf['type'] === 'inline' && !empty($conf['foreign_table']) && empty($conf['MM'])) {
+        if (($conf['type'] === 'inline' || $conf['type'] === 'file') && !empty($conf['foreign_table']) && empty($conf['MM'])) {
             $dbAnalysis = GeneralUtility::makeInstance(RelationHandler::class);
             $dbAnalysis->setUseLiveReferenceIds(false);
             $dbAnalysis->setWorkspaceId($this->getWorkspaceId());
@@ -860,7 +860,7 @@ class ReferenceIndex implements LoggerAwareInterface
         return
             $configuration['type'] === 'group'
             || (
-                in_array($configuration['type'], ['select', 'category', 'inline'], true)
+                in_array($configuration['type'], ['select', 'category', 'inline', 'file'], true)
                 && !empty($configuration['foreign_table'])
             );
     }
diff --git a/typo3/sysext/core/Classes/Database/RelationHandler.php b/typo3/sysext/core/Classes/Database/RelationHandler.php
index a5bfc49680fe..a7540d45b163 100644
--- a/typo3/sysext/core/Classes/Database/RelationHandler.php
+++ b/typo3/sysext/core/Classes/Database/RelationHandler.php
@@ -405,7 +405,7 @@ class RelationHandler
             }
 
             // Skip if not dealing with IRRE in a CSV list on a workspace
-            if (!isset($configuration['type']) || $configuration['type'] !== 'inline'
+            if (!isset($configuration['type']) || ($configuration['type'] !== 'inline' && $configuration['type'] !== 'file')
                 || empty($configuration['foreign_table']) || !empty($configuration['foreign_field'])
                 || !empty($configuration['MM']) || count($this->tableArray) !== 1 || empty($this->tableArray[$configuration['foreign_table']])
                 || $this->getWorkspaceId() === 0 || !BackendUtility::isTableWorkspaceEnabled($configuration['foreign_table'])
diff --git a/typo3/sysext/core/Classes/Migrations/TcaMigration.php b/typo3/sysext/core/Classes/Migrations/TcaMigration.php
index 42ee3355fc64..1542bf33e44d 100644
--- a/typo3/sysext/core/Classes/Migrations/TcaMigration.php
+++ b/typo3/sysext/core/Classes/Migrations/TcaMigration.php
@@ -18,6 +18,7 @@ declare(strict_types=1);
 namespace TYPO3\CMS\Core\Migrations;
 
 use TYPO3\CMS\Core\Database\Query\QueryHelper;
+use TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\MathUtility;
 
@@ -81,7 +82,10 @@ class TcaMigration
         $tca = $this->migrateRenderTypeColorpickerToTypeColor($tca);
         $tca = $this->migrateEvalIntAndDouble2ToTypeNumber($tca);
         $tca = $this->removeAlwaysDescription($tca);
+        $tca = $this->migrateFalHandlingInInlineToTypeFile($tca);
         $tca = $this->removeCtrlCruserId($tca);
+        $tca = $this->removeFalRelatedElementBrowserOptions($tca);
+        $tca = $this->removeFalRelatedOptionsFromTypeInline($tca);
 
         return $tca;
     }
@@ -957,7 +961,7 @@ class TcaMigration
                     continue;
                 }
 
-                // Set the TCA type to "link"
+                // Set the TCA type to "color"
                 $tca[$table]['columns'][$fieldName]['config']['type'] = 'color';
 
                 // Unset "renderType", "max" and "eval"
@@ -1149,4 +1153,224 @@ class TcaMigration
         }
         return $tca;
     }
+
+    /**
+     * Migrates type='inline' with foreign_table='sys_file_reference' to type='file'.
+     * Removes table relation related options.
+     * Removes no longer available appearance options.
+     * Detects usage of "customControls" hook.
+     * Migrates renamed appearance options.
+     * Migrates allowed file extensions.
+     */
+    protected function migrateFalHandlingInInlineToTypeFile(array $tca): array
+    {
+        foreach ($tca as $table => &$tableDefinition) {
+            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'] ?? false)) {
+                continue;
+            }
+
+            foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
+                if (($fieldConfig['config']['type'] ?? '') !== 'inline'
+                    || ($fieldConfig['config']['foreign_table'] ?? '') !== 'sys_file_reference'
+                ) {
+                    // Early return in case column is not of type=inline with foreign_table=sys_file_reference
+                    continue;
+                }
+
+                // Place to add additional information, which will later be appended to the deprecation message
+                $additionalInformation = '';
+
+                // Set the TCA type to "file"
+                $fieldConfig['config']['type'] = 'file';
+
+                // Remove table relation related options, since they are
+                // either not needed anymore or set by TcaPreperation automatically.
+                unset(
+                    $fieldConfig['config']['foreign_table'],
+                    $fieldConfig['config']['foreign_field'],
+                    $fieldConfig['config']['foreign_sortby'],
+                    $fieldConfig['config']['foreign_table_field'],
+                    $fieldConfig['config']['foreign_match_fields'],
+                    $fieldConfig['config']['foreign_label'],
+                    $fieldConfig['config']['foreign_selector'],
+                    $fieldConfig['config']['foreign_unique'],
+                );
+
+                // "new" control is not supported for this type so remove it altogether for cleaner TCA
+                unset($fieldConfig['config']['appearance']['enabledControls']['new']);
+
+                // [appearance][headerThumbnail][field] is not needed anymore
+                unset($fieldConfig['config']['appearance']['headerThumbnail']['field']);
+
+                // A couple of further appearance options are not supported by type "file", unset them as well
+                unset(
+                    $fieldConfig['config']['appearance']['showNewRecordLink'],
+                    $fieldConfig['config']['appearance']['newRecordLinkAddTitle'],
+                    $fieldConfig['config']['appearance']['newRecordLinkTitle'],
+                    $fieldConfig['config']['appearance']['levelLinksPosition'],
+                    $fieldConfig['config']['appearance']['useCombination'],
+                    $fieldConfig['config']['appearance']['suppressCombinationWarning']
+                );
+
+                // Migrate [appearance][showPossibleRecordsSelector] to [appearance][showFileSelectors]
+                if (isset($fieldConfig['config']['appearance']['showPossibleRecordsSelector'])) {
+                    $fieldConfig['config']['appearance']['showFileSelectors'] = $fieldConfig['config']['appearance']['showPossibleRecordsSelector'];
+                    unset($fieldConfig['config']['appearance']['showPossibleRecordsSelector']);
+                }
+
+                // "customControls" hook has been replaced by the CustomFileControlsEvent
+                if (isset($fieldConfig['config']['customControls'])) {
+                    $additionalInformation .= ' The \'customControls\' option is not evaluated anymore and has '
+                        . 'to be replaced with the PSR-14 \'CustomFileControlsEvent\'.';
+                    unset($fieldConfig['config']['customControls']);
+                }
+
+                // Migrate element browser related settings
+                if (!empty($fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config']['appearance'])) {
+                    if (!empty($fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config']['appearance']['elementBrowserAllowed'])) {
+                        // Migrate "allowed" file extensions from appearance
+                        $fieldConfig['config']['allowed'] = $fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config']['appearance']['elementBrowserAllowed'];
+                    }
+                    unset(
+                        $fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config']['appearance']['elementBrowserType'],
+                        $fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config']['appearance']['elementBrowserAllowed']
+                    );
+                    if (empty($fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config']['appearance'])) {
+                        unset($fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config']['appearance']);
+                        if (empty($fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config'])) {
+                            unset($fieldConfig['config']['overrideChildTca']['columns']['uid_local']['config']);
+                            if (empty($fieldConfig['config']['overrideChildTca']['columns']['uid_local'])) {
+                                unset($fieldConfig['config']['overrideChildTca']['columns']['uid_local']);
+                                if (empty($fieldConfig['config']['overrideChildTca']['columns'])) {
+                                    unset($fieldConfig['config']['overrideChildTca']['columns']);
+                                    if (empty($fieldConfig['config']['overrideChildTca'])) {
+                                        unset($fieldConfig['config']['overrideChildTca']);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                // Migrate file extension filter
+                if (!empty($fieldConfig['config']['filter'])) {
+                    foreach ($fieldConfig['config']['filter'] as $key => $filter) {
+                        if (($filter['userFunc'] ?? '') === (FileExtensionFilter::class . '->filterInlineChildren')) {
+                            $allowedFileExtensions = (string)($filter['parameters']['allowedFileExtensions'] ?? '');
+                            // Note: Allowed file extensions in the filter take precedence over possible
+                            // extensions defined for the element browser. This is due to filters are evaluated
+                            // by the DataHandler while element browser is only applied in FormEngine UI.
+                            if ($allowedFileExtensions !== '') {
+                                $fieldConfig['config']['allowed'] = $allowedFileExtensions;
+                            }
+                            $disallowedFileExtensions = (string)($filter['parameters']['disallowedFileExtensions'] ?? '');
+                            if ($disallowedFileExtensions !== '') {
+                                $fieldConfig['config']['disallowed'] = $disallowedFileExtensions;
+                            }
+                            unset($fieldConfig['config']['filter'][$key]);
+                        }
+                    }
+                    // Remove filter if it got empty
+                    if (empty($fieldConfig['config']['filter'])) {
+                        unset($fieldConfig['config']['filter']);
+                    }
+                }
+
+                $this->messages[] = 'The TCA field \'' . $fieldName . '\' of table \'' . $table . '\' defines '
+                    . 'type="inline" with foreign_table=sys_file_reference. The field has therefore been '
+                    . 'migrated to the dedicated TCA type \'file\'. This includes corresponding migration of '
+                    . 'the table mapping fields and filters, which were usually added to the field using the '
+                    . 'ExtensionManagementUtility::getFileFieldTCAConfig().' . $additionalInformation . ' '
+                    . 'Please adjust your TCA accordingly.';
+            }
+        }
+
+        return $tca;
+    }
+
+    /**
+     * Removes the [appearance][elementBrowserType] and [appearance][elementBrowserAllowed]
+     * options from TCA type "group" fields.
+     */
+    protected function removeFalRelatedElementBrowserOptions(array $tca): array
+    {
+        foreach ($tca as $table => &$tableDefinition) {
+            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'] ?? false)) {
+                continue;
+            }
+
+            foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
+                if (($fieldConfig['config']['type'] ?? '') !== 'group'
+                    || (
+                        !isset($fieldConfig['config']['appearance']['elementBrowserType'])
+                        && !isset($fieldConfig['config']['appearance']['elementBrowserAllowed'])
+                    )
+                ) {
+                    // Early return in case column is not of type=group or does not define the options in question
+                    continue;
+                }
+
+                unset(
+                    $fieldConfig['config']['appearance']['elementBrowserType'],
+                    $fieldConfig['config']['appearance']['elementBrowserAllowed']
+                );
+
+                // Also unset "appearance" if empty
+                if (empty($fieldConfig['config']['appearance'])) {
+                    unset($fieldConfig['config']['appearance']);
+                }
+
+                $this->messages[] = 'The TCA field \'' . $fieldName . '\' of table \'' . $table . '\' defines '
+                    . 'fal related element browser options, which are no longer needed and therefore removed. '
+                    . 'Please adjust your TCA accordingly.';
+            }
+        }
+
+        return $tca;
+    }
+
+    /**
+     * Removes the following options from TCA type "inline" fields:
+     * - [appearance][headerThumbnail]
+     * - [appearance][fileUploadAllowed]
+     * - [appearance][fileByUrlAllowed]
+     */
+    protected function removeFalRelatedOptionsFromTypeInline(array $tca): array
+    {
+        foreach ($tca as $table => &$tableDefinition) {
+            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'] ?? false)) {
+                continue;
+            }
+
+            foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
+                if (($fieldConfig['config']['type'] ?? '') !== 'inline'
+                    || (
+                        !isset($fieldConfig['config']['appearance']['headerThumbnail'])
+                        && !isset($fieldConfig['config']['appearance']['fileUploadAllowed'])
+                        && !isset($fieldConfig['config']['appearance']['fileByUrlAllowed'])
+                    )
+                ) {
+                    // Early return in case column is not of type=inline or does not define the options in question
+                    continue;
+                }
+
+                unset(
+                    $fieldConfig['config']['appearance']['headerThumbnail'],
+                    $fieldConfig['config']['appearance']['fileUploadAllowed'],
+                    $fieldConfig['config']['appearance']['fileByUrlAllowed']
+                );
+
+                // Also unset "appearance" if empty
+                if (empty($fieldConfig['config']['appearance'])) {
+                    unset($fieldConfig['config']['appearance']);
+                }
+
+                $this->messages[] = 'The TCA field \'' . $fieldName . '\' of table \'' . $table . '\' defines '
+                    . 'fal related appearance options, which are no longer evaluated and therefore removed. '
+                    . 'Please adjust your TCA accordingly.';
+            }
+        }
+
+        return $tca;
+    }
 }
diff --git a/typo3/sysext/core/Classes/Preparations/TcaPreparation.php b/typo3/sysext/core/Classes/Preparations/TcaPreparation.php
index da0e3196842e..3bf79c2892ea 100644
--- a/typo3/sysext/core/Classes/Preparations/TcaPreparation.php
+++ b/typo3/sysext/core/Classes/Preparations/TcaPreparation.php
@@ -17,6 +17,8 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Core\Preparations;
 
+use TYPO3\CMS\Core\Utility\StringUtility;
+
 /**
  * Prepare TCA. Used in bootstrap and Flex Form Data Structures.
  *
@@ -41,6 +43,7 @@ class TcaPreparation
     public function prepare(array $tca): array
     {
         $tca = $this->configureCategoryRelations($tca);
+        $tca = $this->configureFileReferences($tca);
         return $tca;
     }
 
@@ -165,4 +168,73 @@ class TcaPreparation
 
         return $tca;
     }
+
+    protected function configureFileReferences(array $tca): array
+    {
+        foreach ($tca as $table => &$tableDefinition) {
+            if (!isset($tableDefinition['columns']) || !is_array($tableDefinition['columns'])) {
+                continue;
+            }
+            foreach ($tableDefinition['columns'] as $fieldName => &$fieldConfig) {
+                if (($fieldConfig['config']['type'] ?? '') !== 'file') {
+                    continue;
+                }
+
+                // Set static values for this type. Most of them are not needed due to the
+                // dedicated TCA type. However a lot of underlying code in DataHandler and
+                // friends relies on those keys, especially "foreign_table" and "foreign_selector".
+                // @todo Check which of those values can be removed since only used by FormEngine
+                $fieldConfig['config'] = array_replace_recursive(
+                    $fieldConfig['config'],
+                    [
+                        'foreign_table' => 'sys_file_reference',
+                        'foreign_field' => 'uid_foreign',
+                        'foreign_sortby' => 'sorting_foreign',
+                        'foreign_table_field' => 'tablenames',
+                        'foreign_match_fields' => [
+                            'fieldname' => $fieldName,
+                        ],
+                        'foreign_label' => 'uid_local',
+                        'foreign_selector' => 'uid_local',
+                    ]
+                );
+
+                if (!empty(($allowed = ($fieldConfig['config']['allowed'] ?? null)))) {
+                    $fieldConfig['config']['allowed'] = self::prepareFileExtensions($allowed);
+                }
+                if (!empty(($disallowed = ($fieldConfig['config']['disallowed'] ?? null)))) {
+                    $fieldConfig['config']['disallowed'] = self::prepareFileExtensions($disallowed);
+                }
+            }
+        }
+
+        return $tca;
+    }
+
+    /**
+     * Ensures format, replaces placeholders and remove duplicates
+     *
+     * @todo Does not need to be static, once FlexFormTools calls configureFileReferences() directly
+     */
+    public static function prepareFileExtensions(mixed $fileExtensions): string
+    {
+        if (is_array($fileExtensions)) {
+            $fileExtensions = implode(',', $fileExtensions);
+        } else {
+            $fileExtensions = (string)$fileExtensions;
+        }
+
+        // Replace placeholders with the corresponding $GLOBALS value for now
+        if (preg_match_all('/common-(image|text|media)-types/', $fileExtensions, $matches)) {
+            foreach ($matches[1] as $key => $type) {
+                $fileExtensions = str_replace(
+                    $matches[0][$key],
+                    $GLOBALS['TYPO3_CONF_VARS'][$type === 'image' ? 'GFX' : 'SYS'][$type . 'file_ext'] ?? '',
+                    $fileExtensions
+                );
+            }
+        }
+
+        return StringUtility::uniqueList($fileExtensions);
+    }
 }
diff --git a/typo3/sysext/core/Classes/Resource/Filter/FileExtensionFilter.php b/typo3/sysext/core/Classes/Resource/Filter/FileExtensionFilter.php
index 0d28f856602a..696fc2c0e714 100644
--- a/typo3/sysext/core/Classes/Resource/Filter/FileExtensionFilter.php
+++ b/typo3/sysext/core/Classes/Resource/Filter/FileExtensionFilter.php
@@ -1,5 +1,7 @@
 <?php
 
+declare(strict_types=1);
+
 /*
  * This file is part of the TYPO3 CMS project.
  *
@@ -15,9 +17,10 @@
 
 namespace TYPO3\CMS\Core\Resource\Filter;
 
+use TYPO3\CMS\Backend\RecordList\DatabaseRecordList;
 use TYPO3\CMS\Core\DataHandling\DataHandler;
 use TYPO3\CMS\Core\Resource\Driver\DriverInterface;
-use TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException;
+use TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException;
 use TYPO3\CMS\Core\Resource\ResourceFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
@@ -29,56 +32,78 @@ class FileExtensionFilter
     /**
      * Allowed file extensions. If NULL, all extensions are allowed.
      *
-     * @var array
+     * @var string[]|null
      */
-    protected $allowedFileExtensions;
+    protected ?array $allowedFileExtensions = null;
 
     /**
      * Disallowed file extensions. If NULL, no extension is disallowed (i.e. all are allowed).
      *
-     * @var array
+     * @var string[]|null
      */
-    protected $disallowedFileExtensions;
+    protected ?array $disallowedFileExtensions = null;
+
+    public function filter(
+        array $references,
+        string $allowedFileExtensions,
+        string $disallowedFileExtensions,
+        DataHandler|DatabaseRecordList $dataHandler
+    ): array {
+        if ($allowedFileExtensions !== '') {
+            $this->setAllowedFileExtensions($allowedFileExtensions);
+        }
+        if ($disallowedFileExtensions !== '') {
+            $this->setDisallowedFileExtensions($disallowedFileExtensions);
+        }
+
+        $cleanReferences = [];
+        foreach ($references as $reference) {
+            if (empty($reference)) {
+                continue;
+            }
+            $parts = GeneralUtility::revExplode('_', (string)$reference, 2);
+            $fileReferenceUid = $parts[count($parts) - 1];
+            try {
+                $fileReference = GeneralUtility::makeInstance(ResourceFactory::class)->getFileReferenceObject($fileReferenceUid);
+                $file = $fileReference->getOriginalFile();
+                if ($this->isAllowed($file->getExtension())) {
+                    $cleanReferences[] = $reference;
+                } else {
+                    // Remove the erroneously created reference record again
+                    $dataHandler->deleteAction('sys_file_reference', $fileReferenceUid);
+                }
+            } catch (ResourceDoesNotExistException $e) {
+                // do nothing
+            }
+        }
+        return $cleanReferences;
+    }
 
     /**
      * Entry method for use as DataHandler "inline" field filter
      *
      * @param array $parameters
-     * @param DataHandler $dataHandler
+     * @param DataHandler|DatabaseRecordList $dataHandler
      * @return array
+     * @deprecated Will be removed in TYPO3 v13. Use filterFileReferences() directly instead.
      */
-    public function filterInlineChildren(array $parameters, DataHandler $dataHandler)
+    public function filterInlineChildren(array $parameters, DataHandler|DatabaseRecordList $dataHandler): array
     {
-        $values = $parameters['values'];
-        if ($parameters['allowedFileExtensions'] ?? false) {
-            $this->setAllowedFileExtensions($parameters['allowedFileExtensions']);
-        }
-        if ($parameters['disallowedFileExtensions'] ?? false) {
-            $this->setDisallowedFileExtensions($parameters['disallowedFileExtensions']);
-        }
-        $cleanValues = [];
-        if (is_array($values)) {
-            foreach ($values as $value) {
-                if (empty($value)) {
-                    continue;
-                }
-                $parts = GeneralUtility::revExplode('_', (string)$value, 2);
-                $fileReferenceUid = $parts[count($parts) - 1];
-                try {
-                    $fileReference = GeneralUtility::makeInstance(ResourceFactory::class)->getFileReferenceObject($fileReferenceUid);
-                    $file = $fileReference->getOriginalFile();
-                    if ($this->isAllowed($file->getExtension())) {
-                        $cleanValues[] = $value;
-                    } else {
-                        // Remove the erroneously created reference record again
-                        $dataHandler->deleteAction('sys_file_reference', $fileReferenceUid);
-                    }
-                } catch (FileDoesNotExistException $e) {
-                    // do nothing
-                }
-            }
+        trigger_error(
+            'FileExtensionFilter->filterInlineChildren() will be removed in TYPO3 v13.0. Use FileExtensionFilter->filter() instead.',
+            E_USER_DEPRECATED
+        );
+
+        $references = $parameters['values'] ?? [];
+        if (!is_array($references)) {
+            $references = [];
         }
-        return $cleanValues;
+        return $this->filter(
+            $references,
+            (string)($parameters['allowedFileExtensions'] ?? ''),
+            (string)($parameters['disallowedFileExtensions'] ?? ''),
+            $dataHandler
+        );
     }
 
     /**
@@ -108,7 +133,7 @@ class FileExtensionFilter
             } catch (\InvalidArgumentException $e) {
                 $fileInfo = [];
             }
-            if (!$this->isAllowed($fileInfo['extension'] ?? '')) {
+            if (!$this->isAllowed((string)($fileInfo['extension'] ?? ''))) {
                 $returnCode = -1;
             }
         }
@@ -118,20 +143,18 @@ class FileExtensionFilter
     /**
      * Checks whether a file is allowed according to the criteria defined in the class variables ($this->allowedFileExtensions etc.)
      *
-     * @param string $fileExt
-     * @return bool
      * @internal this is used internally for TYPO3 core only
      */
-    public function isAllowed($fileExt)
+    public function isAllowed(string $fileExtension): bool
     {
-        $fileExt = strtolower($fileExt);
+        $fileExtension = strtolower($fileExtension);
         $result = true;
         // Check allowed file extensions
-        if ($this->allowedFileExtensions !== null && !empty($this->allowedFileExtensions) && !in_array($fileExt, $this->allowedFileExtensions)) {
+        if (!empty($this->allowedFileExtensions) && !in_array($fileExtension, $this->allowedFileExtensions, true)) {
             $result = false;
         }
         // Check disallowed file extensions
-        if ($this->disallowedFileExtensions !== null && !empty($this->disallowedFileExtensions) && in_array($fileExt, $this->disallowedFileExtensions)) {
+        if (!empty($this->disallowedFileExtensions) && in_array($fileExtension, $this->disallowedFileExtensions, true)) {
             $result = false;
         }
         return $result;
@@ -140,9 +163,9 @@ class FileExtensionFilter
     /**
      * Set allowed file extensions
      *
-     * @param mixed $allowedFileExtensions  Comma-separated list or array, of allowed file extensions
+     * @param mixed $allowedFileExtensions Comma-separated list or array, of allowed file extensions
      */
-    public function setAllowedFileExtensions($allowedFileExtensions)
+    public function setAllowedFileExtensions(mixed $allowedFileExtensions): void
     {
         $this->allowedFileExtensions = $this->convertToLowercaseArray($allowedFileExtensions);
     }
@@ -150,9 +173,9 @@ class FileExtensionFilter
     /**
      * Set disallowed file extensions
      *
-     * @param mixed $disallowedFileExtensions  Comma-separated list or array, of allowed file extensions
+     * @param mixed $disallowedFileExtensions Comma-separated list or array, of allowed file extensions
      */
-    public function setDisallowedFileExtensions($disallowedFileExtensions)
+    public function setDisallowedFileExtensions(mixed $disallowedFileExtensions): void
     {
         $this->disallowedFileExtensions = $this->convertToLowercaseArray($disallowedFileExtensions);
     }
@@ -161,11 +184,8 @@ class FileExtensionFilter
      * Converts mixed (string or array) input arguments into an array, NULL if empty.
      *
      * All array values will be converted to lower case.
-     *
-     * @param mixed $inputArgument Comma-separated list or array.
-     * @return array
      */
-    protected function convertToLowercaseArray($inputArgument)
+    protected function convertToLowercaseArray(mixed $inputArgument): ?array
     {
         $returnValue = null;
         if (is_array($inputArgument)) {
diff --git a/typo3/sysext/core/Classes/Resource/Processing/FileDeletionAspect.php b/typo3/sysext/core/Classes/Resource/Processing/FileDeletionAspect.php
index 7d15c2b9f79a..72dfd9fd8856 100644
--- a/typo3/sysext/core/Classes/Resource/Processing/FileDeletionAspect.php
+++ b/typo3/sysext/core/Classes/Resource/Processing/FileDeletionAspect.php
@@ -72,7 +72,6 @@ final class FileDeletionAspect
                     'sys_file_reference',
                     [
                         'uid_local' => (int)$fileObject->getUid(),
-                        'table_local' => 'sys_file',
                     ]
                 );
         } elseif ($fileObject instanceof ProcessedFile) {
diff --git a/typo3/sysext/core/Classes/Resource/Service/UserFileInlineLabelService.php b/typo3/sysext/core/Classes/Resource/Service/UserFileInlineLabelService.php
index 9d2c30757a43..0a0d182f5382 100644
--- a/typo3/sysext/core/Classes/Resource/Service/UserFileInlineLabelService.php
+++ b/typo3/sysext/core/Classes/Resource/Service/UserFileInlineLabelService.php
@@ -24,9 +24,19 @@ use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
 
 /**
  * User file inline label service
+ *
+ * @deprecated since v12, will be removed in v13.
  */
 class UserFileInlineLabelService
 {
+    public function __construct()
+    {
+        trigger_error(
+            'Class ' . __CLASS__ . ' has been deprecated in v12 and will be removed with v13.',
+            E_USER_DEPRECATED
+        );
+    }
+
     /**
      * Get the user function label for the file_reference table
      *
diff --git a/typo3/sysext/core/Classes/Tree/TableConfiguration/DatabaseTreeDataProvider.php b/typo3/sysext/core/Classes/Tree/TableConfiguration/DatabaseTreeDataProvider.php
index a7d4b4702311..f34953c5bc0f 100644
--- a/typo3/sysext/core/Classes/Tree/TableConfiguration/DatabaseTreeDataProvider.php
+++ b/typo3/sysext/core/Classes/Tree/TableConfiguration/DatabaseTreeDataProvider.php
@@ -380,7 +380,7 @@ class DatabaseTreeDataProvider extends AbstractTableConfigurationTreeDataProvide
     protected function getChildrenUidsFromParentRelation(array $row): array
     {
         $uid = $row['uid'];
-        if (in_array($this->columnConfiguration['type'] ?? '', ['select', 'category', 'inline'], true)) {
+        if (in_array($this->columnConfiguration['type'] ?? '', ['select', 'category', 'inline', 'file'], true)) {
             if ($this->columnConfiguration['MM'] ?? null) {
                 $dbGroup = GeneralUtility::makeInstance(RelationHandler::class);
                 // Dummy field for setting "look from other site"
@@ -409,6 +409,7 @@ class DatabaseTreeDataProvider extends AbstractTableConfigurationTreeDataProvide
         $value = (string)$row[$this->getLookupField()];
         switch ((string)$this->columnConfiguration['type']) {
             case 'inline':
+            case 'file':
                 // Intentional fall-through
             case 'select':
             case 'category':
diff --git a/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php b/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php
index 3fd875184aea..d40081a22d7a 100644
--- a/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php
+++ b/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php
@@ -28,7 +28,6 @@ use TYPO3\CMS\Core\Package\Cache\PackageDependentCacheIdentifier;
 use TYPO3\CMS\Core\Package\Exception as PackageException;
 use TYPO3\CMS\Core\Package\PackageManager;
 use TYPO3\CMS\Core\Preparations\TcaPreparation;
-use TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter;
 
 /**
  * Extension Management functions
@@ -534,57 +533,19 @@ class ExtensionManagementUtility
      * @param string $disallowedFileExtensions Comma-separated list of disallowed file extensions (e.g. "doc,docx")
      *
      * @return array
+     * @deprecated since TYPO3 v12.0. Use the TCA type "file" directly
      */
     public static function getFileFieldTCAConfig(string $fieldName, array $customSettingOverride = [], string $allowedFileExtensions = '', string $disallowedFileExtensions = ''): array
     {
+        trigger_error(
+            'ExtensionManagementUtility::getFileFieldTCAConfig() will be removed in TYPO3 v13.0. Use TCA type "file" directly instead.',
+            E_USER_DEPRECATED
+        );
+
         $fileFieldTCAConfig = [
-            'type' => 'inline',
-            'foreign_table' => 'sys_file_reference',
-            'foreign_field' => 'uid_foreign',
-            'foreign_sortby' => 'sorting_foreign',
-            'foreign_table_field' => 'tablenames',
-            'foreign_match_fields' => [
-                'fieldname' => $fieldName,
-            ],
-            'foreign_label' => 'uid_local',
-            'foreign_selector' => 'uid_local',
-            'overrideChildTca' => [
-                'columns' => [
-                    'uid_local' => [
-                        'config' => [
-                            'appearance' => [
-                                'elementBrowserType' => 'file',
-                                'elementBrowserAllowed' => $allowedFileExtensions,
-                            ],
-                        ],
-                    ],
-                ],
-            ],
-            'filter' => [
-                [
-                    'userFunc' => FileExtensionFilter::class . '->filterInlineChildren',
-                    'parameters' => [
-                        'allowedFileExtensions' => $allowedFileExtensions,
-                        'disallowedFileExtensions' => $disallowedFileExtensions,
-                    ],
-                ],
-            ],
-            'appearance' => [
-                'useSortable' => true,
-                'headerThumbnail' => [
-                    'field' => 'uid_local',
-                    'height' => '45m',
-                ],
-
-                'enabledControls' => [
-                    'info' => true,
-                    'new' => false,
-                    'dragdrop' => true,
-                    'sort' => false,
-                    'hide' => true,
-                    'delete' => true,
-                ],
-            ],
+            'type' => 'file',
+            'allowed' => $allowedFileExtensions,
+            'disallowed'=> $disallowedFileExtensions,
         ];
         ArrayUtility::mergeRecursiveWithOverrule($fileFieldTCAConfig, $customSettingOverride);
         return $fileFieldTCAConfig;
diff --git a/typo3/sysext/core/Classes/Utility/RootlineUtility.php b/typo3/sysext/core/Classes/Utility/RootlineUtility.php
index 512b06d280aa..9567325197af 100644
--- a/typo3/sysext/core/Classes/Utility/RootlineUtility.php
+++ b/typo3/sysext/core/Classes/Utility/RootlineUtility.php
@@ -286,7 +286,7 @@ class RootlineUtility
         if (!empty($configuration['MM']) && !empty($configuration['type']) && in_array($configuration['type'], ['select', 'inline', 'group'])) {
             return true;
         }
-        if (!empty($configuration['foreign_field']) && !empty($configuration['type']) && in_array($configuration['type'], ['select', 'inline'])) {
+        if (!empty($configuration['foreign_field']) && !empty($configuration['type']) && in_array($configuration['type'], ['select', 'inline', 'file'])) {
             return true;
         }
         if (($configuration['type'] ?? '') === 'category' && ($configuration['relationship'] ?? '') === 'manyToMany') {
diff --git a/typo3/sysext/core/Configuration/DefaultConfiguration.php b/typo3/sysext/core/Configuration/DefaultConfiguration.php
index 1149a5832762..cd04f4aef107 100644
--- a/typo3/sysext/core/Configuration/DefaultConfiguration.php
+++ b/typo3/sysext/core/Configuration/DefaultConfiguration.php
@@ -665,6 +665,11 @@ return [
                             \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInlineConfiguration::class,
                         ],
                     ],
+                    \TYPO3\CMS\Backend\Form\FormDataProvider\TcaFiles::class => [
+                        'depends' => [
+                            \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline::class,
+                        ],
+                    ],
                     \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInputPlaceholders::class => [
                         'depends' => [
                             \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInlineConfiguration::class,
@@ -890,6 +895,11 @@ return [
                             \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInlineConfiguration::class,
                         ],
                     ],
+                    \TYPO3\CMS\Backend\Form\FormDataProvider\TcaFiles::class => [
+                        'depends' => [
+                            \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline::class,
+                        ],
+                    ],
                     \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInputPlaceholders::class => [
                         'depends' => [
                             \TYPO3\CMS\Backend\Form\FormDataProvider\SiteResolving::class,
@@ -976,6 +986,11 @@ return [
                             \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInlineConfiguration::class,
                         ],
                     ],
+                    \TYPO3\CMS\Backend\Form\FormDataProvider\TcaFiles::class => [
+                        'depends' => [
+                            \TYPO3\CMS\Backend\Form\FormDataProvider\TcaInline::class,
+                        ],
+                    ],
                 ],
                 'siteConfiguration' => [
                     \TYPO3\CMS\Backend\Form\FormDataProvider\InitializeProcessedTca::class => [],
diff --git a/typo3/sysext/core/Configuration/TCA/be_users.php b/typo3/sysext/core/Configuration/TCA/be_users.php
index fe22a0bd9b2c..0bcf831bdbe5 100644
--- a/typo3/sysext/core/Configuration/TCA/be_users.php
+++ b/typo3/sysext/core/Configuration/TCA/be_users.php
@@ -97,11 +97,11 @@ return [
         ],
         'avatar' => [
             'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_users.avatar',
-            'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
-                'avatar',
-                ['maxitems' => 1],
-                $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
-            ),
+            'config' => [
+                'type' => 'file',
+                'maxitems' => 1,
+                'allowed' => 'common-image-types',
+            ],
         ],
         'db_mountpoints' => [
             'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_users.options_db_mounts',
diff --git a/typo3/sysext/core/Configuration/TCA/pages.php b/typo3/sysext/core/Configuration/TCA/pages.php
index 2307c76a3f1e..530f784a744b 100644
--- a/typo3/sysext/core/Configuration/TCA/pages.php
+++ b/typo3/sysext/core/Configuration/TCA/pages.php
@@ -671,49 +671,47 @@ return [
         'media' => [
             'exclude' => true,
             'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:pages.media',
-            'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
-                'media',
-                [
-                    // Use the imageoverlayPalette instead of the basicoverlayPalette
-                    'overrideChildTca' => [
-                        'types' => [
-                            '0' => [
-                                'showitem' => '
+            'config' => [
+                'type' => 'file',
+                'behaviour' => [
+                    'allowLanguageSynchronization' => true,
+                ],
+                // Use the imageoverlayPalette instead of the basicoverlayPalette
+                'overrideChildTca' => [
+                    'types' => [
+                        '0' => [
+                            'showitem' => '
                                     --palette--;;imageoverlayPalette,
                                     --palette--;;filePalette',
-                            ],
-                            \TYPO3\CMS\Core\Resource\File::FILETYPE_TEXT => [
-                                'showitem' => '
+                        ],
+                        \TYPO3\CMS\Core\Resource\File::FILETYPE_TEXT => [
+                            'showitem' => '
                                     --palette--;;imageoverlayPalette,
                                     --palette--;;filePalette',
-                            ],
-                            \TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [
-                                'showitem' => '
+                        ],
+                        \TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [
+                            'showitem' => '
                                     --palette--;;imageoverlayPalette,
                                     --palette--;;filePalette',
-                            ],
-                            \TYPO3\CMS\Core\Resource\File::FILETYPE_AUDIO => [
-                                'showitem' => '
+                        ],
+                        \TYPO3\CMS\Core\Resource\File::FILETYPE_AUDIO => [
+                            'showitem' => '
                                     --palette--;;audioOverlayPalette,
                                     --palette--;;filePalette',
-                            ],
-                            \TYPO3\CMS\Core\Resource\File::FILETYPE_VIDEO => [
-                                'showitem' => '
+                        ],
+                        \TYPO3\CMS\Core\Resource\File::FILETYPE_VIDEO => [
+                            'showitem' => '
                                     --palette--;;videoOverlayPalette,
                                     --palette--;;filePalette',
-                            ],
-                            \TYPO3\CMS\Core\Resource\File::FILETYPE_APPLICATION => [
-                                'showitem' => '
+                        ],
+                        \TYPO3\CMS\Core\Resource\File::FILETYPE_APPLICATION => [
+                            'showitem' => '
                                     --palette--;;imageoverlayPalette,
                                     --palette--;;filePalette',
-                            ],
                         ],
                     ],
-                    'behaviour' => [
-                        'allowLanguageSynchronization' => true,
-                    ],
-                ]
-            ),
+                ],
+            ],
         ],
         'is_siteroot' => [
             'exclude' => true,
diff --git a/typo3/sysext/core/Configuration/TCA/sys_file_collection.php b/typo3/sysext/core/Configuration/TCA/sys_file_collection.php
index 93bc6925c591..26804de41848 100644
--- a/typo3/sysext/core/Configuration/TCA/sys_file_collection.php
+++ b/typo3/sysext/core/Configuration/TCA/sys_file_collection.php
@@ -100,7 +100,9 @@ return [
         ],
         'files' => [
             'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_collection.files',
-            'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig('files'),
+            'config' => [
+                'type' => 'file',
+            ],
         ],
         'title' => [
             'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_collection.title',
diff --git a/typo3/sysext/core/Configuration/TCA/sys_file_reference.php b/typo3/sysext/core/Configuration/TCA/sys_file_reference.php
index 8ec0dc09655d..133429650fae 100644
--- a/typo3/sysext/core/Configuration/TCA/sys_file_reference.php
+++ b/typo3/sysext/core/Configuration/TCA/sys_file_reference.php
@@ -4,13 +4,6 @@ return [
     'ctrl' => [
         'title' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference',
         'label' => 'uid_local',
-        'formattedLabel_userFunc' => 'TYPO3\\CMS\\Core\\Resource\\Service\\UserFileInlineLabelService->getInlineLabel',
-        'formattedLabel_userFunc_options' => [
-            'sys_file' => [
-                'title',
-                'name',
-            ],
-        ],
         'tstamp' => 'tstamp',
         'crdate' => 'crdate',
         'type' => 'uid_local:type',
@@ -104,14 +97,6 @@ return [
                 'default' => 0,
             ],
         ],
-        'table_local' => [
-            'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.table_local',
-            'config' => [
-                'type' => 'input',
-                'size' => 20,
-                'default' => 'sys_file',
-            ],
-        ],
         'title' => [
             'l10n_mode' => 'prefixLangTitle',
             'exclude' => true,
diff --git a/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-98479-RemovedFileReferenceRelatedFunctionality.rst b/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-98479-RemovedFileReferenceRelatedFunctionality.rst
new file mode 100644
index 000000000000..c3577e224d42
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-98479-RemovedFileReferenceRelatedFunctionality.rst
@@ -0,0 +1,65 @@
+.. include:: /Includes.rst.txt
+
+.. _breaking-98479-1664622195:
+
+===============================================================
+Breaking: #98479 - Removed file reference related functionality
+===============================================================
+
+See :issue:`98479`
+
+Description
+===========
+
+With the introduction of the new TCA type :php:`file`, a couple of cross
+dependencies have been removed, mainly related to FormEngine.
+
+The :php:`customControls` hook option is not available for the new
+TCA type :php:`file`. It has been replaced by the new PSR-14
+:php:`CustomFileControlsEvent` for this use case.
+
+The field :sql:`table_local` of table :sql:`sys_file_reference`: is no longer
+evaluated by TYPO3 and has therefore been removed.
+
+The following options are no longer evaluated for TCA type :php:`inline`:
+
+- :php:`[appearance][headerThumbnail]`
+- :php:`[appearance][fileUploadAllowed]`
+- :php:`[appearance][fileByUrlAllowed]`
+
+A TCA migration is in place, removing those values from custom configurations.
+
+Impact
+======
+
+Adding custom controls with the :php:`customControls` option does no longer
+work for FAL fields.
+
+Using the :sql:`table_local` field of table :sql:`sys_file_reference` does
+no longer work and might lead to database errors.
+
+Using one of the mentioned :php:`[appearance]` TCA options does no longer
+have any effect.
+
+Affected installations
+======================
+
+All installations making use of the :php:`customControls` option for FAL
+fields, directly using the sql:`table_local` field of table
+:sql:`sys_file_reference` or using one of the mentioned :php:`[appearance]`
+TCA options for TCA type :php:`inline` fields.
+
+Migration
+=========
+
+Migrate corresponding user functions for the :php:`customControls` option to
+a PSR-14 event listeners of the
+:doc:`CustomFileControlsEvent <../12.0/Feature-98479-NewTCATypeFile.rst>`.
+
+Remove any usage of the :sql:`table_local` field of
+table :sql:`sys_file_reference` in custom extension code.
+
+Remove the mentioned :php:`[appearance]` TCA options from your custom TCA
+configurations.
+
+.. index:: Backend, Database, FAL, PHP-API, TCA, PartiallyScanned, ext:backend
diff --git a/typo3/sysext/core/Documentation/Changelog/12.0/Deprecation-98479-DeprecatedFileReferenceRelatedFunctionality.rst b/typo3/sysext/core/Documentation/Changelog/12.0/Deprecation-98479-DeprecatedFileReferenceRelatedFunctionality.rst
new file mode 100644
index 000000000000..62475466c287
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/12.0/Deprecation-98479-DeprecatedFileReferenceRelatedFunctionality.rst
@@ -0,0 +1,59 @@
+.. include:: /Includes.rst.txt
+
+.. _deprecation-98479-1664622350:
+
+=====================================================================
+Deprecation: #98479 - Deprecated file reference related functionality
+=====================================================================
+
+See :issue:`98479`
+
+Description
+===========
+
+With the introduction of the new TCA type :php:`file`, a couple of cross
+dependencies have been deprecated, mainly related to FormEngine.
+
+The :php:`UserFileInlineLabelService` class has been deprecated, since it was
+only used for generating the inline label for file references in TCA type
+:php:`inline`. This is now handled by the new TCA type :php:`file` directly.
+
+The :php:`FileExtensionFilter->filterInlineChildren()` method, which was
+previously used as :php:`[filter][userFunc]` to filter the available
+file extensions in FormEngine as well as :php:`DataHandler` has been
+deprecated. This is now done internally.
+
+The :php:`ExtensionManagementUtility::getFileFieldTCAConfig()` method, which
+was usually used to simplify configuration of FAL fields in TCA has been
+deprecated as well, since the applied configuration is now handled internally.
+
+Impact
+======
+
+Instantiating the :php:`UserFileInlineLabelService` class, as well as
+calling the :php:`FileExtensionFilter->filterInlineChildren()` and
+:php:`ExtensionManagementUtility::getFileFieldTCAConfig()` methods will
+trigger a PHP :php:`E_USER_DEPRECATED` level error. The extension scanner
+also reports any usage.
+
+Affected installations
+======================
+
+All installations with extensions using the :php:`UserFileInlineLabelService`
+class or one of the mentioned methods.
+
+Migration
+=========
+
+Remove any usage of the :php:`UserFileInlineLabelService` class. There is no
+migration available, since this FAL specific functionality is now handled
+internally.
+
+Replace any usage of :php:`FileExtensionFilter->filterInlineChildren()` with
+:php:`FileExtensionFilter->filter()`. However, usage of this method in custom
+extension code should usually not be necessary.
+
+Replace any usage of :php:`ExtensionManagementUtility::getFileFieldTCAConfig()`
+by directly using the new TCA type :doc:`file <../12.0/Feature-98479-NewTCATypeFile.rst>`.
+
+.. index:: Backend, Database, FAL, PHP-API, TCA, PartiallyScanned, ext:backend
diff --git a/typo3/sysext/core/Documentation/Changelog/12.0/Feature-98479-NewTCATypeFile.rst b/typo3/sysext/core/Documentation/Changelog/12.0/Feature-98479-NewTCATypeFile.rst
new file mode 100644
index 000000000000..bb811dd108bb
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/12.0/Feature-98479-NewTCATypeFile.rst
@@ -0,0 +1,200 @@
+.. include:: /Includes.rst.txt
+
+.. _feature-98479-1664537749:
+
+=====================================
+Feature: #98479 - New TCA type "file"
+=====================================
+
+See :issue:`98479`
+
+Description
+===========
+
+A new TCA field type called :php:`file` has been added to TYPO3 Core. Its
+main purpose is to simplify the TCA configuration for adding file reference
+fields to records. It therefore supersedes the usage of TCA type :php:`inline`
+with :php:`foreign_table` set to :php:`sys_file_reference`, which had previously
+usually been configured using the now deprecated API method
+:php:`ExtensionManagementUtility->getFileFieldTCAConfig()` for this use case.
+
+This helps on determination of the semantic meaning and also allows to
+reduce internal cross dependencies between TCA type `inline` and FAL.
+
+The new TCA type :php:`file` features the following column configuration:
+
+- :php:`allowed`
+- :php:`appearance`: :php:`collapseAll`, :php:`expandSingle`, :php:`createNewRelationLinkTitle`, :php:`useSortable`, :php:`enabledControls`, :php:`headerThumbnail`, :php:`fileUploadAllowed`, :php:`fileByUrlAllowed`, :php:`elementBrowserEnabled`, :php:`showPossibleLocalizationRecords`, :php:`showAllLocalizationLink`, :php:`showSynchronizationLink`, :php:`showFileSelectors`
+- :php:`behaviour`: :php:`allowLanguageSynchronization`, :php:`disableMovingChildrenWithParent`, :php:`enableCascadingDelete`
+- :php:`disallowed`
+- :php:`fieldInformation`
+- :php:`fieldWizard`
+- :php:`maxitems`
+- :php:`minitems`
+- :php:`overrideChildTca`
+- :php:`readOnly`
+
+.. note::
+
+    The option :php:`showFileSelectors` can be used to define whether the
+    file selectors, such as "Select & upload files" are displayed. This is
+    similar to the the :php:`showPossibleRecordsSelector` option, available
+    for TCA type :php:`inline`.
+
+The following column configuration can be overwritten by Page TSconfig:
+
+- :typoscript:`appearance`
+- :typoscript:`behaviour`
+- :typoscript:`maxitems`
+- :typoscript:`minitems`
+- :typoscript:`readOnly`
+
+A possible migration using the API method therefore looks like the following:
+
+.. code-block:: php
+
+    // Before
+    'columns' => [
+        'image' => [
+            'label' => 'My image',
+            'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
+                'image',
+                [
+                    'maxitems' => 6,
+                ],
+                $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
+            ),
+        ],
+    ],
+
+    // After
+    'columns' => [
+        'image' => [
+            'label' => 'My image',
+            'config' => [
+                'type' => 'file',
+                'maxitems' => 6,
+                'allowed' => 'common-image-types'
+            ],
+        ],
+    ],
+
+The example uses the :php:`common-image-types` placeholder for the
+:php:`allowed` option. This placeholder is internally replaced and
+helps to further reduce the usage of :php:`$GLOBALS`. Further placeholders
+are :php:`common-text-types` and :php:`common-media-types`. It's possible
+to use multiple placeholders. It's also possible to mix them with single
+file extensions. Additionally, it's also possible to define the file
+extensions as `array`.
+
+Another example without usage of the API method would therefore look like this:
+
+.. code-block:: php
+
+    // Before
+    'columns' => [
+        'image' => [
+            'label' => 'My image',
+            'config' => [
+                'type' => 'inline',
+                'foreign_table' => 'sys_file_reference',
+                'foreign_field' => 'uid_foreign',
+                'foreign_sortby' => 'sorting_foreign',
+                'foreign_table_field' => 'tablenames',
+                'foreign_match_fields' => [
+                    'fieldname' => 'image',
+                ],
+                'foreign_label' => 'uid_local',
+                'foreign_selector' => 'uid_local',
+                'overrideChildTca' => [
+                    'columns' => [
+                        'uid_local' => [
+                            'config' => [
+                                'appearance' => [
+                                    'elementBrowserType' => 'file',
+                                    'elementBrowserAllowed' => 'jpg,png,gif',
+                                ],
+                            ],
+                        ],
+                    ],
+                ],
+            ]
+        ],
+    ],
+
+    // After
+    'columns' => [
+        'image' => [
+            'label' => 'My image',
+            'config' => [
+                'type' => 'file',
+                'allowed' => ['jpg','png','gif'],
+            ],
+        ],
+    ],
+
+Together with the new TCA type, three new PSR-14 Events have been introduced:
+
+* :php:`TYPO3\CMS\Backend\Form\Event\CustomFileControlsEvent`
+* :php:`TYPO3\CMS\Backend\Form\Event\ModifyFileReferenceControlsEvent`
+* :php:`TYPO3\CMS\Backend\Form\Event\ModifyFileReferenceEnabledControlsEvent`
+
+CustomFileControlsEvent
+=======================
+
+Listeners to this Event will be able to add custom controls to a TCA type
+:php:`file` field in FormEngine. This replaces the :php:`customControls`
+hook option, which is only available for TCA type :php:`inline`.
+
+The new event provides the following methods:
+
+- :php:`getResultArray()`: Returns the whole result array
+- :php:`setResultArray(array $resultArray)`: Allows to overwrite the result array, e.g. to add additional JS modules
+- :php:`getControls()`: Returns all configured custom controls
+- :php:`setControls()`: Overwrites the custom controls
+- :php:`addControl()`: Adds a custom control. It's recommended to set the optional :php:`$identifier` argument.
+- :php:`removeControl()`: Removes a custom control. This only works in case the custom control was added with an identifier.
+- :php:`getTableName()`: Returns the table name in question
+- :php:`getFieldName()`: Returns the field name in question
+- :php:`getDatabaseRow()`: Returns the database row of the record in question
+- :php:`getFieldConfig()`: Returns the fields' TCA configuration
+- :php:`getFormFieldIdentifier()`: Returns the form elements' identifier
+- :php:`getFormFieldName()`: Returns the form elements' name
+
+.. note::
+
+    Custom controls are always displayed below the file references. In contrast
+    to the selectors, e.g. "Select & upload files" are custom controls
+    independent of the :php:`readonly` and :php:`showFileSelectors` options.
+    This means, you have full control in which scenario your custom controls
+    are being displayed.
+
+ModifyFileReferenceControlsEvent
+================================
+
+Listeners to this Event will be able to modify the controls of a single
+file reference of a TCA type `file` field. This event is similar to the
+:php:`ModifyInlineElementControlsEvent`, which is only available for TCA
+type `inline`. See corresponding PHP class or the other
+:doc:`changelog <../12.0/Feature-97231-PSR-14EventsForModifyingInlineElementControls>`
+for more information about available methods and their usage.
+
+ModifyFileReferenceEnabledControlsEvent
+=======================================
+
+Listeners to this Event will be able to modify the state (enabled or disabled)
+for the controls of a single file reference of a TCA type `file` field. This
+event is similar to the :php:`ModifyInlineElementEnabledControlsEvent`, which
+is only available for TCA type `inline`. See corresponding PHP class or the
+other :doc:`changelog <../12.0/Feature-97231-PSR-14EventsForModifyingInlineElementControls>`
+for more information about available methods and their usage.
+
+Impact
+======
+
+It's now possible to simplify the TCA configuration for file reference
+fields, using the new TCA type `file`. Three new PSR-14 Events allow to
+modify available controls of the TCA field as well as the related file
+references.
+
+.. index:: Backend, FAL, PHP-API, TCA, ext:backend
diff --git a/typo3/sysext/core/Resources/Private/Language/locallang_tca.xlf b/typo3/sysext/core/Resources/Private/Language/locallang_tca.xlf
index 7f389f0f5533..eb5aa0e0cbad 100644
--- a/typo3/sysext/core/Resources/Private/Language/locallang_tca.xlf
+++ b/typo3/sysext/core/Resources/Private/Language/locallang_tca.xlf
@@ -522,9 +522,6 @@
 			<trans-unit id="sys_file_reference.sorting_foreign" resname="sys_file_reference.sorting_foreign">
 				<source>Sorting foreign</source>
 			</trans-unit>
-			<trans-unit id="sys_file_reference.table_local" resname="sys_file_reference.table_local">
-				<source>Local table</source>
-			</trans-unit>
 			<trans-unit id="sys_file_reference.basicoverlayPalette" resname="sys_file_reference.basicoverlayPalette">
 				<source>File Metadata</source>
 			</trans-unit>
diff --git a/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/InlineFalCest.php b/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/FileCest.php
similarity index 88%
rename from typo3/sysext/core/Tests/Acceptance/Application/FormEngine/InlineFalCest.php
rename to typo3/sysext/core/Tests/Acceptance/Application/FormEngine/FileCest.php
index a7be00465210..274c541b6cea 100644
--- a/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/InlineFalCest.php
+++ b/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/FileCest.php
@@ -22,15 +22,15 @@ use TYPO3\CMS\Core\Tests\Acceptance\Support\Helper\ModalDialog;
 use TYPO3\CMS\Core\Tests\Acceptance\Support\Helper\PageTree;
 
 /**
- * Tests for inline fal
+ * Tests for type=file (FAL)
  */
-class InlineFalCest
+class FileCest
 {
     protected static string $filenameSelector = '.form-irre-header-body > span > dl.row:first-child > dd.col';
     protected static string $saveButtonLink = '//*/button[@name="_savedok"][1]';
 
     /**
-     * Open styleguide inline fal page in list module
+     * Open styleguide file page in list module
      */
     public function _before(ApplicationTester $I, PageTree $pageTree): void
     {
@@ -38,11 +38,11 @@ class InlineFalCest
 
         $I->click('List');
         $I->waitForElement('svg .nodes .node');
-        $pageTree->openPath(['styleguide TCA demo', 'inline fal']);
+        $pageTree->openPath(['styleguide TCA demo', 'file']);
         $I->switchToContentFrame();
 
-        $I->waitForText('inline fal', 20);
-        $editRecordLinkCssPath = '#recordlist-tx_styleguide_inline_fal a[aria-label="Edit record"]';
+        $I->waitForText('file', 20);
+        $editRecordLinkCssPath = '#recordlist-tx_styleguide_file a[aria-label="Edit record"]';
         $I->click($editRecordLinkCssPath);
         $I->waitForText('Edit Form', 3, 'h1');
     }
@@ -70,7 +70,7 @@ class InlineFalCest
 
     public function deleteFalRelation(ApplicationTester $I, ModalDialog $modalDialog): void
     {
-        $deleteButtonSelector = '.tab-content .t3js-editform-delete-inline-record';
+        $deleteButtonSelector = '.tab-content .t3js-editform-delete-file-reference';
         $filename = $I->grabTextFrom(self::$filenameSelector);
 
         $I->click($deleteButtonSelector);
diff --git a/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/NullPlaceholderCest.php b/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/NullPlaceholderCest.php
index 8611c01ad4a5..b6280016863b 100644
--- a/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/NullPlaceholderCest.php
+++ b/typo3/sysext/core/Tests/Acceptance/Application/FormEngine/NullPlaceholderCest.php
@@ -43,11 +43,11 @@ class NullPlaceholderCest
     {
         $I->amGoingTo('Check if deactivating null checkboxes marks as "changed"');
 
-        $editRecordLinkCssPath = '#recordlist-tx_styleguide_inline_fal a[aria-label="Edit record"]';
+        $editRecordLinkCssPath = '#recordlist-tx_styleguide_file a[aria-label="Edit record"]';
         $I->click($editRecordLinkCssPath);
 
         $I->waitForElementNotVisible('#t3js-ui-block');
-        $I->waitForText('Edit Form engine - inline fal "1" on page "inline fal"');
+        $I->waitForText('Edit Form engine - file "1" on page "file"');
         $I->click('typical fal');
         $I->click('.form-irre-header');
         $I->waitForElementNotVisible('.nprogress-custom-parent');
@@ -73,8 +73,8 @@ class NullPlaceholderCest
         $I->switchToMainFrame();
         $I->click('List');
         $I->waitForElement('svg .nodes .node');
-        $pageTree->openPath(['styleguide TCA demo', 'inline fal']);
+        $pageTree->openPath(['styleguide TCA demo', 'file']);
         $I->switchToContentFrame();
-        $I->waitForText('inline fal');
+        $I->waitForText('file');
     }
 }
diff --git a/typo3/sysext/core/Tests/Functional/DataHandling/FlexformIrre/DataSet/ImportDefault.csv b/typo3/sysext/core/Tests/Functional/DataHandling/FlexformIrre/DataSet/ImportDefault.csv
index 21edd416b081..e8c489b68d4c 100644
--- a/typo3/sysext/core/Tests/Functional/DataHandling/FlexformIrre/DataSet/ImportDefault.csv
+++ b/typo3/sysext/core/Tests/Functional/DataHandling/FlexformIrre/DataSet/ImportDefault.csv
@@ -13,8 +13,8 @@
 ,"uid","pid","storage","identifier","name",,,,,,,,,
 ,20,0,1,"/typo3-logo.png","typo3-logo.png",,,,,,,,,
 "sys_file_reference",,,,,,,,,,,,,,
-,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid",,
-,1,1,20,100,"tt_content","files",1,"sys_file",0,0,0,0,,
+,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid",,
+,1,1,20,100,"tt_content","files",1,0,0,0,0,,
 "sys_refindex",,,,,,,,,,,,,,
 ,"hash","tablename","recuid","field","flexpointer","softref_key","softref_id","sorting","workspace","ref_table","ref_uid","ref_string",,
 ,"0ad00e77a175a4a5d134cc2b115839fd","sys_file",20,"storage",,,,0,0,"sys_file_storage",1,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/DataSet/ImportDefault.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/DataSet/ImportDefault.csv
index a156b6b56549..02927690a710 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/DataSet/ImportDefault.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/DataSet/ImportDefault.csv
@@ -13,11 +13,11 @@
 ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link","l10n_diffsource"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link","l10n_diffsource"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,,
 "tt_content",,,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/DataSet/ImportDefaultWorkspaces.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/DataSet/ImportDefaultWorkspaces.csv
index 89870306468e..8332a6e64b71 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/DataSet/ImportDefaultWorkspaces.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/DataSet/ImportDefaultWorkspaces.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link","l10n_diffsource"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link","l10n_diffsource"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,,
 "tt_content",,,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/changeContentSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/changeContentSorting.csv
index bbb752715c17..ed4c9f92d3a7 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/changeContentSorting.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/changeContentSorting.csv
@@ -13,11 +13,11 @@
 ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,
 ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,
 ,330,89,768,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/copyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/copyContent.csv
index 01cbaefa9e72..36428e525bb5 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/copyContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/copyContent.csv
@@ -13,13 +13,13 @@
 ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,
 ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,0,0,0,0,0,0,21,332,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,131,89,0,0,0,0,0,0,0,1,332,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,0,0,0,0,0,0,21,332,"tt_content","image",1,"Taken at T3BOARD",,,
+,131,89,0,0,0,0,0,0,0,1,332,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,
 ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/copyContentToLanguage.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/copyContentToLanguage.csv
index 725acbd7a93d..a4827a604369 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/copyContentToLanguage.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/copyContentToLanguage.csv
@@ -14,13 +14,13 @@
 ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,
 ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,1,0,0,0,0,0,21,332,"tt_content","image",1,"sys_file","[Translate to Dansk:] Taken at T3BOARD",,,
-,131,89,0,1,0,0,0,0,0,1,332,"tt_content","image",2,"sys_file","[Translate to Dansk:] This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,1,0,0,0,0,0,21,332,"tt_content","image",1,"[Translate to Dansk:] Taken at T3BOARD",,,
+,131,89,0,1,0,0,0,0,0,1,332,"tt_content","image",2,"[Translate to Dansk:] This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,
 ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/createContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/createContentWFileReference.csv
index febd26ed6a6d..731a11312c5c 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/createContentWFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/createContentWFileReference.csv
@@ -13,12 +13,12 @@
 ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,
 ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,0,0,0,0,0,0,1,332,"tt_content","image",1,"sys_file","Image #1",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,0,0,0,0,0,0,1,332,"tt_content","image",1,"Image #1",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,
 ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/createContentWFileReferenceNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/createContentWFileReferenceNDeleteFileReference.csv
index 72853835b64c..bdf9f266b79d 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/createContentWFileReferenceNDeleteFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/createContentWFileReferenceNDeleteFileReference.csv
@@ -13,12 +13,12 @@
 ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,
 ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,1,0,0,0,0,0,0,1,332,"tt_content","image",1,"sys_file","Image #1",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,1,0,0,0,0,0,0,1,332,"tt_content","image",1,"Image #1",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/deleteContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/deleteContent.csv
index a9f6a1a9e310..4c972c9c42ec 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/deleteContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/deleteContent.csv
@@ -13,11 +13,11 @@
 ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,
 ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,
 ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/localizeContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/localizeContent.csv
index 0e8a90429ba5..5a6e4ddb6dee 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/localizeContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/localizeContent.csv
@@ -14,13 +14,13 @@
 ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,
 ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,1,128,0,0,0,0,21,332,"tt_content","image",1,"sys_file","[Translate to Dansk:] Taken at T3BOARD",,,
-,131,89,0,1,129,0,0,0,0,1,332,"tt_content","image",2,"sys_file","[Translate to Dansk:] This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,1,128,0,0,0,0,21,332,"tt_content","image",1,"[Translate to Dansk:] Taken at T3BOARD",,,
+,131,89,0,1,129,0,0,0,0,1,332,"tt_content","image",2,"[Translate to Dansk:] This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,
 ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContent.csv
index 8105472eac75..aaaabdaeb2da 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContent.csv
@@ -13,11 +13,11 @@
 ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,
 ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,
 ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNAddFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNAddFileReference.csv
index d19f3a800468..d4a98600a85a 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNAddFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNAddFileReference.csv
@@ -13,12 +13,12 @@
 ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,
 ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,0,0,0,0,0,0,1,331,"tt_content","image",3,"sys_file","Image #3",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,0,0,0,0,0,0,1,331,"tt_content","image",3,"Image #3",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,
 ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNDeleteAllFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNDeleteAllFileReference.csv
index 9bb8ff1e336f..c5a6ba0275c5 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNDeleteAllFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNDeleteAllFileReference.csv
@@ -13,11 +13,11 @@
 ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,
 ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,
 ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNDeleteFileReference.csv
index 864d37a8b0e6..963115ffa644 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNDeleteFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentNDeleteFileReference.csv
@@ -13,11 +13,11 @@
 ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,
 ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",1,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",1,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,
 ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentWFileReference.csv
index 8ed5b887fb23..c158e98ace11 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentWFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/modifyContentWFileReference.csv
@@ -13,11 +13,11 @@
 ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,
 ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","Image #1",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"Image #1",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,
 ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/moveContentToDifferentPage.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/moveContentToDifferentPage.csv
index e97f5d00899c..2a09aa180832 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/moveContentToDifferentPage.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/moveContentToDifferentPage.csv
@@ -13,11 +13,11 @@
 ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,
 ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,
 ,330,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/moveContentToDifferentPageNChangeSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/moveContentToDifferentPageNChangeSorting.csv
index d467ab3a6599..227963285f2c 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/moveContentToDifferentPageNChangeSorting.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/Modify/DataSet/moveContentToDifferentPageNChangeSorting.csv
@@ -13,11 +13,11 @@
 ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,
 ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,90,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,90,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,90,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,90,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3_origuid","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,
 ,330,90,512,0,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/changeContentSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/changeContentSorting.csv
index 3a3338f7583d..21895dbe437f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/changeContentSorting.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/changeContentSorting.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/copyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/copyContent.csv
index 3a3338f7583d..21895dbe437f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/copyContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/copyContent.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/createContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/createContentWFileReference.csv
index 3a3338f7583d..21895dbe437f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/createContentWFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/createContentWFileReference.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/createContentWFileReferenceNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/createContentWFileReferenceNDeleteFileReference.csv
index 3a3338f7583d..21895dbe437f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/createContentWFileReferenceNDeleteFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/createContentWFileReferenceNDeleteFileReference.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/deleteContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/deleteContent.csv
index 3a3338f7583d..21895dbe437f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/deleteContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/deleteContent.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/localizeContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/localizeContent.csv
index 98da3f031671..c3062fa44e91 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/localizeContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/localizeContent.csv
@@ -21,11 +21,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContent.csv
index 3a3338f7583d..21895dbe437f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContent.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNAddFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNAddFileReference.csv
index 3a3338f7583d..21895dbe437f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNAddFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNAddFileReference.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNDeleteAllFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNDeleteAllFileReference.csv
index 3a3338f7583d..21895dbe437f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNDeleteAllFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNDeleteAllFileReference.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNDeleteFileReference.csv
index 3a3338f7583d..21895dbe437f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNDeleteFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentNDeleteFileReference.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentWFileReference.csv
index 3a3338f7583d..21895dbe437f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentWFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/modifyContentWFileReference.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/moveContentToDifferentPage.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/moveContentToDifferentPage.csv
index 3a3338f7583d..21895dbe437f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/moveContentToDifferentPage.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/moveContentToDifferentPage.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/moveContentToDifferentPageNChangeSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/moveContentToDifferentPageNChangeSorting.csv
index 3a3338f7583d..21895dbe437f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/moveContentToDifferentPageNChangeSorting.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesDiscard/DataSet/moveContentToDifferentPageNChangeSorting.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/changeContentSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/changeContentSorting.csv
index fd80c6e2a67d..589bd43de805 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/changeContentSorting.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/changeContentSorting.csv
@@ -20,13 +20,13 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,0,0,1,0,0,127,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,131,89,0,0,0,1,0,0,126,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,0,0,1,0,0,127,21,330,"tt_content","image",1,"Kasper",,,
+,131,89,0,0,0,1,0,0,126,1,330,"tt_content","image",2,"T3BOARD",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/copyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/copyContent.csv
index 2b1baf7abe13..fcdd6cd16dc2 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/copyContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/copyContent.csv
@@ -20,13 +20,13 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,0,0,1,1,0,0,21,332,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,131,89,0,0,0,1,1,0,0,1,332,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,0,0,1,1,0,0,21,332,"tt_content","image",1,"Taken at T3BOARD",,,
+,131,89,0,0,0,1,1,0,0,1,332,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/createContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/createContentWFileReference.csv
index dfabc7afddbb..07fe6f89e5d6 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/createContentWFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/createContentWFileReference.csv
@@ -20,12 +20,12 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,0,0,1,1,0,0,1,332,"tt_content","image",1,"sys_file","Image #1",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,0,0,1,1,0,0,1,332,"tt_content","image",1,"Image #1",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/createContentWFileReferenceNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/createContentWFileReferenceNDeleteFileReference.csv
index 3f3387daeaa6..1949be6927ed 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/createContentWFileReferenceNDeleteFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/createContentWFileReferenceNDeleteFileReference.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/deleteContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/deleteContent.csv
index 15e20dd78aa5..50fd4434c77b 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/deleteContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/deleteContent.csv
@@ -20,13 +20,13 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,0,0,1,2,0,128,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,131,89,0,0,0,1,2,0,129,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,0,0,1,2,0,128,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,131,89,0,0,0,1,2,0,129,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/localizeContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/localizeContent.csv
index 58f6b2db83cc..823d98e38e9a 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/localizeContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/localizeContent.csv
@@ -21,13 +21,13 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,1,128,1,1,0,0,21,332,"tt_content","image",1,"sys_file","[Translate to Dansk:] Taken at T3BOARD",,,
-,131,89,0,1,129,1,1,0,0,1,332,"tt_content","image",2,"sys_file","[Translate to Dansk:] This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,1,128,1,1,0,0,21,332,"tt_content","image",1,"[Translate to Dansk:] Taken at T3BOARD",,,
+,131,89,0,1,129,1,1,0,0,1,332,"tt_content","image",2,"[Translate to Dansk:] This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContent.csv
index 3f6af745d350..f8e4ac0b358c 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContent.csv
@@ -20,13 +20,13 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,0,0,1,0,0,128,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,131,89,0,0,0,1,0,0,129,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,0,0,1,0,0,128,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,131,89,0,0,0,1,0,0,129,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNAddFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNAddFileReference.csv
index deff0ceb24e3..2d305a67ade4 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNAddFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNAddFileReference.csv
@@ -20,14 +20,14 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,0,0,1,0,0,128,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,131,89,0,0,0,1,0,0,129,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,132,89,0,0,0,1,1,0,0,1,331,"tt_content","image",3,"sys_file","Image #3",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,0,0,1,0,0,128,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,131,89,0,0,0,1,0,0,129,1,331,"tt_content","image",2,"This is Kasper",,,
+,132,89,0,0,0,1,1,0,0,1,331,"tt_content","image",3,"Image #3",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNDeleteAllFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNDeleteAllFileReference.csv
index 961bac5f081f..a6729f647088 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNDeleteAllFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNDeleteAllFileReference.csv
@@ -20,13 +20,13 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,0,0,1,2,0,129,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,131,89,0,0,0,1,2,0,128,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,0,0,1,2,0,129,1,331,"tt_content","image",2,"This is Kasper",,,
+,131,89,0,0,0,1,2,0,128,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNDeleteFileReference.csv
index 720e90523a9f..3fb3ac2a1ec7 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNDeleteFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentNDeleteFileReference.csv
@@ -20,13 +20,13 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,0,0,1,0,0,129,1,331,"tt_content","image",1,"sys_file","This is Kasper",,,
-,131,89,0,0,0,1,2,0,128,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,0,0,1,0,0,129,1,331,"tt_content","image",1,"This is Kasper",,,
+,131,89,0,0,0,1,2,0,128,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentWFileReference.csv
index 7e254b5d5d24..6c3f3d093c05 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentWFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/modifyContentWFileReference.csv
@@ -20,13 +20,13 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,0,0,1,0,0,128,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,131,89,0,0,0,1,0,0,129,1,331,"tt_content","image",2,"sys_file","Image #1",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,0,0,1,0,0,128,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,131,89,0,0,0,1,0,0,129,1,331,"tt_content","image",2,"Image #1",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/moveContentToDifferentPage.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/moveContentToDifferentPage.csv
index 5616ed55fac2..336953e86f21 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/moveContentToDifferentPage.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/moveContentToDifferentPage.csv
@@ -20,13 +20,13 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,90,0,0,0,1,4,0,128,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,131,90,0,0,0,1,4,0,129,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,90,0,0,0,1,4,0,128,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,131,90,0,0,0,1,4,0,129,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/moveContentToDifferentPageNChangeSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/moveContentToDifferentPageNChangeSorting.csv
index 548abc790cbe..42b51569c69e 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/moveContentToDifferentPageNChangeSorting.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesModify/DataSet/moveContentToDifferentPageNChangeSorting.csv
@@ -20,15 +20,15 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,90,0,0,0,1,4,0,128,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,131,90,0,0,0,1,4,0,129,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,132,90,0,0,0,1,4,0,127,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,133,90,0,0,0,1,4,0,126,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,90,0,0,0,1,4,0,128,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,131,90,0,0,0,1,4,0,129,1,331,"tt_content","image",2,"This is Kasper",,,
+,132,90,0,0,0,1,4,0,127,21,330,"tt_content","image",1,"Kasper",,,
+,133,90,0,0,0,1,4,0,126,1,330,"tt_content","image",2,"T3BOARD",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/changeContentSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/changeContentSorting.csv
index d000f128ef37..92fd2290bc0b 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/changeContentSorting.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/changeContentSorting.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,768,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/copyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/copyContent.csv
index f7d1066a736a..d248dd0d0daf 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/copyContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/copyContent.csv
@@ -20,13 +20,13 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,0,0,0,0,0,0,21,332,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,131,89,0,0,0,0,0,0,0,1,332,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,0,0,0,0,0,0,21,332,"tt_content","image",1,"Taken at T3BOARD",,,
+,131,89,0,0,0,0,0,0,0,1,332,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/createContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/createContentWFileReference.csv
index 354483d046e3..1ae00eac2898 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/createContentWFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/createContentWFileReference.csv
@@ -20,12 +20,12 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,0,0,0,0,0,0,1,332,"tt_content","image",1,"sys_file","Image #1",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,0,0,0,0,0,0,1,332,"tt_content","image",1,"Image #1",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/createContentWFileReferenceNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/createContentWFileReferenceNDeleteFileReference.csv
index 72c2d7c516ec..24c562a6e8ac 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/createContentWFileReferenceNDeleteFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/createContentWFileReferenceNDeleteFileReference.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/deleteContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/deleteContent.csv
index 61a0cfdd380d..c804470d289b 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/deleteContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/deleteContent.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/localizeContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/localizeContent.csv
index bfcf01a1262b..a40f7107f9c2 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/localizeContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/localizeContent.csv
@@ -21,13 +21,13 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,1,128,0,0,0,0,21,332,"tt_content","image",1,"sys_file","[Translate to Dansk:] Taken at T3BOARD",,,
-,131,89,0,1,129,0,0,0,0,1,332,"tt_content","image",2,"sys_file","[Translate to Dansk:] This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,1,128,0,0,0,0,21,332,"tt_content","image",1,"[Translate to Dansk:] Taken at T3BOARD",,,
+,131,89,0,1,129,0,0,0,0,1,332,"tt_content","image",2,"[Translate to Dansk:] This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContent.csv
index 76ed244b715f..eb168714bae9 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContent.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNAddFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNAddFileReference.csv
index 4c1b80e494c4..a442bfcb6a0f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNAddFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNAddFileReference.csv
@@ -20,12 +20,12 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,132,89,0,0,0,0,0,0,0,1,331,"tt_content","image",3,"sys_file","Image #3",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,132,89,0,0,0,0,0,0,0,1,331,"tt_content","image",3,"Image #3",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNDeleteAllFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNDeleteAllFileReference.csv
index f54079c0549a..22a11ed0382f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNDeleteAllFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNDeleteAllFileReference.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNDeleteFileReference.csv
index 4eaae9b44016..9fe4cb370c02 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNDeleteFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentNDeleteFileReference.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",1,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",1,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentWFileReference.csv
index 1a5b7a6c9b4f..2cd656ae2ba4 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentWFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/modifyContentWFileReference.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","Image #1",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"Image #1",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/moveContentToDifferentPage.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/moveContentToDifferentPage.csv
index c01bf9871bed..17aac23f6575 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/moveContentToDifferentPage.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/moveContentToDifferentPage.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/moveContentToDifferentPageNChangeSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/moveContentToDifferentPageNChangeSorting.csv
index 46eaf5e869af..52d1ecfe8a8d 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/moveContentToDifferentPageNChangeSorting.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublish/DataSet/moveContentToDifferentPageNChangeSorting.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,90,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,90,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,90,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,90,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,90,512,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/changeContentSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/changeContentSorting.csv
index fc9e1dd2216c..b3a4e9484162 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/changeContentSorting.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/changeContentSorting.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link","l10n_diffsource"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link","l10n_diffsource"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,,
 "tt_content",,,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,,
 ,330,89,768,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/copyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/copyContent.csv
index f7d1066a736a..d248dd0d0daf 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/copyContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/copyContent.csv
@@ -20,13 +20,13 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,0,0,0,0,0,0,21,332,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,131,89,0,0,0,0,0,0,0,1,332,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,0,0,0,0,0,0,21,332,"tt_content","image",1,"Taken at T3BOARD",,,
+,131,89,0,0,0,0,0,0,0,1,332,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/createContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/createContentWFileReference.csv
index 354483d046e3..1ae00eac2898 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/createContentWFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/createContentWFileReference.csv
@@ -20,12 +20,12 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,0,0,0,0,0,0,1,332,"tt_content","image",1,"sys_file","Image #1",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,0,0,0,0,0,0,1,332,"tt_content","image",1,"Image #1",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/createContentWFileReferenceNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/createContentWFileReferenceNDeleteFileReference.csv
index 72c2d7c516ec..24c562a6e8ac 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/createContentWFileReferenceNDeleteFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/createContentWFileReferenceNDeleteFileReference.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/deleteContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/deleteContent.csv
index 61a0cfdd380d..c804470d289b 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/deleteContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/deleteContent.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/localizeContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/localizeContent.csv
index 967e6e95a684..1c7680634304 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/localizeContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/localizeContent.csv
@@ -21,13 +21,13 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,130,89,0,1,128,0,0,0,0,21,332,"tt_content","image",1,"sys_file","[Translate to Dansk:] Taken at T3BOARD",,,
-,131,89,0,1,129,0,0,0,0,1,332,"tt_content","image",2,"sys_file","[Translate to Dansk:] This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,130,89,0,1,128,0,0,0,0,21,332,"tt_content","image",1,"[Translate to Dansk:] Taken at T3BOARD",,,
+,131,89,0,1,129,0,0,0,0,1,332,"tt_content","image",2,"[Translate to Dansk:] This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContent.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContent.csv
index 76ed244b715f..eb168714bae9 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContent.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContent.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNAddFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNAddFileReference.csv
index 4c1b80e494c4..a442bfcb6a0f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNAddFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNAddFileReference.csv
@@ -20,12 +20,12 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
-,132,89,0,0,0,0,0,0,0,1,331,"tt_content","image",3,"sys_file","Image #3",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
+,132,89,0,0,0,0,0,0,0,1,331,"tt_content","image",3,"Image #3",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNDeleteAllFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNDeleteAllFileReference.csv
index f54079c0549a..22a11ed0382f 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNDeleteAllFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNDeleteAllFileReference.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,1,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNDeleteFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNDeleteFileReference.csv
index 4eaae9b44016..9fe4cb370c02 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNDeleteFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentNDeleteFileReference.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",1,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,1,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",1,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentWFileReference.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentWFileReference.csv
index 1a5b7a6c9b4f..2cd656ae2ba4 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentWFileReference.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/modifyContentWFileReference.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","Image #1",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,89,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,89,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"Image #1",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/moveContentToDifferentPage.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/moveContentToDifferentPage.csv
index c01bf9871bed..17aac23f6575 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/moveContentToDifferentPage.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/moveContentToDifferentPage.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,89,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,89,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,89,256,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/moveContentToDifferentPageNChangeSorting.csv b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/moveContentToDifferentPageNChangeSorting.csv
index 46eaf5e869af..52d1ecfe8a8d 100644
--- a/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/moveContentToDifferentPageNChangeSorting.csv
+++ b/typo3/sysext/core/Tests/Functional/DataScenarios/FAL/WorkspacesPublishAll/DataSet/moveContentToDifferentPageNChangeSorting.csv
@@ -20,11 +20,11 @@
 ,1,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,
-,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","table_local","title","description","alternative","link"
-,126,90,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"sys_file","T3BOARD",,,
-,127,90,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"sys_file","Kasper",,,
-,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"sys_file","Taken at T3BOARD",,,
-,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"sys_file","This is Kasper",,,
+,"uid","pid","deleted","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","uid_local","uid_foreign","tablenames","fieldname","sorting_foreign","title","description","alternative","link"
+,126,90,0,0,0,0,0,0,0,1,330,"tt_content","image",2,"T3BOARD",,,
+,127,90,0,0,0,0,0,0,0,21,330,"tt_content","image",1,"Kasper",,,
+,128,90,0,0,0,0,0,0,0,21,331,"tt_content","image",1,"Taken at T3BOARD",,,
+,129,90,0,0,0,0,0,0,0,1,331,"tt_content","image",2,"This is Kasper",,,
 "tt_content",,,,,,,,,,,,,,,,,,,
 ,"uid","pid","sorting","deleted","sys_language_uid","l18n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","header","image",,,,,,,
 ,330,90,512,0,0,0,0,0,0,0,"Regular Element #1",2,,,,,,,
diff --git a/typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript b/typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript
index 418661e3a90e..dd48118b9cea 100644
--- a/typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript
+++ b/typo3/sysext/core/Tests/Functional/Fixtures/Frontend/JsonRenderer.typoscript
@@ -12,7 +12,7 @@ config {
 			pages = uid,_PAGES_OVERLAY_UID,pid,sorting,title
 			sys_category = uid,_ORIG_uid,_LOCALIZED_UID,pid,sys_language_uid,title,parent,items,sys_language_uid
 			sys_file = uid,_ORIG_uid,_LOCALIZED_UID,pid,title,sys_language_uid
-			sys_file_reference = uid,_ORIG_uid,_LOCALIZED_UID,title,description,alternative,link,missing,identifier,file,pid,sys_language_uid,title,parent,items,sys_language_uid,uid_local,uid_foreign,tablenames,fieldname,table_local
+			sys_file_reference = uid,_ORIG_uid,_LOCALIZED_UID,title,description,alternative,link,missing,identifier,file,pid,sys_language_uid,title,parent,items,sys_language_uid,uid_local,uid_foreign,tablenames,fieldname
 			tt_content = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,header,categories,tx_testdatahandler_categories,tx_testdatahandler_category
 			tx_testdatahandler_element = uid,_ORIG_uid,_LOCALIZED_UID,pid,sorting,sys_language_uid,title
 		}
diff --git a/typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php b/typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php
index 021897a693d7..9977747af9a9 100644
--- a/typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php
+++ b/typo3/sysext/core/Tests/Unit/DataHandling/DataHandlerTest.php
@@ -1079,8 +1079,8 @@ class DataHandlerTest extends UnitTestCase
             '1' => ['table' => StringUtility::getUniqueId('bar_'), 'id' => 67],
         ];
 
-        $mockDataHandler = $this->getAccessibleMock(DataHandler::class, ['getInlineFieldType', 'deleteAction', 'createRelationHandlerInstance'], [], '', false);
-        $mockDataHandler->expects(self::once())->method('getInlineFieldType')->willReturn('field');
+        $mockDataHandler = $this->getAccessibleMock(DataHandler::class, ['getRelationFieldType', 'deleteAction', 'createRelationHandlerInstance'], [], '', false);
+        $mockDataHandler->expects(self::once())->method('getRelationFieldType')->willReturn('field');
         $mockDataHandler->expects(self::once())->method('createRelationHandlerInstance')->willReturn($mockRelationHandler);
         $mockDataHandler->expects(self::never())->method('deleteAction');
         $mockDataHandler->deleteRecord_procBasedOnFieldType($table, 42, 'bar', $conf);
diff --git a/typo3/sysext/core/Tests/Unit/Migrations/TcaMigrationTest.php b/typo3/sysext/core/Tests/Unit/Migrations/TcaMigrationTest.php
index f99f64932e49..79779b5cd3df 100644
--- a/typo3/sysext/core/Tests/Unit/Migrations/TcaMigrationTest.php
+++ b/typo3/sysext/core/Tests/Unit/Migrations/TcaMigrationTest.php
@@ -18,6 +18,7 @@ declare(strict_types=1);
 namespace TYPO3\CMS\Core\Tests\Unit\Migrations;
 
 use TYPO3\CMS\Core\Migrations\TcaMigration;
+use TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter;
 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
 
 /**
@@ -3109,4 +3110,381 @@ class TcaMigrationTest extends UnitTestCase
         $subject = new TcaMigration();
         self::assertSame($expected, $subject->migrate($input));
     }
+
+    private function falHandlingInTypeInlineIsMigratedToTypeFileDataProvider(): iterable
+    {
+        yield 'Full example of type=inline with foreign_table=sys_file_reference migrated to type=file' => [
+            'input' => [
+                'aTable' => [
+                    'columns' => [
+                        'aColumn' => [
+                            'config' => [
+                                'type' => 'inline',
+                                'minitems' => 1,
+                                'maxitems' => 2,
+                                'foreign_field' => 'uid_foreign',
+                                'foreign_label' => 'uid_local',
+                                'foreign_match_fields' => [
+                                    'fieldname' => 'aColumn',
+                                ],
+                                'foreign_selector' => 'uid_local',
+                                'foreign_unique' => 'uid_local',
+                                'foreign_sortby' => 'sorting_foreign',
+                                'foreign_table' => 'sys_file_reference',
+                                'foreign_table_field' => 'tablenames',
+                                'appearance' => [
+                                    'createNewRelationLinkTitle' => 'Add file',
+                                    'enabledControls' => [
+                                        'delete' => true,
+                                        'dragdrop' => true,
+                                        'sort' => false,
+                                        'hide' => true,
+                                        'info' => true,
+                                        'new' => false,
+                                    ],
+                                    'headerThumbnail' => [
+                                        'field' => 'uid_local',
+                                        'height' => '45m',
+                                    ],
+                                    'showPossibleLocalizationRecords' => true,
+                                    'useSortable' => true,
+                                    'showNewRecordLink' => true,
+                                    'newRecordLinkAddTitle' => true,
+                                    'newRecordLinkTitle' => true,
+                                    'levelLinksPosition' => 'both',
+                                    'useCombination' => true,
+                                    'suppressCombinationWarning' => true,
+                                ],
+                                'filter' => [
+                                    [
+                                        'userFunc' => FileExtensionFilter::class . '->filterInlineChildren',
+                                        'parameters' => [
+                                            'allowedFileExtensions' => 'jpg,png',
+                                            'disallowedFileExtensions' => '',
+                                        ],
+                                    ],
+                                ],
+                                'overrideChildTca' => [
+                                    'columns' => [
+                                        'uid_local' => [
+                                            'config' => [
+                                                'appearance' => [
+                                                    'elementBrowserAllowed' => 'jpg,png',
+                                                    'elementBrowserType' => 'file',
+                                                ],
+                                            ],
+                                        ],
+                                    ],
+                                    'types' => [
+                                        '0' => [
+                                            'showitem' => '--palette--;;somePalette',
+                                        ],
+                                    ],
+                                ],
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+            'expected' => [
+                'aTable' => [
+                    'columns' => [
+                        'aColumn' => [
+                            'config' => [
+                                'type' => 'file',
+                                'minitems' => 1,
+                                'maxitems' => 2,
+                                'appearance' => [
+                                    'createNewRelationLinkTitle' => 'Add file',
+                                    'enabledControls' => [
+                                        'delete' => true,
+                                        'dragdrop' => true,
+                                        'sort' => false,
+                                        'hide' => true,
+                                        'info' => true,
+                                    ],
+                                    'headerThumbnail' => [
+                                        'height' => '45m',
+                                    ],
+                                    'showPossibleLocalizationRecords' => true,
+                                    'useSortable' => true,
+                                ],
+                                'overrideChildTca' => [
+                                    'types' => [
+                                        '0' => [
+                                            'showitem' => '--palette--;;somePalette',
+                                        ],
+                                    ],
+                                ],
+                                'allowed' => 'jpg,png',
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+        ];
+        yield 'Allowed and disallowed list is migrated from unused filter' => [
+            'input' => [
+                'aTable' => [
+                    'columns' => [
+                        'aColumn' => [
+                            'config' => [
+                                'type' => 'inline',
+                                'foreign_table' => 'sys_file_reference',
+                                'filter' => [
+                                    [
+                                        'userFunc' => FileExtensionFilter::class . '->filterInlineChildren',
+                                        'parameters' => [
+                                            'allowedFileExtensions' => 'jpg,png',
+                                            'disallowedFileExtensions' => 'pdf,pages',
+                                        ],
+                                    ],
+                                ],
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+            'expected' => [
+                'aTable' => [
+                    'columns' => [
+                        'aColumn' => [
+                            'config' => [
+                                'type' => 'file',
+                                'allowed' => 'jpg,png',
+                                'disallowed' => 'pdf,pages',
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+        ];
+        yield 'Allowed list from filter takes precedence over element browser related option' => [
+            'input' => [
+                'aTable' => [
+                    'columns' => [
+                        'aColumn' => [
+                            'config' => [
+                                'type' => 'inline',
+                                'foreign_table' => 'sys_file_reference',
+                                'overrideChildTca' => [
+                                    'columns' => [
+                                        'uid_local' => [
+                                            'config' => [
+                                                'appearance' => [
+                                                    'elementBrowserAllowed' => 'jpg,png',
+                                                ],
+                                            ],
+                                        ],
+                                    ],
+                                ],
+                                'filter' => [
+                                    [
+                                        'userFunc' => FileExtensionFilter::class . '->filterInlineChildren',
+                                        'parameters' => [
+                                            'allowedFileExtensions' => 'pdf,docx',
+                                        ],
+                                    ],
+                                ],
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+            'expected' => [
+                'aTable' => [
+                    'columns' => [
+                        'aColumn' => [
+                            'config' => [
+                                'type' => 'file',
+                                'allowed' => 'pdf,docx',
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+        ];
+        yield 'customControls hook is removed' => [
+            'input' => [
+                'aTable' => [
+                    'columns' => [
+                        'aColumn' => [
+                            'config' => [
+                                'type' => 'inline',
+                                'foreign_table' => 'sys_file_reference',
+                                'customControls' => [
+                                    'userFunc' => '->someFunc()',
+                                ],
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+            'expected' => [
+                'aTable' => [
+                    'columns' => [
+                        'aColumn' => [
+                            'config' => [
+                                'type' => 'file',
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+            'The \'customControls\' option is not evaluated anymore',
+        ];
+        yield 'renamed appearance options are migrated' => [
+            'input' => [
+                'aTable' => [
+                    'columns' => [
+                        'aColumn' => [
+                            'config' => [
+                                'type' => 'inline',
+                                'foreign_table' => 'sys_file_reference',
+                                'appearance' => [
+                                    'showPossibleRecordsSelector' => false,
+                                ],
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+            'expected' => [
+                'aTable' => [
+                    'columns' => [
+                        'aColumn' => [
+                            'config' => [
+                                'type' => 'file',
+                                'appearance' => [
+                                    'showFileSelectors' => false,
+                                ],
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+        ];
+        yield 'Usage of sys_file_reference as foreign_table without type=inline is still possible' => [
+            'input' => [
+                'aTable' => [
+                    'columns' => [
+                        'aColumn' => [
+                            'config' => [
+                                'type' => 'select',
+                                'foreign_table' => 'sys_file_reference',
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+            'expected' => [
+                'aTable' => [
+                    'columns' => [
+                        'aColumn' => [
+                            'config' => [
+                                'type' => 'select',
+                                'foreign_table' => 'sys_file_reference',
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+        ];
+    }
+
+    /**
+     * @dataProvider falHandlingInTypeInlineIsMigratedToTypeFileDataProvider
+     * @test
+     * @param array<string, mixed> $input
+     * @param array<string, mixed> $expected
+     * @param string $expectedMessagePart
+     */
+    public function falHandlingInTypeInlineIsMigratedToTypeFile(array $input, array $expected, $expectedMessagePart = ''): void
+    {
+        $subject = new TcaMigration();
+        self::assertSame($expected, $subject->migrate($input));
+        if ($expectedMessagePart !== '') {
+            $messageFound = false;
+            foreach ($subject->getMessages() as $message) {
+                if (str_contains($message, $expectedMessagePart)) {
+                    $messageFound = true;
+                    break;
+                }
+            }
+            self::assertTrue($messageFound);
+        }
+    }
+
+    /**
+     * @test
+     */
+    public function falRelatedElementBrowserOptionsAreRemovedFromTypeGroup(): void
+    {
+        $input = [
+            'aTable' => [
+                'columns' => [
+                    'aColumns' => [
+                        'config' => [
+                            'type' => 'group',
+                            'appearance' => [
+                                'elementBrowserAllowed' => 'jpg,png',
+                                'elementBrowserType' => 'file',
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+        ];
+        $expected = [
+            'aTable' => [
+                'columns' => [
+                    'aColumns' => [
+                        'config' => [
+                            'type' => 'group',
+                        ],
+                    ],
+                ],
+            ],
+        ];
+        $subject = new TcaMigration();
+        self::assertSame($expected, $subject->migrate($input));
+    }
+
+    /**
+     * @test
+     */
+    public function falRelatedOptionsAreRemovedFromTypeInline(): void
+    {
+        $input = [
+            'aTable' => [
+                'columns' => [
+                    'aColumns' => [
+                        'config' => [
+                            'type' => 'inline',
+                            'appearance' => [
+                                'headerThumbnail' => [
+                                    'height' => '45c',
+                                ],
+                                'fileUploadAllowed' => true,
+                                'fileByUrlAllowed' => true,
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+        ];
+        $expected = [
+            'aTable' => [
+                'columns' => [
+                    'aColumns' => [
+                        'config' => [
+                            'type' => 'inline',
+                        ],
+                    ],
+                ],
+            ],
+        ];
+        $subject = new TcaMigration();
+        self::assertSame($expected, $subject->migrate($input));
+    }
 }
diff --git a/typo3/sysext/core/Tests/Unit/Preparations/TcaPreparationTest.php b/typo3/sysext/core/Tests/Unit/Preparations/TcaPreparationTest.php
index 7543d1227d88..c5cf0ac403ac 100644
--- a/typo3/sysext/core/Tests/Unit/Preparations/TcaPreparationTest.php
+++ b/typo3/sysext/core/Tests/Unit/Preparations/TcaPreparationTest.php
@@ -348,4 +348,30 @@ class TcaPreparationTest extends UnitTestCase
             ],
         ]);
     }
+
+    /**
+     * @test
+     */
+    public function prepareFileExtensionsReplacesPlaceholders(): void
+    {
+        $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] = 'jpg,png';
+
+        self::assertEquals(
+            'jpg,png,gif',
+            TcaPreparation::prepareFileExtensions(['common-image-types', 'gif'])
+        );
+    }
+
+    /**
+     * @test
+     */
+    public function prepareFileExtensionsRemovesDuplicates(): void
+    {
+        $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] = 'jpg,png';
+
+        self::assertEquals(
+            'jpg,png,gif',
+            TcaPreparation::prepareFileExtensions('common-image-types,jpg,gif')
+        );
+    }
 }
diff --git a/typo3/sysext/core/Tests/Unit/Resource/Utility/FileExtensionFilterTest.php b/typo3/sysext/core/Tests/Unit/Resource/Utility/FileExtensionFilterTest.php
index b398b808bf29..f2c976d2e4bc 100644
--- a/typo3/sysext/core/Tests/Unit/Resource/Utility/FileExtensionFilterTest.php
+++ b/typo3/sysext/core/Tests/Unit/Resource/Utility/FileExtensionFilterTest.php
@@ -41,37 +41,16 @@ class FileExtensionFilterTest extends UnitTestCase
     }
 
     /**
-     * @return array
-     */
-    public function invalidInlineChildrenFilterParametersDataProvider(): array
-    {
-        return [
-            [null, null, null],
-            ['', '', [0, '', null, false]],
-            [null, null, [0, '', null, false]],
-        ];
-    }
-
-    /**
-     * @param array|string $allowed
-     * @param array|string $disallowed
-     * @param array|string $values
      * @test
-     * @dataProvider invalidInlineChildrenFilterParametersDataProvider
      */
-    public function areInlineChildrenFilteredWithInvalidParameters($allowed, $disallowed, $values): void
+    public function areInlineChildrenFilteredWithInvalidParameters(): void
     {
-        $parameters = [
-            'allowedFileExtensions' => $allowed,
-            'disallowedFileExtensions' => $disallowed,
-            'values' => $values,
-        ];
         $dataHandlerProphecy = $this->prophesize(DataHandler::class);
         $dataHandlerProphecy->deleteAction()->shouldNotBeCalled();
         $resourceFactoryProphecy = $this->prophesize(ResourceFactory::class);
         $resourceFactoryProphecy->getFileReferenceObject()->shouldNotBeCalled();
         GeneralUtility::setSingletonInstance(ResourceFactory::class, $resourceFactoryProphecy->reveal());
-        (new FileExtensionFilter())->filterInlineChildren($parameters, $dataHandlerProphecy->reveal());
+        (new FileExtensionFilter())->filter([0, '', null, false], '', '', $dataHandlerProphecy->reveal());
     }
 
     /**
diff --git a/typo3/sysext/core/Tests/UnitDeprecated/Resource/Utility/FileExtensionFilterTest.php b/typo3/sysext/core/Tests/UnitDeprecated/Resource/Utility/FileExtensionFilterTest.php
new file mode 100644
index 000000000000..592dc09832e4
--- /dev/null
+++ b/typo3/sysext/core/Tests/UnitDeprecated/Resource/Utility/FileExtensionFilterTest.php
@@ -0,0 +1,77 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * 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!
+ */
+
+namespace TYPO3\CMS\Core\Tests\UnitDeprecated\Resource\Utility;
+
+use Prophecy\PhpUnit\ProphecyTrait;
+use TYPO3\CMS\Core\DataHandling\DataHandler;
+use TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter;
+use TYPO3\CMS\Core\Resource\ResourceFactory;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
+
+/**
+ * Test suite for filtering files by their extensions.
+ */
+class FileExtensionFilterTest extends UnitTestCase
+{
+    use ProphecyTrait;
+
+    /**
+     * Cleans up this test suite.
+     */
+    protected function tearDown(): void
+    {
+        GeneralUtility::purgeInstances();
+        parent::tearDown();
+    }
+
+    /**
+     * @return array
+     */
+    public function invalidInlineChildrenFilterParametersDataProvider(): array
+    {
+        return [
+            [null, null, null],
+            ['', '', [0, '', null, false]],
+            [null, null, [0, '', null, false]],
+        ];
+    }
+
+    /**
+     * @param array|string $allowed
+     * @param array|string $disallowed
+     * @param array|string $values
+     * @test
+     * @dataProvider invalidInlineChildrenFilterParametersDataProvider
+     */
+    public function areInlineChildrenFilteredWithInvalidParameters($allowed, $disallowed, $values): void
+    {
+        $parameters = [
+            'allowedFileExtensions' => $allowed,
+            'disallowedFileExtensions' => $disallowed,
+            'values' => $values,
+        ];
+
+        $dataHandlerProphecy = $this->prophesize(DataHandler::class);
+        $dataHandlerProphecy->deleteAction()->shouldNotBeCalled();
+        $resourceFactoryProphecy = $this->prophesize(ResourceFactory::class);
+        $resourceFactoryProphecy->getFileReferenceObject()->shouldNotBeCalled();
+        GeneralUtility::setSingletonInstance(ResourceFactory::class, $resourceFactoryProphecy->reveal());
+        (new FileExtensionFilter())->filterInlineChildren($parameters, $dataHandlerProphecy->reveal());
+    }
+}
diff --git a/typo3/sysext/core/ext_tables.sql b/typo3/sysext/core/ext_tables.sql
index 273a59b313d7..30e164f7ec4c 100644
--- a/typo3/sysext/core/ext_tables.sql
+++ b/typo3/sysext/core/ext_tables.sql
@@ -257,7 +257,6 @@ CREATE TABLE sys_file_reference (
 	tablenames varchar(64) DEFAULT '' NOT NULL,
 	fieldname varchar(64) DEFAULT '' NOT NULL,
 	sorting_foreign int(11) DEFAULT '0' NOT NULL,
-	table_local varchar(64) DEFAULT '' NOT NULL,
 
 	# Local usage overlay fields
 	title tinytext,
diff --git a/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Configuration/TCA/tx_blogexample_domain_model_blog.php b/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Configuration/TCA/tx_blogexample_domain_model_blog.php
index 029d8cc23ba8..076098eded42 100644
--- a/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Configuration/TCA/tx_blogexample_domain_model_blog.php
+++ b/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Configuration/TCA/tx_blogexample_domain_model_blog.php
@@ -118,7 +118,9 @@ return [
         'logo' => [
             'exclude' => true,
             'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xlf:tx_blogexample_domain_model_blog.logo',
-            'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig('logo', ['default' => 0]),
+            'config' => [
+                'type' => 'file',
+            ],
         ],
         'posts' => [
             'exclude' => true,
diff --git a/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Mapper/DataMapFactoryTest.php b/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Mapper/DataMapFactoryTest.php
index 5a501ef9880b..99cfc085bf60 100644
--- a/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Mapper/DataMapFactoryTest.php
+++ b/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Mapper/DataMapFactoryTest.php
@@ -471,6 +471,7 @@ class DataMapFactoryTest extends UnitTestCase
             [['type' => 'datetime'], TableColumnType::DATETIME],
             [['type' => 'color'], TableColumnType::COLOR],
             [['type' => 'number'], TableColumnType::NUMBER],
+            [['type' => 'file'], TableColumnType::FILE],
         ];
     }
 
diff --git a/typo3/sysext/fluid/Tests/Functional/Fixtures/ViewHelpers/Link/FileViewHelper/DatabaseImport.csv b/typo3/sysext/fluid/Tests/Functional/Fixtures/ViewHelpers/Link/FileViewHelper/DatabaseImport.csv
index 5da9e77a55e4..a7d8f26019dd 100644
--- a/typo3/sysext/fluid/Tests/Functional/Fixtures/ViewHelpers/Link/FileViewHelper/DatabaseImport.csv
+++ b/typo3/sysext/fluid/Tests/Functional/Fixtures/ViewHelpers/Link/FileViewHelper/DatabaseImport.csv
@@ -5,8 +5,8 @@ sys_file,,,,,,,,,,,,,,
 ,uid,pid,storage,type,identifier,identifier_hash,folder_hash,extension,mime_type,name,sha1,size,creation_date,modification_date
 ,1,0,1,2,/user_upload/typo3_image2.jpg,f90bb9a35622f35b5279195e324eddbaec8164b2,19669f1e02c2f16705ec7587044c66443be70725,jpg,image/jpeg,typo3_image2.jpg,da9acdf1e105784a57bbffec9520969578287797,7958,1389878273,1389878273
 sys_file_reference,,,,,,,,,,,,,,
-,uid,uid_local,uid_foreign,tablenames,fieldname,table_local,,,,,,,,
-,2,1,1,tt_content,image,sys_file,,,,,,,,
+,uid,uid_local,uid_foreign,tablenames,fieldname,,,,,,,,
+,2,1,1,tt_content,image,,,,,,,,
 sys_file_processedfile,,,,,,,,,,,,,,
 ,uid,storage,original,identifier,name,configuration,width,height,task_type,,,,,
 ,3,1,1,/_processed_/csm_typo3_image2_5c2670fd59.jpg,csm_typo3_image2_5c2670fd59.jpg,a:0:{},300,225,Image.Preview,,,,,
diff --git a/typo3/sysext/form/Documentation/I/Concepts/Finishers/Index.rst b/typo3/sysext/form/Documentation/I/Concepts/Finishers/Index.rst
index ddab24a77dd0..300157112f56 100644
--- a/typo3/sysext/form/Documentation/I/Concepts/Finishers/Index.rst
+++ b/typo3/sysext/form/Documentation/I/Concepts/Finishers/Index.rst
@@ -207,8 +207,6 @@ Here is an example for adding uploads to ext:news (fal_related_files and fal_med
             mapOnDatabaseColumn: uid_local
             skipIfValueIsEmpty: true
         databaseColumnMappings:
-          table_local:
-            value: sys_file
           tablenames:
             value: tx_news_domain_model_news
           fieldname:
@@ -229,8 +227,6 @@ Here is an example for adding uploads to ext:news (fal_related_files and fal_med
             mapOnDatabaseColumn: uid_local
             skipIfValueIsEmpty: true
         databaseColumnMappings:
-          table_local:
-            value: sys_file
           tablenames:
             value: tx_news_domain_model_news
           fieldname:
diff --git a/typo3/sysext/frontend/Configuration/TCA/backend_layout.php b/typo3/sysext/frontend/Configuration/TCA/backend_layout.php
index 6249545a53f5..ac202e271113 100644
--- a/typo3/sysext/frontend/Configuration/TCA/backend_layout.php
+++ b/typo3/sysext/frontend/Configuration/TCA/backend_layout.php
@@ -63,16 +63,14 @@ return [
         'icon' => [
             'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_tca.xlf:backend_layout.icon',
             'exclude' => true,
-            'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
-                'icon',
-                [
-                    'maxitems' => 1,
-                    'appearance' => [
-                        'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference',
-                    ],
+            'config' => [
+                'type' => 'file',
+                'allowed' => 'common-image-types',
+                'maxitems' => 1,
+                'appearance' => [
+                    'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference',
                 ],
-                $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
-            ),
+            ],
         ],
     ],
     'types' => [
diff --git a/typo3/sysext/frontend/Configuration/TCA/fe_users.php b/typo3/sysext/frontend/Configuration/TCA/fe_users.php
index 7557fcac54b5..dfbc885832bc 100644
--- a/typo3/sysext/frontend/Configuration/TCA/fe_users.php
+++ b/typo3/sysext/frontend/Configuration/TCA/fe_users.php
@@ -191,13 +191,11 @@ return [
         'image' => [
             'exclude' => true,
             'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.image',
-            'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
-                'image',
-                [
-                    'maxitems' => 6,
-                ],
-                $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
-            ),
+            'config' => [
+                'type' => 'file',
+                'allowed' => 'common-image-types',
+                'maxitems' => 6,
+            ],
         ],
         'disable' => [
             'exclude' => true,
diff --git a/typo3/sysext/frontend/Configuration/TCA/tt_content.php b/typo3/sysext/frontend/Configuration/TCA/tt_content.php
index 946b4a4e8cf3..ec8a89b05683 100644
--- a/typo3/sysext/frontend/Configuration/TCA/tt_content.php
+++ b/typo3/sysext/frontend/Configuration/TCA/tt_content.php
@@ -595,7 +595,9 @@ return [
         ],
         'image' => [
             'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.images',
-            'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig('image', [
+            'config' => [
+                'type' => 'file',
+                'allowed' => 'common-image-types',
                 'appearance' => [
                     'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference',
                     'showPossibleLocalizationRecords' => true,
@@ -636,11 +638,13 @@ return [
                         ],
                     ],
                 ],
-            ], $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']),
+            ],
         ],
         'assets' => [
             'label' => 'LLL:EXT:frontend/Resources/Private/Language/Database.xlf:tt_content.asset_references',
-            'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig('assets', [
+            'config' => [
+                'type' => 'file',
+                'allowed' => 'common-media-types',
                 'appearance' => [
                     'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/Database.xlf:tt_content.asset_references.addFileReference',
                     'showPossibleLocalizationRecords' => true,
@@ -681,7 +685,7 @@ return [
                         ],
                     ],
                 ],
-            ], $GLOBALS['TYPO3_CONF_VARS']['SYS']['mediafile_ext']),
+            ],
         ],
         'imagewidth' => [
             'exclude' => true,
@@ -973,12 +977,13 @@ return [
         ],
         'media' => [
             'label' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:media',
-            'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig('media', [
+            'config' => [
+                'type' => 'file',
                 'appearance' => [
                     'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:media.addFileReference',
                     'showPossibleLocalizationRecords' => true,
                 ],
-            ]),
+            ],
         ],
         'filelink_size' => [
             'exclude' => true,
diff --git a/typo3/sysext/frontend/Tests/Functional/ContentObject/DataSet/FileReferences.csv b/typo3/sysext/frontend/Tests/Functional/ContentObject/DataSet/FileReferences.csv
index d44afc82297d..8cb29a6dbe87 100644
--- a/typo3/sysext/frontend/Tests/Functional/ContentObject/DataSet/FileReferences.csv
+++ b/typo3/sysext/frontend/Tests/Functional/ContentObject/DataSet/FileReferences.csv
@@ -6,5 +6,5 @@
 ,1,0,2,1,"/user_upload/team-t3board10.jpg","jpg","image/jpeg","team-t3board10.jpg","ae6951147687ed1f94f60973fca7ef46e2ba2372",166843,1375080761,1374139442,0,0,"16ba2a587da8ef10dfccbe8b9841bde85afbd2d4","19669f1e02c2f16705ec7587044c66443be70725",0,,,
 ,,,,,,,,,,,,,,,,,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,,
-,"uid","pid","title","uid_local","uid_foreign","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","deleted","tablenames","fieldname","sorting_foreign","table_local","description","alternative","link","l10n_diffsource"
-,1,1,"T3BOARD",1,297,0,0,0,0,0,0,0,"tt_content","image",2,"sys_file",,,,
+,"uid","pid","title","uid_local","uid_foreign","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","deleted","tablenames","fieldname","sorting_foreign","description","alternative","link","l10n_diffsource"
+,1,1,"T3BOARD",1,297,0,0,0,0,0,0,0,"tt_content","image",2,,,,
diff --git a/typo3/sysext/frontend/Tests/Functional/ContentObject/DataSet/FilesContentObjectDataSet.csv b/typo3/sysext/frontend/Tests/Functional/ContentObject/DataSet/FilesContentObjectDataSet.csv
index 9b7e00916bd4..5cebb12b878b 100644
--- a/typo3/sysext/frontend/Tests/Functional/ContentObject/DataSet/FilesContentObjectDataSet.csv
+++ b/typo3/sysext/frontend/Tests/Functional/ContentObject/DataSet/FilesContentObjectDataSet.csv
@@ -18,23 +18,23 @@
 ,9,0,2,1,"/user_upload/file9.jpg","jpg","image/png","file9.jpg","ae6951147687ed1f94f60973fca7ef46e2ba2372",166843,1375080761,1374139442,0,0,"16ba2a587da8ef10dfccbe8b9841bde85afbd2d4","19669f1e02c2f16705ec7587044c66443be70725",0,,,
 ,,,,,,,,,,,,,,,,,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,,
-,"uid","pid","title","uid_local","uid_foreign","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","deleted","tablenames","fieldname","sorting_foreign","table_local","description","alternative","link","l10n_diffsource"
-,1,1,"T3BOARD",1,297,0,0,0,0,0,0,0,"tt_content","image",1,"sys_file",,,,
-,2,1,"Kasper",2,297,0,0,0,0,0,0,0,"tt_content","image",2,"sys_file",,,,
-,3,1,"TYPO3 Logo",3,297,0,0,0,0,0,0,0,"tt_content","image",3,"sys_file",,,,
-,4,1,"T3BOARD in collection",1,1,0,0,0,0,0,0,0,"sys_file_collection","files",1,"sys_file",,,,
-,5,1,"Kasper in collection",2,1,0,0,0,0,0,0,0,"sys_file_collection","files",2,"sys_file",,,,
-,6,1,"TYPO3 Logo in collection",3,1,0,0,0,0,0,0,0,"sys_file_collection","files",3,"sys_file",,,,
-,7,1,"T3BOARD in collection",4,2,0,0,0,0,0,0,0,"sys_file_collection","files",1,"sys_file",,,,
-,8,1,"Kasper in collection",5,2,0,0,0,0,0,0,0,"sys_file_collection","files",2,"sys_file",,,,
-,9,1,"TYPO3 Logo in collection",6,2,0,0,0,0,0,0,0,"sys_file_collection","files",3,"sys_file",,,,
-,10,1,"T3BOARD in collection",7,3,0,0,0,0,0,0,0,"sys_file_collection","files",1,"sys_file",,,,
-,11,1,"Kasper in collection",8,3,0,0,0,0,0,0,0,"sys_file_collection","files",2,"sys_file",,,,
-,12,1,"TYPO3 Logo in collection",9,3,0,0,0,0,0,0,0,"sys_file_collection","files",3,"sys_file",,,,
-,13,1,"File 4",4,298,0,0,0,0,0,0,0,"tt_content","image",1,"sys_file",,,,
-,14,1,"File 5",5,298,0,0,0,0,0,0,0,"tt_content","image",2,"sys_file",,,,
-,15,1,"File 6",6,298,0,0,0,0,0,0,0,"tt_content","image",3,"sys_file",,,,
-,16,1,"File 7",7,1,0,0,0,0,0,0,0,"pages","media",2,"sys_file",,,,
+,"uid","pid","title","uid_local","uid_foreign","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","deleted","tablenames","fieldname","sorting_foreign","description","alternative","link","l10n_diffsource"
+,1,1,"T3BOARD",1,297,0,0,0,0,0,0,0,"tt_content","image",1,,,,
+,2,1,"Kasper",2,297,0,0,0,0,0,0,0,"tt_content","image",2,,,,
+,3,1,"TYPO3 Logo",3,297,0,0,0,0,0,0,0,"tt_content","image",3,,,,
+,4,1,"T3BOARD in collection",1,1,0,0,0,0,0,0,0,"sys_file_collection","files",1,,,,
+,5,1,"Kasper in collection",2,1,0,0,0,0,0,0,0,"sys_file_collection","files",2,,,,
+,6,1,"TYPO3 Logo in collection",3,1,0,0,0,0,0,0,0,"sys_file_collection","files",3,,,,
+,7,1,"T3BOARD in collection",4,2,0,0,0,0,0,0,0,"sys_file_collection","files",1,,,,
+,8,1,"Kasper in collection",5,2,0,0,0,0,0,0,0,"sys_file_collection","files",2,,,,
+,9,1,"TYPO3 Logo in collection",6,2,0,0,0,0,0,0,0,"sys_file_collection","files",3,,,,
+,10,1,"T3BOARD in collection",7,3,0,0,0,0,0,0,0,"sys_file_collection","files",1,,,,
+,11,1,"Kasper in collection",8,3,0,0,0,0,0,0,0,"sys_file_collection","files",2,,,,
+,12,1,"TYPO3 Logo in collection",9,3,0,0,0,0,0,0,0,"sys_file_collection","files",3,,,,
+,13,1,"File 4",4,298,0,0,0,0,0,0,0,"tt_content","image",1,,,,
+,14,1,"File 5",5,298,0,0,0,0,0,0,0,"tt_content","image",2,,,,
+,15,1,"File 6",6,298,0,0,0,0,0,0,0,"tt_content","image",3,,,,
+,16,1,"File 7",7,1,0,0,0,0,0,0,0,"pages","media",2,,,,
 "sys_file_storage",,,,,,,,,,,,,,,,,,,,
 ,"uid","pid","name","driver","configuration","is_browsable","is_public","is_writable","is_online",,,,,,,,,,,
 ,1,0,"Storage 1","Local","<?xml version='1.0' encoding='utf-8' standalone='yes' ?><T3FlexForms><data><sheet index='sDEF'><language index='lDEF'><field index='basePath'><value index='vDEF'>fileadmin/</value></field><field index='pathType'><value index='vDEF'>relative</value></field><field index='caseSensitive'><value index='vDEF'>1</value></field></language></sheet></data></T3FlexForms>",1,1,1,1,,,,,,,,,,,
diff --git a/typo3/sysext/frontend/Tests/Functional/Rendering/DataSet/LiveDefaultElements.csv b/typo3/sysext/frontend/Tests/Functional/Rendering/DataSet/LiveDefaultElements.csv
index 77104f4c6f8a..473ba480380c 100644
--- a/typo3/sysext/frontend/Tests/Functional/Rendering/DataSet/LiveDefaultElements.csv
+++ b/typo3/sysext/frontend/Tests/Functional/Rendering/DataSet/LiveDefaultElements.csv
@@ -24,14 +24,14 @@
 ,1,0,0,0,0,0,0,0,0,1,"Image Kasper",401,600,,,0,,,,
 ,21,0,0,0,0,0,0,0,0,21,"Image T3BOARD",1024,683,,,0,,,,
 "sys_file_reference",,,,,,,,,,,,,,,,,,,,
-,"uid","pid","title","uid_local","uid_foreign","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","deleted","tablenames","fieldname","sorting_foreign","table_local","description","alternative","link","l10n_diffsource"
-,126,89,"T3BOARD",1,297,0,0,0,0,0,0,0,"tt_content","image",2,"sys_file",,,,
-,127,89,"Kasper",21,299,0,0,0,0,0,0,0,"tt_content","image",1,"sys_file",,,,
-,128,89,"[Kasper] Image translated to Dansk",21,300,1,127,0,0,0,0,0,"tt_content","image",1,"sys_file",,,,
-,129,89,"[T3BOARD] Image added in Dansk (without parent)",1,300,1,0,0,0,0,0,0,"tt_content","image",2,"sys_file",,,,
-,130,89,"[T3BOARD] Image added to DK element without default language",1,303,1,0,0,0,0,0,0,"tt_content","image",1,"sys_file",,,,
-,131,89,"[T3BOARD] image translated to DE from DK",1,302,2,0,0,0,0,0,0,"tt_content","image",1,"sys_file",,,,
-,132,89,"Kasper2",1,298,0,0,0,0,0,0,0,"tt_content","image",1,"sys_file",,,,
+,"uid","pid","title","uid_local","uid_foreign","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","deleted","tablenames","fieldname","sorting_foreign","description","alternative","link","l10n_diffsource"
+,126,89,"T3BOARD",1,297,0,0,0,0,0,0,0,"tt_content","image",2,,,,
+,127,89,"Kasper",21,299,0,0,0,0,0,0,0,"tt_content","image",1,,,,
+,128,89,"[Kasper] Image translated to Dansk",21,300,1,127,0,0,0,0,0,"tt_content","image",1,,,,
+,129,89,"[T3BOARD] Image added in Dansk (without parent)",1,300,1,0,0,0,0,0,0,"tt_content","image",2,,,,
+,130,89,"[T3BOARD] Image added to DK element without default language",1,303,1,0,0,0,0,0,0,"tt_content","image",1,,,,
+,131,89,"[T3BOARD] image translated to DE from DK",1,302,2,0,0,0,0,0,0,"tt_content","image",1,,,,
+,132,89,"Kasper2",1,298,0,0,0,0,0,0,0,"tt_content","image",1,,,,
 "sys_category",,,,,,,,,,,,,,,,,,,,
 ,"uid","pid","title","sys_language_uid","l10n_parent","t3ver_wsid","t3ver_state","t3ver_stage","t3ver_oid","deleted",,,,,,,,,,
 ,1,89,"Category 1",0,0,0,0,0,0,0,,,,,,,,,,
diff --git a/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentWithImagesTest.php b/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentWithImagesTest.php
index 6815c3805973..4ba68165af85 100644
--- a/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentWithImagesTest.php
+++ b/typo3/sysext/impexp/Tests/Functional/Export/PagesAndTtContentWithImagesTest.php
@@ -165,7 +165,6 @@ class PagesAndTtContentWithImagesTest extends AbstractImportExportTestCase
                     'tablenames',
                     'fieldname',
                     'sorting_foreign',
-                    'table_local',
                     'title',
                     'description',
                     'alternative',
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithDifferentImageToExistingData.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithDifferentImageToExistingData.csv
index 818c3f2ab102..218517efe922 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithDifferentImageToExistingData.csv
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithDifferentImageToExistingData.csv
@@ -19,9 +19,9 @@
 ,3,0,1,2,"/user_upload/typo3_image5.jpg","8180e85d25c96697ec9d2004683216831b91ffc1","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image5.jpg","c3511df85d21bc578faf71c6a19eeb3ff44af370",7425
 ,4,0,1,2,"/user_upload/typo3_image2_01.jpg","299dc37e3c3428b85d9b39c353c6557fa834dac5","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2_01.jpg","e873c1e2ffd0f191e183a1057de3eef4d62e782d",5565
 "sys_file_reference",,,,,,,,,,,,
-,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link",
-,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
-,2,4,4,2,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
+,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link",
+,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,,
+,2,4,4,2,"tt_content","image",\NULL,\NULL,\NULL,,
 "sys_file_metadata",,,,,,,,,,,,
 ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",,
 ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",0,0,,
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImageWithForcedUids.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImageWithForcedUids.csv
index 0244828fa9ef..16accd19096e 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImageWithForcedUids.csv
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImageWithForcedUids.csv
@@ -12,8 +12,8 @@
 ,"uid","pid","storage","type","identifier","identifier_hash","folder_hash","extension","mime_type","name","sha1","size"
 ,1,0,1,2,"/user_upload/typo3_image2.jpg","f90bb9a35622f35b5279195e324eddbaec8164b2","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2.jpg","da9acdf1e105784a57bbffec9520969578287797",7958
 "sys_file_reference",,,,,,,,,,,,
-,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link",
-,101,8,1,21,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
+,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link",
+,101,8,1,21,"tt_content","image",\NULL,\NULL,\NULL,,
 "sys_file_metadata",,,,,,,,,,,,
 ,"uid","pid","file","title","width","height","description","alternative",,,,
 ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",,,,
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButNotIncluded.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButNotIncluded.csv
index 9572387bf7d1..614380e45535 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButNotIncluded.csv
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButNotIncluded.csv
@@ -12,8 +12,8 @@
 ,"uid","pid","storage","type","identifier","identifier_hash","folder_hash","extension","mime_type","name","sha1","size"
 ,1,0,1,2,"/user_upload/typo3_image2.jpg","f90bb9a35622f35b5279195e324eddbaec8164b2","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2.jpg","da9acdf1e105784a57bbffec9520969578287797",7958
 "sys_file_reference",,,,,,,,,,,,
-,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link",
-,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
+,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link",
+,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,,
 "sys_file_metadata",,,,,,,,,,,,
 ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",,
 ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",0,0,,
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseInsensitiveFilesystems.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseInsensitiveFilesystems.csv
index 644b4706c231..5dfe3b76eafe 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseInsensitiveFilesystems.csv
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseInsensitiveFilesystems.csv
@@ -12,8 +12,8 @@
 ,"uid","pid","storage","type","identifier","identifier_hash","folder_hash","extension","mime_type","name","sha1","size"
 ,1,0,1,2,"/user_upload/typo3_image2.jpg","f90bb9a35622f35b5279195e324eddbaec8164b2","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2.jpg","da9acdf1e105784a57bbffec9520969578287797",7958
 "sys_file_reference",,,,,,,,,,,,
-,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link",
-,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
+,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link",
+,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,,
 "sys_file_metadata",,,,,,,,,,,,
 ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",,
 ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",0,0,,
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseSensitiveFilesystems.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseSensitiveFilesystems.csv
index e67dab07d8f0..fa13768e34ee 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseSensitiveFilesystems.csv
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesButWithoutStorageOnCaseSensitiveFilesystems.csv
@@ -12,8 +12,8 @@
 ,"uid","pid","storage","type","identifier","identifier_hash","folder_hash","extension","mime_type","name","sha1","size"
 ,1,0,1,2,"/user_upload/typo3_image2.jpg","f90bb9a35622f35b5279195e324eddbaec8164b2","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2.jpg","da9acdf1e105784a57bbffec9520969578287797",7958
 "sys_file_reference",,,,,,,,,,,,
-,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link",
-,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
+,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link",
+,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,,
 "sys_file_metadata",,,,,,,,,,,,
 ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",,
 ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",0,0,,
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesOnCaseInsensitiveFilesystems.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesOnCaseInsensitiveFilesystems.csv
index 4620e2d28668..9cd8fca77de1 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesOnCaseInsensitiveFilesystems.csv
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesOnCaseInsensitiveFilesystems.csv
@@ -12,8 +12,8 @@
 ,"uid","pid","storage","type","identifier","identifier_hash","folder_hash","extension","mime_type","name","sha1","size"
 ,1,0,1,2,"/user_upload/typo3_image2.jpg","f90bb9a35622f35b5279195e324eddbaec8164b2","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2.jpg","da9acdf1e105784a57bbffec9520969578287797",7958
 "sys_file_reference",,,,,,,,,,,,
-,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link",
-,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
+,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link",
+,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,,
 "sys_file_metadata",,,,,,,,,,,,
 ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",,
 ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",0,0,,
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesOnCaseSensitiveFilesystems.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesOnCaseSensitiveFilesystems.csv
index 5185d10d3916..41b0a032e047 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesOnCaseSensitiveFilesystems.csv
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesOnCaseSensitiveFilesystems.csv
@@ -12,8 +12,8 @@
 ,"uid","pid","storage","type","identifier","identifier_hash","folder_hash","extension","mime_type","name","sha1","size"
 ,1,0,1,2,"/user_upload/typo3_image2.jpg","f90bb9a35622f35b5279195e324eddbaec8164b2","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2.jpg","da9acdf1e105784a57bbffec9520969578287797",7958
 "sys_file_reference",,,,,,,,,,,,
-,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link",
-,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
+,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link",
+,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,,
 "sys_file_metadata",,,,,,,,,,,,
 ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",,
 ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",0,0,,
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesWithSpacesInPath.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesWithSpacesInPath.csv
index d60382d11a86..54dcb72467ba 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesWithSpacesInPath.csv
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithImagesWithSpacesInPath.csv
@@ -13,8 +13,8 @@
 ,1,0,1,2,"/user_upload/folder_with_spaces/typo3_image2.jpg","060a2cd7f623c1c4c3edaf20f2dd561dadc30354","9de358f64a020b01f020a76ff7c59674913ba5c5","jpg","image/jpeg","typo3_image2.jpg","da9acdf1e105784a57bbffec9520969578287797",7958
 ,2,0,1,2,"/user_upload/folder_with_spaces/typo3_image3.jpg","53313966f99b5d632c1db8799ae25349ad3318f8","9de358f64a020b01f020a76ff7c59674913ba5c5","jpg","image/jpeg","typo3_image3.jpg","e873c1e2ffd0f191e183a1057de3eef4d62e782d",5565
 "sys_file_reference",,,,,,,,,,,,
-,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link",
-,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
+,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link",
+,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,,
 "sys_file_metadata",,,,,,,,,,,,
 ,"uid","pid","file","title","width","height","description","alternative",,,,
 ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",,,,
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithSameImageToExistingData.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithSameImageToExistingData.csv
index b1b6fe9be26c..7ad34fde038f 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithSameImageToExistingData.csv
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndRelatedTtContentWithSameImageToExistingData.csv
@@ -18,9 +18,9 @@
 ,2,0,1,2,"/user_upload/typo3_image3.jpg","25777b72e5e1cbed2d1b33e4fe5b737304b5bd28","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image3.jpg","e873c1e2ffd0f191e183a1057de3eef4d62e782d",5565
 ,3,0,1,2,"/user_upload/typo3_image5.jpg","8180e85d25c96697ec9d2004683216831b91ffc1","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image5.jpg","c3511df85d21bc578faf71c6a19eeb3ff44af370",7425
 "sys_file_reference",,,,,,,,,,,,
-,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link",
-,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
-,2,4,1,2,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
+,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link",
+,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,,
+,2,4,1,2,"tt_content","image",\NULL,\NULL,\NULL,,
 "sys_file_metadata",,,,,,,,,,,,
 ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",,
 ,1,0,1,"New title of the dummy image",400,300,"This is a dummy image.","Photo of program code",0,0,,
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndTtContentWithRemappingNewSysFileEntries.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndTtContentWithRemappingNewSysFileEntries.csv
index 7c40c540654c..de2638de2ddb 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndTtContentWithRemappingNewSysFileEntries.csv
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/importPagesAndTtContentWithRemappingNewSysFileEntries.csv
@@ -15,7 +15,7 @@
 ,2,0,1,2,"/user_upload/used-1.jpg","a0d28ab6398a25c7a0c24f6ace6a3b43d773115e","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","used-1.jpg","da9acdf1e105784a57bbffec9520969578287797",7958
 ,3,0,1,2,"/user_upload/used-2.jpg","5fd92415f6154c29349bbfb214b9e2d9dbb3d89a","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","used-2.jpg","c3511df85d21bc578faf71c6a19eeb3ff44af370",7425
 "sys_file_reference",,,,,,,,,,,,
-,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link",
-,1,1,3,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
-,2,1,3,2,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
-,3,1,2,3,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
+,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link",
+,1,1,3,1,"tt_content","image",\NULL,\NULL,\NULL,,
+,2,1,3,2,"tt_content","image",\NULL,\NULL,\NULL,,
+,3,1,2,3,"tt_content","image",\NULL,\NULL,\NULL,,
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentKeepsRelationsBetweenImportedPagesAndRecords.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentKeepsRelationsBetweenImportedPagesAndRecords.csv
index 70a30e464fbc..9bffe8fd622b 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentKeepsRelationsBetweenImportedPagesAndRecords.csv
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentKeepsRelationsBetweenImportedPagesAndRecords.csv
@@ -18,9 +18,9 @@
 ,2,0,1,2,"/user_upload/typo3_image3.jpg","25777b72e5e1cbed2d1b33e4fe5b737304b5bd28","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image3.jpg","e873c1e2ffd0f191e183a1057de3eef4d62e782d",5565
 ,3,0,1,2,"/user_upload/typo3_image5.jpg","8180e85d25c96697ec9d2004683216831b91ffc1","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image5.jpg","c3511df85d21bc578faf71c6a19eeb3ff44af370",7425
 "sys_file_reference",,,,,,,,,,,,
-,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link",
-,1,1,1,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
-,2,5,1,2,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
+,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link",
+,1,1,1,1,"tt_content","image",\NULL,\NULL,\NULL,,
+,2,5,1,2,"tt_content","image",\NULL,\NULL,\NULL,,
 "sys_file_metadata",,,,,,,,,,,,
 ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",,
 ,1,0,1,"Dummy image",400,300,"This is a dummy image.","Photo of program code",0,0,,
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentWithDifferentImageToExistingData.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentWithDifferentImageToExistingData.csv
index 07a657ff30ca..19cfb86c56c0 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentWithDifferentImageToExistingData.csv
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentWithDifferentImageToExistingData.csv
@@ -16,8 +16,8 @@
 ,3,0,1,2,"/user_upload/typo3_image5.jpg","8180e85d25c96697ec9d2004683216831b91ffc1","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image5.jpg","c3511df85d21bc578faf71c6a19eeb3ff44af370",7425
 ,4,0,1,2,"/user_upload/typo3_image2_01.jpg","299dc37e3c3428b85d9b39c353c6557fa834dac5","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2_01.jpg","e873c1e2ffd0f191e183a1057de3eef4d62e782d",5565
 "sys_file_reference",,,,,,,,,,,,
-,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link",
-,1,1,4,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
+,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link",
+,1,1,4,1,"tt_content","image",\NULL,\NULL,\NULL,,
 "sys_file_metadata",,,,,,,,,,,,
 ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",,
 ,1,0,4,\NULL,400,267,\NULL,\NULL,0,0,,
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentWithDifferentImageToExistingDataAndPagesAsNew.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentWithDifferentImageToExistingDataAndPagesAsNew.csv
index aa8bb6cadae5..13d6ab978689 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentWithDifferentImageToExistingDataAndPagesAsNew.csv
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseAssertions/updatePagesAndRelatedTtContentWithDifferentImageToExistingDataAndPagesAsNew.csv
@@ -18,8 +18,8 @@
 ,3,0,1,2,"/user_upload/typo3_image5.jpg","8180e85d25c96697ec9d2004683216831b91ffc1","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image5.jpg","c3511df85d21bc578faf71c6a19eeb3ff44af370",7425
 ,4,0,1,2,"/user_upload/typo3_image2_01.jpg","299dc37e3c3428b85d9b39c353c6557fa834dac5","19669f1e02c2f16705ec7587044c66443be70725","jpg","image/jpeg","typo3_image2_01.jpg","e873c1e2ffd0f191e183a1057de3eef4d62e782d",5565
 "sys_file_reference",,,,,,,,,,,,
-,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","table_local","title","description","alternative","link",
-,1,4,4,1,"tt_content","image","sys_file",\NULL,\NULL,\NULL,,
+,"uid","pid","uid_local","uid_foreign","tablenames","fieldname","title","description","alternative","link",
+,1,4,4,1,"tt_content","image",\NULL,\NULL,\NULL,,
 "sys_file_metadata",,,,,,,,,,,,
 ,"uid","pid","file","title","width","height","description","alternative","sys_language_uid","l10n_parent",,
 ,1,0,4,\NULL,400,267,\NULL,\NULL,0,0,,
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseImports/sys_file_reference.csv b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseImports/sys_file_reference.csv
index 9a7b9ea39fd5..d48d37520f87 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseImports/sys_file_reference.csv
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/DatabaseImports/sys_file_reference.csv
@@ -1,3 +1,3 @@
 sys_file_reference,,,,,,,,
-,uid,pid,uid_local,uid_foreign,tablenames,fieldname,table_local,l10n_diffsource
-,1,1,1,1,tt_content,image,sys_file,
+,uid,pid,uid_local,uid_foreign,tablenames,fieldname,l10n_diffsource
+,1,1,1,1,tt_content,image,
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-corrupt-image.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-corrupt-image.xml
index 6bac66560de2..ca506751cf52 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-corrupt-image.xml
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-corrupt-image.xml
@@ -209,7 +209,6 @@
 				<field index="tablenames">tt_content</field>
 				<field index="fieldname">image</field>
 				<field index="sorting_foreign" type="integer">0</field>
-				<field index="table_local">sys_file</field>
 				<field index="title" type="NULL"></field>
 				<field index="description" type="NULL"></field>
 				<field index="alternative" type="NULL"></field>
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-image-but-not-included.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-image-but-not-included.xml
index 9723ad2656c2..9d9a20b6c607 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-image-but-not-included.xml
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-image-but-not-included.xml
@@ -209,7 +209,6 @@
 				<field index="tablenames">tt_content</field>
 				<field index="fieldname">image</field>
 				<field index="sorting_foreign" type="integer">0</field>
-				<field index="table_local">sys_file</field>
 				<field index="title" type="NULL"></field>
 				<field index="description" type="NULL"></field>
 				<field index="alternative" type="NULL"></field>
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-image.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-image.xml
index f24eb2d59c1d..01d6d5e16aaa 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-image.xml
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlExports/pages-and-ttcontent-with-image.xml
@@ -209,7 +209,6 @@
 				<field index="tablenames">tt_content</field>
 				<field index="fieldname">image</field>
 				<field index="sorting_foreign" type="integer">0</field>
-				<field index="table_local">sys_file</field>
 				<field index="title" type="NULL"></field>
 				<field index="description" type="NULL"></field>
 				<field index="alternative" type="NULL"></field>
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-existing-different-image.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-existing-different-image.xml
index 28daee188dba..30a8cfc6dfe1 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-existing-different-image.xml
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-existing-different-image.xml
@@ -192,7 +192,6 @@
 				<field index="tablenames">tt_content</field>
 				<field index="fieldname">image</field>
 				<field index="sorting_foreign">0</field>
-				<field index="table_local">sys_file</field>
 				<field index="title" type="NULL"></field>
 				<field index="description" type="NULL"></field>
 				<field index="alternative" type="NULL"></field>
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-existing-same-image.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-existing-same-image.xml
index ba40131497d9..ffcd35bd9a02 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-existing-same-image.xml
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-existing-same-image.xml
@@ -192,7 +192,6 @@
 				<field index="tablenames">tt_content</field>
 				<field index="fieldname">image</field>
 				<field index="sorting_foreign">0</field>
-				<field index="table_local">sys_file</field>
 				<field index="title" type="NULL"></field>
 				<field index="description" type="NULL"></field>
 				<field index="alternative" type="NULL"></field>
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-but-not-included.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-but-not-included.xml
index 10a05be16bb9..aee0f50e09a3 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-but-not-included.xml
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-but-not-included.xml
@@ -245,7 +245,6 @@
 				<field index="tablenames">tt_content</field>
 				<field index="fieldname">image</field>
 				<field index="sorting_foreign">0</field>
-				<field index="table_local">sys_file</field>
 				<field index="title" type="NULL"></field>
 				<field index="description" type="NULL"></field>
 				<field index="alternative" type="NULL"></field>
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-forced-uids.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-forced-uids.xml
index 14c2037491cc..dcc509250044 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-forced-uids.xml
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-forced-uids.xml
@@ -237,7 +237,6 @@
 				<field index="tablenames">tt_content</field>
 				<field index="fieldname">image</field>
 				<field index="sorting_foreign">0</field>
-				<field index="table_local">sys_file</field>
 				<field index="title" type="NULL"></field>
 				<field index="description" type="NULL"></field>
 				<field index="alternative" type="NULL"></field>
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-invalid-storage.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-invalid-storage.xml
index 6ad29a728f87..2f909459b8b9 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-invalid-storage.xml
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-invalid-storage.xml
@@ -245,7 +245,6 @@
 				<field index="tablenames">tt_content</field>
 				<field index="fieldname">image</field>
 				<field index="sorting_foreign">0</field>
-				<field index="table_local">sys_file</field>
 				<field index="title" type="NULL"></field>
 				<field index="description" type="NULL"></field>
 				<field index="alternative" type="NULL"></field>
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-spaces-in-path.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-spaces-in-path.xml
index f0da39847a8d..81b2635eed6d 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-spaces-in-path.xml
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-with-spaces-in-path.xml
@@ -211,7 +211,6 @@
 				<field index="tablenames">tt_content</field>
 				<field index="fieldname">image</field>
 				<field index="sorting_foreign">0</field>
-				<field index="table_local">sys_file</field>
 				<field index="title" type="NULL"></field>
 				<field index="description" type="NULL"></field>
 				<field index="alternative" type="NULL"></field>
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-without-storage.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-without-storage.xml
index 6a6c21be699f..51bba3354015 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-without-storage.xml
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image-without-storage.xml
@@ -202,7 +202,6 @@
 				<field index="tablenames">tt_content</field>
 				<field index="fieldname">image</field>
 				<field index="sorting_foreign">0</field>
-				<field index="table_local">sys_file</field>
 				<field index="title" type="NULL"></field>
 				<field index="description" type="NULL"></field>
 				<field index="alternative" type="NULL"></field>
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image.xml
index c14399d80338..65626d0c7935 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image.xml
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-image.xml
@@ -245,7 +245,6 @@
 				<field index="tablenames">tt_content</field>
 				<field index="fieldname">image</field>
 				<field index="sorting_foreign">0</field>
-				<field index="table_local">sys_file</field>
 				<field index="title" type="NULL"></field>
 				<field index="description" type="NULL"></field>
 				<field index="alternative" type="NULL"></field>
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-missing-image.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-missing-image.xml
index 6894844bf3b3..933827009260 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-missing-image.xml
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-missing-image.xml
@@ -192,7 +192,6 @@
 				<field index="tablenames">tt_content</field>
 				<field index="fieldname">image</field>
 				<field index="sorting_foreign">0</field>
-				<field index="table_local">sys_file</field>
 				<field index="title" type="NULL"></field>
 				<field index="description" type="NULL"></field>
 				<field index="alternative" type="NULL"></field>
diff --git a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-two-images.xml b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-two-images.xml
index b8c1f0097694..d358b74ad98b 100644
--- a/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-two-images.xml
+++ b/typo3/sysext/impexp/Tests/Functional/Fixtures/XmlImports/pages-and-ttcontent-with-two-images.xml
@@ -263,7 +263,6 @@
 				<field index="tablenames">tt_content</field>
 				<field index="fieldname">image</field>
 				<field index="sorting_foreign">0</field>
-				<field index="table_local">sys_file</field>
 				<field index="title" type="NULL"></field>
 				<field index="description" type="NULL"></field>
 				<field index="alternative" type="NULL"></field>
@@ -290,7 +289,6 @@
 				<field index="tablenames">tt_content</field>
 				<field index="fieldname">image</field>
 				<field index="sorting_foreign">0</field>
-				<field index="table_local">sys_file</field>
 				<field index="title" type="NULL"></field>
 				<field index="description" type="NULL"></field>
 				<field index="alternative" type="NULL"></field>
@@ -317,7 +315,6 @@
 				<field index="tablenames">tt_content</field>
 				<field index="fieldname">image</field>
 				<field index="sorting_foreign">0</field>
-				<field index="table_local">sys_file</field>
 				<field index="title" type="NULL"></field>
 				<field index="description" type="NULL"></field>
 				<field index="alternative" type="NULL"></field>
diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php
index 66650f5d74fc..501230959b8b 100644
--- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php
+++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php
@@ -2182,4 +2182,9 @@ return [
             'Breaking-98490-VariousHooksAndMethodsChangedInDatabaseRecordList.rst',
         ],
     ],
+    'TYPO3\CMS\Core\Resource\Service\UserFileInlineLabelService' => [
+        'restFiles' => [
+            'Deprecation-98479-DeprecatedFileReferenceRelatedFunctionality.rst',
+        ],
+    ],
 ];
diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php
index 6b67de65662a..f9ff9b58f2d4 100644
--- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php
+++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php
@@ -5351,5 +5351,11 @@ return [
             'Breaking-98490-VariousHooksAndMethodsChangedInDatabaseRecordList.rst',
         ],
     ],
-
+    'TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter->filterInlineChildren' => [
+        'numberOfMandatoryArguments' => 2,
+        'maximumNumberOfArguments' => 2,
+        'restFiles' => [
+            'Deprecation-98479-DeprecatedFileReferenceRelatedFunctionality.rst',
+        ],
+    ],
 ];
diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php
index d9dd1f44ecc4..5671d1f86d61 100644
--- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php
+++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php
@@ -1392,4 +1392,11 @@ return [
             'Deprecation-97544-PreviewURIGenerationRelatedFunctionalityInBackendUtility.rst',
         ],
     ],
+    'TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig' => [
+        'numberOfMandatoryArguments' => 1,
+        'maximumNumberOfArguments' => 4,
+        'restFiles' => [
+            'Deprecation-98479-DeprecatedFileReferenceRelatedFunctionality.rst',
+        ],
+    ],
 ];
diff --git a/typo3/sysext/seo/Configuration/TCA/Overrides/pages.php b/typo3/sysext/seo/Configuration/TCA/Overrides/pages.php
index f784c40268cc..11146a456a3d 100644
--- a/typo3/sysext/seo/Configuration/TCA/Overrides/pages.php
+++ b/typo3/sysext/seo/Configuration/TCA/Overrides/pages.php
@@ -181,33 +181,31 @@ $tca = [
         'og_image' => [
             'exclude' => true,
             'label' => 'LLL:EXT:seo/Resources/Private/Language/locallang_tca.xlf:pages.og_image',
-            'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
-                'og_image',
-                [
-                    // Use the imageoverlayPalette instead of the basicoverlayPalette
-                    'overrideChildTca' => [
-                        'types' => [
-                            '0' => [
-                                'showitem' => '
-                                    --palette--;;imageoverlayPalette,
-                                    --palette--;;filePalette',
-                            ],
-                            \TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [
-                                'showitem' => '
-                                    --palette--;;imageoverlayPalette,
-                                    --palette--;;filePalette',
-                            ],
+            'config' => [
+                'type' => 'file',
+                'allowed' => 'common-image-types',
+                'behaviour' => [
+                    'allowLanguageSynchronization' => true,
+                ],
+                // Use the imageoverlayPalette instead of the basicoverlayPalette
+                'overrideChildTca' => [
+                    'types' => [
+                        '0' => [
+                            'showitem' => '
+                                --palette--;;imageoverlayPalette,
+                                --palette--;;filePalette',
                         ],
-                        'columns' => [
-                            'crop' => $openGraphCropConfiguration,
+                        \TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [
+                            'showitem' => '
+                                --palette--;;imageoverlayPalette,
+                                --palette--;;filePalette',
                         ],
                     ],
-                    'behaviour' => [
-                        'allowLanguageSynchronization' => true,
+                    'columns' => [
+                        'crop' => $openGraphCropConfiguration,
                     ],
                 ],
-                $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
-            ),
+            ],
         ],
         'twitter_title' => [
             'exclude' => true,
@@ -233,33 +231,31 @@ $tca = [
         'twitter_image' => [
             'exclude' => true,
             'label' => 'LLL:EXT:seo/Resources/Private/Language/locallang_tca.xlf:pages.twitter_image',
-            'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
-                'twitter_image',
-                [
-                    // Use the imageoverlayPalette instead of the basicoverlayPalette
-                    'overrideChildTca' => [
-                        'types' => [
-                            '0' => [
-                                'showitem' => '
-                                    --palette--;;imageoverlayPalette,
-                                    --palette--;;filePalette',
-                            ],
-                            \TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [
-                                'showitem' => '
-                                    --palette--;;imageoverlayPalette,
-                                    --palette--;;filePalette',
-                            ],
+            'config' => [
+                'type' => 'file',
+                'allowed' => 'common-image-types',
+                'behaviour' => [
+                    'allowLanguageSynchronization' => true,
+                ],
+                // Use the imageoverlayPalette instead of the basicoverlayPalette
+                'overrideChildTca' => [
+                    'types' => [
+                        '0' => [
+                            'showitem' => '
+                                --palette--;;imageoverlayPalette,
+                                --palette--;;filePalette',
                         ],
-                        'columns' => [
-                            'crop' => $openGraphCropConfiguration,
+                        \TYPO3\CMS\Core\Resource\File::FILETYPE_IMAGE => [
+                            'showitem' => '
+                                --palette--;;imageoverlayPalette,
+                                --palette--;;filePalette',
                         ],
                     ],
-                    'behaviour' => [
-                        'allowLanguageSynchronization' => true,
+                    'columns' => [
+                        'crop' => $openGraphCropConfiguration,
                     ],
                 ],
-                $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
-            ),
+            ],
         ],
         'twitter_card' => [
             'exclude' => true,
diff --git a/typo3/sysext/setup/Classes/Controller/SetupModuleController.php b/typo3/sysext/setup/Classes/Controller/SetupModuleController.php
index 9303aaa17c9f..4bd5950e870f 100644
--- a/typo3/sysext/setup/Classes/Controller/SetupModuleController.php
+++ b/typo3/sysext/setup/Classes/Controller/SetupModuleController.php
@@ -724,10 +724,6 @@ class SetupModuleController
                     'fieldname',
                     $queryBuilder->createNamedParameter('avatar', \PDO::PARAM_STR)
                 ),
-                $queryBuilder->expr()->eq(
-                    'table_local',
-                    $queryBuilder->createNamedParameter('sys_file', \PDO::PARAM_STR)
-                ),
                 $queryBuilder->expr()->eq(
                     'uid_foreign',
                     $queryBuilder->createNamedParameter($beUserId, \PDO::PARAM_INT)
@@ -771,10 +767,6 @@ class SetupModuleController
                     'fieldname',
                     $queryBuilder->createNamedParameter('avatar', \PDO::PARAM_STR)
                 ),
-                $queryBuilder->expr()->eq(
-                    'table_local',
-                    $queryBuilder->createNamedParameter('sys_file', \PDO::PARAM_STR)
-                ),
                 $queryBuilder->expr()->eq(
                     'uid_foreign',
                     $queryBuilder->createNamedParameter($beUserId, \PDO::PARAM_INT)
@@ -811,7 +803,6 @@ class SetupModuleController
                     'tablenames' => 'be_users',
                     'fieldname' => 'avatar',
                     'pid' => 0,
-                    'table_local' => 'sys_file',
                 ];
                 $storeRec['be_users'][(int)$beUserId]['avatar'] = 'NEW1234';
             }
diff --git a/typo3/sysext/setup/ext_tables.php b/typo3/sysext/setup/ext_tables.php
index 9255c607a136..94b7e8e0cbb8 100644
--- a/typo3/sysext/setup/ext_tables.php
+++ b/typo3/sysext/setup/ext_tables.php
@@ -43,7 +43,7 @@ $GLOBALS['TYPO3_USER_SETTINGS'] = [
             'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:be_users.avatar',
             'type' => 'avatar',
             'table' => 'be_users',
-            'allowed' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'],
+            'allowed' => 'common-image-types',
         ],
         'lang' => [
             'type' => 'language',
diff --git a/typo3/sysext/workspaces/Classes/Controller/Remote/RemoteServer.php b/typo3/sysext/workspaces/Classes/Controller/Remote/RemoteServer.php
index b86478466687..68e817f60c2f 100644
--- a/typo3/sysext/workspaces/Classes/Controller/Remote/RemoteServer.php
+++ b/typo3/sysext/workspaces/Classes/Controller/Remote/RemoteServer.php
@@ -150,11 +150,11 @@ class RemoteServer
             // check for exclude fields
             if ($this->getBackendUser()->isAdmin() || $GLOBALS['TCA'][$parameter->table]['columns'][$fieldName]['exclude'] == 0 || GeneralUtility::inList($this->getBackendUser()->groupData['non_exclude_fields'], $parameter->table . ':' . $fieldName)) {
                 // call diff class only if there is a difference
-                if ($configuration['type'] === 'inline' && $configuration['foreign_table'] === 'sys_file_reference') {
+                if ($configuration['type'] === 'file') {
                     $useThumbnails = false;
-                    if (!empty($configuration['overrideChildTca']['columns']['uid_local']['config']['appearance']['elementBrowserAllowed']) && !empty($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'])) {
+                    if (!empty($configuration['allowed']) && !empty($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'])) {
                         $fileExtensions = GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], true);
-                        $allowedExtensions = GeneralUtility::trimExplode(',', $configuration['overrideChildTca']['columns']['uid_local']['config']['appearance']['elementBrowserAllowed'], true);
+                        $allowedExtensions = GeneralUtility::trimExplode(',', $configuration['allowed'], true);
                         $differentExtensions = array_diff($allowedExtensions, $fileExtensions);
                         $useThumbnails = empty($differentExtensions);
                     }
diff --git a/typo3/sysext/workspaces/Classes/Dependency/ElementEntityProcessor.php b/typo3/sysext/workspaces/Classes/Dependency/ElementEntityProcessor.php
index 61c07aa2fb55..2bb08be718d1 100644
--- a/typo3/sysext/workspaces/Classes/Dependency/ElementEntityProcessor.php
+++ b/typo3/sysext/workspaces/Classes/Dependency/ElementEntityProcessor.php
@@ -99,7 +99,7 @@ class ElementEntityProcessor
             return ElementEntity::RESPONSE_Skip;
         }
         $fieldConfiguration = BackendUtility::getTcaFieldConfiguration($caller->getTable(), $callerArguments['field']);
-        $inlineFieldType = $this->getDataHandler()->getInlineFieldType($fieldConfiguration);
+        $inlineFieldType = $this->getDataHandler()->getRelationFieldType($fieldConfiguration);
         if (!$fieldConfiguration || ($fieldConfiguration['type'] !== 'flex' && $inlineFieldType !== 'field' && $inlineFieldType !== 'list')) {
             return ElementEntity::RESPONSE_Skip;
         }
@@ -118,7 +118,7 @@ class ElementEntityProcessor
     public function createNewDependentElementParentReferenceCallback(array $callerArguments, array $targetArgument, ElementEntity $caller, $eventName)
     {
         $fieldConfiguration = BackendUtility::getTcaFieldConfiguration($callerArguments['table'], $callerArguments['field']);
-        $inlineFieldType = $this->getDataHandler()->getInlineFieldType($fieldConfiguration);
+        $inlineFieldType = $this->getDataHandler()->getRelationFieldType($fieldConfiguration);
         if (!$fieldConfiguration || ($fieldConfiguration['type'] !== 'flex' && $inlineFieldType !== 'field' && $inlineFieldType !== 'list')) {
             return ElementEntity::RESPONSE_Skip;
         }
diff --git a/typo3/sysext/workspaces/Classes/Hook/DataHandlerHook.php b/typo3/sysext/workspaces/Classes/Hook/DataHandlerHook.php
index f44b78fb0b94..09bbfab1358d 100644
--- a/typo3/sysext/workspaces/Classes/Hook/DataHandlerHook.php
+++ b/typo3/sysext/workspaces/Classes/Hook/DataHandlerHook.php
@@ -431,36 +431,34 @@ class DataHandlerHook
      */
     protected function moveRecord_processFieldValue(DataHandler $dataHandler, $resolvedPageId, $table, $uid, $value, array $configuration): void
     {
-        $inlineFieldType = $dataHandler->getInlineFieldType($configuration);
-        $inlineProcessing = (
-            ($inlineFieldType === 'list' || $inlineFieldType === 'field')
-            && BackendUtility::isTableWorkspaceEnabled($configuration['foreign_table'])
-            && (!isset($configuration['behaviour']['disableMovingChildrenWithParent']) || !$configuration['behaviour']['disableMovingChildrenWithParent'])
-        );
+        if (($configuration['behaviour']['disableMovingChildrenWithParent'] ?? false)
+            || !in_array($dataHandler->getRelationFieldType($configuration), ['list', 'field'], true)
+            || !BackendUtility::isTableWorkspaceEnabled($configuration['foreign_table'])
+        ) {
+            return;
+        }
 
-        if ($inlineProcessing) {
-            if ($table === 'pages') {
-                // If the inline elements are related to a page record,
-                // make sure they reside at that page and not at its parent
-                $resolvedPageId = $uid;
-            }
+        if ($table === 'pages') {
+            // If the inline elements are related to a page record,
+            // make sure they reside at that page and not at its parent
+            $resolvedPageId = $uid;
+        }
 
-            $dbAnalysis = $this->createRelationHandlerInstance();
-            $dbAnalysis->start($value, $configuration['foreign_table'], '', $uid, $table, $configuration);
+        $dbAnalysis = $this->createRelationHandlerInstance();
+        $dbAnalysis->start($value, $configuration['foreign_table'], '', $uid, $table, $configuration);
 
-            // Moving records to a positive destination will insert each
-            // record at the beginning, thus the order is reversed here:
-            foreach ($dbAnalysis->itemArray as $item) {
-                $versionedRecord = BackendUtility::getWorkspaceVersionOfRecord($dataHandler->BE_USER->workspace, $item['table'], $item['id'], 'uid,t3ver_state');
-                if (empty($versionedRecord)) {
-                    continue;
-                }
-                $versionState = VersionState::cast($versionedRecord['t3ver_state']);
-                if ($versionState->indicatesPlaceholder()) {
-                    continue;
-                }
-                $dataHandler->moveRecord($item['table'], $item['id'], $resolvedPageId);
+        // Moving records to a positive destination will insert each
+        // record at the beginning, thus the order is reversed here:
+        foreach ($dbAnalysis->itemArray as $item) {
+            $versionedRecord = BackendUtility::getWorkspaceVersionOfRecord($dataHandler->BE_USER->workspace, $item['table'], $item['id'], 'uid,t3ver_state');
+            if (empty($versionedRecord)) {
+                continue;
+            }
+            $versionState = VersionState::cast($versionedRecord['t3ver_state']);
+            if ($versionState->indicatesPlaceholder()) {
+                continue;
             }
+            $dataHandler->moveRecord($item['table'], $item['id'], $resolvedPageId);
         }
     }
 
@@ -895,8 +893,7 @@ class DataHandlerHook
      */
     protected function version_swap_processFields($tableName, array $configuration, array $liveData, array $versionData, DataHandler $dataHandler)
     {
-        $inlineType = $dataHandler->getInlineFieldType($configuration);
-        if ($inlineType !== 'field') {
+        if ($dataHandler->getRelationFieldType($configuration) !== 'field') {
             return;
         }
         $foreignTable = $configuration['foreign_table'];
-- 
GitLab