diff --git a/src/main/java/de/ozgcloud/eingang/fim/FimMessageDataMapper.java b/src/main/java/de/ozgcloud/eingang/fim/FimMessageDataMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..b224761b12a780515069f34984102c135529ecfd
--- /dev/null
+++ b/src/main/java/de/ozgcloud/eingang/fim/FimMessageDataMapper.java
@@ -0,0 +1,54 @@
+package de.ozgcloud.eingang.fim;
+
+import java.util.List;
+
+import org.springframework.stereotype.Component;
+
+import de.ozgcloud.eingang.common.formdata.IncomingFile;
+import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
+import de.ozgcloud.eingang.xta.EingangRepresentationsAndAttachments;
+import de.ozgcloud.eingang.xta.XtaIncomingFilesMapper;
+import de.ozgcloud.xta.client.model.XtaFile;
+import de.ozgcloud.xta.client.model.XtaMessage;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.log4j.Log4j2;
+
+@Component
+@RequiredArgsConstructor
+@Log4j2
+public class FimMessageDataMapper {
+	private final XtaIncomingFilesMapper xtaIncomingFilesMapper;
+
+	static final String FIM_ATTACHMENT_GROUP_NAME = "sonstige";
+
+	public EingangRepresentationsAndAttachments mapEingangRepresentationsAndAttachments(XtaMessage message) {
+		return EingangRepresentationsAndAttachments.builder()
+				.primaryFormDataFileName(message.messageFile().name())
+				.primaryFormDataPdfFileName("")
+				.representations(getRepresentations(message))
+				.attachments(getAttachmentGroups(message))
+				.build();
+	}
+
+	List<IncomingFile> getRepresentations(XtaMessage message) {
+		return List.of(xtaIncomingFilesMapper.toIncomingFile(message.messageFile()));
+	}
+
+	List<IncomingFileGroup> getAttachmentGroups(XtaMessage msg) {
+		var attachments = getAttachments(msg.attachmentFiles());
+		return attachments.isEmpty()
+				? List.of()
+				: List.of(
+						IncomingFileGroup.builder()
+								.name(FIM_ATTACHMENT_GROUP_NAME)
+								.files(attachments)
+								.build()
+				);
+	}
+
+	private List<IncomingFile> getAttachments(List<XtaFile> attachmentFiles) {
+		return attachmentFiles.stream()
+				.map(xtaIncomingFilesMapper::toIncomingFile)
+				.toList();
+	}
+}
diff --git a/src/main/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapper.java b/src/main/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapper.java
index 1c4fb0545a16cb00f0ca4ad92df343494260bb78..819636c9a64d2e979d0444bc52bd7e2e3c058a96 100644
--- a/src/main/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapper.java
+++ b/src/main/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapper.java
@@ -35,6 +35,9 @@ import de.ozgcloud.eingang.common.errorhandling.TechnicalException;
 import de.ozgcloud.eingang.common.formdata.IncomingFile;
 import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
 import de.ozgcloud.eingang.xta.EingangRepresentationsAndAttachments;
+import de.ozgcloud.eingang.xta.XtaIncomingFilesMapper;
+import de.ozgcloud.eingang.xta.zip.ZipFileExtractor;
+import de.ozgcloud.xta.client.model.XtaMessage;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
 
@@ -46,8 +49,31 @@ public class XdomeaMessageDataMapper {
 	static final String ATTACHMENT_GROUP_NAME = "Dokument";
 
 	private final XdomeaXMLValueReader valueReader;
+	private final XtaIncomingFilesMapper xtaIncomingFilesMapper;
+	private final ZipFileExtractor zipFileExtractor;
+
+	public EingangRepresentationsAndAttachments extractEingangRepresentationsAndAttachments(XtaMessage message) {
+		var incomingZipFile = xtaIncomingFilesMapper.toIncomingFile(message.messageFile());
+		try {
+			return tryExtractEingangRepresentationsAndAttachments(incomingZipFile);
+		} catch (RuntimeException e) {
+			LOG.error("Error while extracting Xdomea ZIP file!", e);
+			return EingangRepresentationsAndAttachments.builder()
+					.primaryFormDataFileName("")
+					.primaryFormDataPdfFileName("")
+					.representations(List.of(incomingZipFile))
+					.attachments(List.of())
+					.build();
+		}
+	}
+
+	EingangRepresentationsAndAttachments tryExtractEingangRepresentationsAndAttachments(IncomingFile zipFile) {
+		return mapEingangRepresentationsAndAttachments(
+				zipFileExtractor.extractIncomingFilesSafely(zipFile)
+		);
+	}
 
-	public EingangRepresentationsAndAttachments mapEingangRepresentationsAndAttachments(List<IncomingFile> incomingFileList) {
+	EingangRepresentationsAndAttachments mapEingangRepresentationsAndAttachments(List<IncomingFile> incomingFileList) {
 		return removeUuidPrefixFromEingangFiles(
 				mapRawEingangRepresentationsAndAttachments(incomingFileList)
 		);
diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapper.java b/src/main/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapper.java
index 029bff7c01fc66a3ed0d633e2cda8feeb2727832..25e373eb289fce54ca817ce3e726a8fdea0ce0e9 100644
--- a/src/main/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapper.java
+++ b/src/main/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapper.java
@@ -24,44 +24,28 @@ package de.ozgcloud.eingang.xta;
 
 import java.io.File;
 import java.io.IOException;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Stream;
 
-import de.ozgcloud.common.binaryfile.TempFileUtils;
-import de.ozgcloud.eingang.common.errorhandling.TechnicalException;
 import jakarta.activation.DataHandler;
+
 import org.springframework.stereotype.Component;
 
+import de.ozgcloud.common.binaryfile.TempFileUtils;
+import de.ozgcloud.eingang.common.errorhandling.TechnicalException;
 import de.ozgcloud.eingang.common.formdata.IncomingFile;
-import de.ozgcloud.eingang.xta.zip.ZipFileExtractor;
 import de.ozgcloud.xta.client.model.XtaFile;
-
 import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
 
 @Log4j2
 @Component
 @RequiredArgsConstructor
-class XtaIncomingFilesMapper {
-
-	private final ZipFileExtractor zipFileExtractor;
+public class XtaIncomingFilesMapper {
 
-	public List<IncomingFile> toIncomingFiles(XtaFile messageFile) {
-		if (Objects.nonNull(messageFile)) {
-			return Stream.of(messageFile)
-					.map(this::toIncomingFile)
-					.flatMap(this::tryToExtractZip)
-					.toList();
-		}
-		return List.of();
-	}
-
-	IncomingFile toIncomingFile(XtaFile messageFile) {
-		File tmpFile = persistToFile(messageFile.content());
+	public IncomingFile toIncomingFile(XtaFile file) {
+		File tmpFile = persistToFile(file.content());
 		return IncomingFile.builder()
-				.name(messageFile.name())
-				.contentType(messageFile.contentType())
+				.name(file.name())
+				.contentType(file.contentType())
 				.file(tmpFile)
 				.size(tmpFile.length())
 				.build();
@@ -71,17 +55,7 @@ class XtaIncomingFilesMapper {
 		try (var inputStream = data.getInputStream()) {
 			return TempFileUtils.writeTmpFile(inputStream);
 		} catch (IOException e) {
-			throw new TechnicalException("Error writing Attachment to temp file", e);
-		}
-
-	}
-
-	Stream<IncomingFile> tryToExtractZip(IncomingFile incomingFile) {
-		try {
-			List<IncomingFile> extractedZips = zipFileExtractor.extractIncomingFilesSafely(incomingFile);
-			return extractedZips.stream();
-		} catch (RuntimeException e) {
-			return Stream.of(incomingFile);
+			throw new TechnicalException("Error writing xta file to temp file", e);
 		}
 	}
 }
diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java b/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java
index 82d53feff44124836433dd00f21cb23e400ceead..d3eb010b2d16a2c9667b1894cb52c64ce3af4882 100644
--- a/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java
+++ b/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java
@@ -28,15 +28,15 @@ import java.util.Optional;
 import org.mapstruct.Context;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
+import org.mapstruct.Named;
 
 import de.ozgcloud.eingang.common.formdata.FormData;
 import de.ozgcloud.eingang.common.formdata.FormHeader;
-import de.ozgcloud.eingang.common.formdata.FormMetaData;
 import de.ozgcloud.eingang.common.vorgang.VorgangNummerSupplier;
 import de.ozgcloud.eingang.semantik.enginebased.FilesMapperHelper;
 import de.ozgcloud.xta.client.model.XtaMessageMetaData;
 
-@Mapper(imports = { FilesMapperHelper.class, XtaMapperHelper.class })
+@Mapper(imports = { FilesMapperHelper.class })
 interface XtaMessageMapper {
 	int VORGANG_NUMMER_SUFFIX_LENGTH = 4;
 
@@ -46,14 +46,26 @@ interface XtaMessageMapper {
 	@Mapping(target = "zustaendigeStelle", ignore = true)
 	@Mapping(target = "zustaendigeStelles", ignore = true)
 	@Mapping(target = "header", source = "metaData")
-	@Mapping(target = "numberOfAttachments", expression = "java(FilesMapperHelper.countAttachedFiles(representationsAttachmentsPair.attachments()))")
-	@Mapping(target = "numberOfRepresentations", dependsOn = "representations", expression = "java(representationsAttachmentsPair.representations().size())")
+	@Mapping(target = "numberOfAttachments", expression = "java(FilesMapperHelper.countAttachedFiles(eingang.attachments()))")
+	@Mapping(target = "numberOfRepresentations", dependsOn = "representations", expression = "java(eingang.representations().size())")
 	@Mapping(target = "representation", ignore = true)
 	@Mapping(target = "attachment", ignore = true)
-	@Mapping(target = "control.metaData", source = "metaData")
-	FormData toFormData(EingangRepresentationsAndAttachments representationsAttachmentsPair, XtaMessageMetaData metaData,
+	@Mapping(target = "control", expression = "java( toFormDataControl(eingang, metaData) )")
+	FormData toFormData(EingangRepresentationsAndAttachments eingang, XtaMessageMetaData metaData,
 			@Context VorgangNummerSupplier vorgangNummerSupplier);
 
+	default FormData.FormDataControl toFormDataControl(EingangRepresentationsAndAttachments eingang, XtaMessageMetaData metaData) {
+		return FormData.FormDataControl.builder()
+				.metaData(Optional.of(formMetaDataFromMetaData(metaData)))
+				.representations(Optional.of(toEingangRepresentations(eingang)))
+				.build();
+	}
+
+	@Mapping(target = "primaryFormDataRepresentation", source = "primaryFormDataFileName")
+	@Mapping(target = "primaryFormDataPdfRepresentation", source = "primaryFormDataPdfFileName")
+	@Named("toEingangRepresentations")
+	FormData.Representations toEingangRepresentations(EingangRepresentationsAndAttachments eingang);
+
 	@Mapping(target = "formId", source = "messageTypeCode")
 	@Mapping(target = "requestId", source = "messageId")
 	@Mapping(target = "vorgangNummer", expression = "java(vorgangNummerSupplier.get(VORGANG_NUMMER_SUFFIX_LENGTH))")
@@ -79,8 +91,4 @@ interface XtaMessageMapper {
 		return XtaMessageId.from(id);
 	}
 
-	default Optional<FormMetaData> mapMetaData(XtaMessageMetaData value) {
-		return Optional.ofNullable(formMetaDataFromMetaData(value));
-	}
-
 }
diff --git a/src/main/java/de/ozgcloud/eingang/xta/XtaService.java b/src/main/java/de/ozgcloud/eingang/xta/XtaService.java
index 1898f89e539569c93f14507b846fbcf23c14f6c1..9a8843f58b86cc183244ab8684e5137c9d04b527 100644
--- a/src/main/java/de/ozgcloud/eingang/xta/XtaService.java
+++ b/src/main/java/de/ozgcloud/eingang/xta/XtaService.java
@@ -23,29 +23,22 @@
  */
 package de.ozgcloud.eingang.xta;
 
-import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 import java.util.function.Consumer;
 
-import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 
 import de.ozgcloud.eingang.common.errorhandling.TechnicalException;
 import de.ozgcloud.eingang.common.formdata.FormData;
-import de.ozgcloud.eingang.common.formdata.FormData.Representations;
-import de.ozgcloud.eingang.common.formdata.IncomingFile;
-import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
 import de.ozgcloud.eingang.common.vorgang.VorgangNummerSupplier;
+import de.ozgcloud.eingang.fim.FimMessageDataMapper;
 import de.ozgcloud.eingang.semantik.SemantikAdapter;
 import de.ozgcloud.eingang.xdomea.XdomeaMessageDataMapper;
 import de.ozgcloud.xta.client.XtaClient;
 import de.ozgcloud.xta.client.exception.XtaClientException;
-import de.ozgcloud.xta.client.model.XtaFile;
 import de.ozgcloud.xta.client.model.XtaMessage;
-import de.ozgcloud.xta.client.model.XtaMessageMetaData;
 import de.ozgcloud.xta.client.model.XtaMessageStatus;
 import de.ozgcloud.xta.client.model.XtaTransportReport;
 import lombok.NonNull;
@@ -69,7 +62,7 @@ class XtaService {
 	private final XtaMessageMapper mapper;
 	private final VorgangNummerSupplier vorgangNummerSupplier;
 	private final XdomeaMessageDataMapper xdomeaMessageDataMapper;
-	private final XtaIncomingFilesMapper xtaIncomingFilesMapper;
+	private final FimMessageDataMapper fimMessageDataMapper;
 
 	public void fetchMessages() throws XtaClientException {
 
@@ -86,7 +79,7 @@ class XtaService {
 		try {
 			return Optional.of(getFormData(xtaMessage));
 		} catch (RuntimeException exception) {
-			LOG.error("Failed to process xta message (id: %s)".formatted(xtaMessage.metaData().messageId()), exception);
+			LOG.error("Failed to process xta message with id: {}", xtaMessage.metaData().messageId(), exception);
 			return Optional.empty();
 		}
 	}
@@ -101,56 +94,25 @@ class XtaService {
 	}
 
 	FormData getFormData(XtaMessage xtaMessage) {
-		var metaData = xtaMessage.metaData();
-		var incomingFiles = xtaIncomingFilesMapper.toIncomingFiles(xtaMessage.messageFile());
-		var representationsAttachmentsPair = getRepresentationsAttachmentsPair(metaData, incomingFiles);
-
-		var formData = mapper.toFormData(representationsAttachmentsPair, metaData, vorgangNummerSupplier);
-		formData = addAttachments(xtaMessage, formData);
-
-		return addRepresentations(formData, xtaMessage.messageFile().name());
+		return mapper.toFormData(
+				getRepresentationsAndAttachments(xtaMessage),
+				xtaMessage.metaData(),
+				vorgangNummerSupplier
+		);
 	}
 
-	EingangRepresentationsAndAttachments getRepresentationsAttachmentsPair(XtaMessageMetaData metaData, List<IncomingFile> incomingFiles) {
+	EingangRepresentationsAndAttachments getRepresentationsAndAttachments(XtaMessage message) {
+		var metaData = message.metaData();
 		if (isXDomeaMessageType(metaData.messageTypeCode())) {
-			return xdomeaMessageDataMapper.mapEingangRepresentationsAndAttachments(incomingFiles);
+			return xdomeaMessageDataMapper.extractEingangRepresentationsAndAttachments(message);
 		}
 		if (isFimMessageType(metaData.messageTypeCode())) {
-			return mapIncomingFilesToRepresentations(incomingFiles);
+			return fimMessageDataMapper.mapEingangRepresentationsAndAttachments(message);
 		}
 
 		throw new TechnicalException("Unexpected XTA message type: %s".formatted(metaData.messageTypeCode()));
 	}
 
-	FormData addAttachments(XtaMessage msg, FormData inFormData) {
-		var attachments = buildAttachmentsInFiles(msg.attachmentFiles());
-		if (CollectionUtils.isNotEmpty(attachments)) {
-			return inFormData.toBuilder()
-					.attachment(IncomingFileGroup.builder().name("sonstige").files(attachments).build())
-					.numberOfAttachments(attachments.size())
-					.build();
-		}
-		return inFormData;
-	}
-
-	private List<IncomingFile> buildAttachmentsInFiles(Collection<XtaFile> attachmentFiles) {
-		return attachmentFiles.stream().map(xtaIncomingFilesMapper::toIncomingFile).toList();
-	}
-
-	FormData addRepresentations(FormData formData, String primaryFormDataMessage) {
-		return formData.toBuilder().control(
-						formData.getControl().toBuilder()
-								.representations(Optional.of(buildRepresentations(formData.getControl().getRepresentations(), primaryFormDataMessage)))
-								.build())
-				.build();
-	}
-
-	private Representations buildRepresentations(Optional<Representations> base, String primaryFormDataMessage) {
-		return base.map(Representations::toBuilder).orElseGet(Representations::builder)
-				.primaryFormDataRepresentation(primaryFormDataMessage)
-				.build();
-	}
-
 	private boolean isXDomeaMessageType(String messageType) {
 		return StringUtils.equals(messageType, XDOMEA_0201_MESSAGE_TYPE);
 	}
@@ -159,13 +121,6 @@ class XtaService {
 		return StringUtils.startsWith(messageType, FIM_MESSAGE_TYPE_PREFIX);
 	}
 
-	EingangRepresentationsAndAttachments mapIncomingFilesToRepresentations(List<IncomingFile> incomingFiles) {
-		return EingangRepresentationsAndAttachments.builder()
-				.representations(incomingFiles)
-				.attachments(Collections.emptyList())
-				.build();
-	}
-
 	void logTransportReports(List<XtaTransportReport> transportReports) {
 		for (var transportReport : transportReports) {
 			if (transportReport.status() == XtaMessageStatus.GREEN) {
diff --git a/src/test/java/de/ozgcloud/eingang/fim/FimMessageDataMapperTest.java b/src/test/java/de/ozgcloud/eingang/fim/FimMessageDataMapperTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e746ba6b9f709d01ce4ede61393ceb79b31dacdb
--- /dev/null
+++ b/src/test/java/de/ozgcloud/eingang/fim/FimMessageDataMapperTest.java
@@ -0,0 +1,200 @@
+package de.ozgcloud.eingang.fim;
+
+import static de.ozgcloud.eingang.fim.FimMessageDataMapper.*;
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import java.util.List;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+
+import de.ozgcloud.eingang.common.formdata.IncomingFile;
+import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
+import de.ozgcloud.eingang.xta.EingangRepresentationsAndAttachments;
+import de.ozgcloud.eingang.xta.XtaFileTestFactory;
+import de.ozgcloud.eingang.xta.XtaIncomingFilesMapper;
+import de.ozgcloud.eingang.xta.XtaMessageTestFactory;
+import de.ozgcloud.xta.client.model.XtaFile;
+import de.ozgcloud.xta.client.model.XtaMessage;
+
+class FimMessageDataMapperTest {
+
+	@Spy
+	@InjectMocks
+	private FimMessageDataMapper mapper;
+
+	@Mock
+	private XtaIncomingFilesMapper xtaIncomingFilesMapper;
+
+	private final String primaryFormDataFileName = "test-fim.xml";
+	private final String fimAttachmentFileName = "upload.pdf";
+	private final String fimAttachment2FileName = "upload.png";
+
+	private final XtaFile primaryFormDataFile = XtaFileTestFactory.createBuilder()
+			.name(primaryFormDataFileName)
+			.build();
+
+	private final XtaFile fimAttachment1 = XtaFileTestFactory.createBuilder()
+			.name(fimAttachmentFileName)
+			.build();
+
+	private final XtaFile fimAttachment2 = XtaFileTestFactory.createBuilder()
+			.name(fimAttachment2FileName)
+			.build();
+
+	private final XtaMessage message = XtaMessageTestFactory.createBuilder()
+			.messageFile(primaryFormDataFile)
+			.attachmentFiles(List.of(fimAttachment1, fimAttachment2))
+			.build();
+
+	@DisplayName("map EingangRepresentationsAndAttachments")
+	@Nested
+	class TestMapEingangRepresentationsAndAttachments {
+
+		@Mock
+		private IncomingFile representationIncomingFile;
+
+		@Mock
+		private IncomingFileGroup attachmentIncomingFileGroup;
+
+		@BeforeEach
+		void mock() {
+			doReturn(List.of(representationIncomingFile)).when(mapper).getRepresentations(any());
+			doReturn(List.of(attachmentIncomingFileGroup)).when(mapper).getAttachmentGroups(any());
+		}
+
+		@DisplayName("should map primaryFormDataFileName")
+		@Test
+		void shouldMapPrimaryFormDataFileName() {
+			var result = mapEingangRepresentationsAndAttachments();
+
+			assertThat(result.primaryFormDataFileName()).isEqualTo(primaryFormDataFileName);
+		}
+
+		@DisplayName("should map primaryFormDataPdfFileName")
+		@Test
+		void shouldMapPrimaryFormDataPdfFileName() {
+			var result = mapEingangRepresentationsAndAttachments();
+
+			assertThat(result.primaryFormDataPdfFileName()).isEmpty();
+		}
+
+		@DisplayName("should call getRepresentations")
+		@Test
+		void shouldCallGetRepresentations() {
+			mapEingangRepresentationsAndAttachments();
+
+			verify(mapper).getRepresentations(message);
+		}
+
+		@DisplayName("should map representations")
+		@Test
+		void shouldMapRepresentations() {
+			var result = mapEingangRepresentationsAndAttachments();
+
+			assertThat(result.representations()).containsExactly(representationIncomingFile);
+		}
+
+		@DisplayName("should call getAttachmentGroups")
+		@Test
+		void shouldCallGetAttachmentGroups() {
+			mapEingangRepresentationsAndAttachments();
+
+			verify(mapper).getAttachmentGroups(message);
+		}
+
+		@DisplayName("should map attachments")
+		@Test
+		void shouldMapAttachments() {
+			var result = mapEingangRepresentationsAndAttachments();
+
+			assertThat(result.attachments()).containsExactly(attachmentIncomingFileGroup);
+		}
+
+		private EingangRepresentationsAndAttachments mapEingangRepresentationsAndAttachments() {
+			return mapper.mapEingangRepresentationsAndAttachments(message);
+		}
+	}
+
+	@DisplayName("get attachment groups")
+	@Nested
+	class TestGetAttachmentGroups {
+		@Mock
+		private IncomingFile attachmentIncomingFile1;
+
+		@Mock
+		private IncomingFile attachmentIncomingFile2;
+
+		@BeforeEach
+		void mock() {
+			when(xtaIncomingFilesMapper.toIncomingFile(any()))
+					.thenReturn(attachmentIncomingFile1)
+					.thenReturn(attachmentIncomingFile2);
+
+		}
+
+		@DisplayName("should call toIncomingFile")
+		@Test
+		void shouldCallToIncomingFile() {
+			mapper.getAttachmentGroups(message);
+
+			verify(xtaIncomingFilesMapper).toIncomingFile(fimAttachment1);
+			verify(xtaIncomingFilesMapper).toIncomingFile(fimAttachment2);
+		}
+
+		@DisplayName("should return group with name")
+		@Test
+		void shouldReturnGroupWithName() {
+			var result = mapper.getAttachmentGroups(message);
+
+			assertThat(result)
+					.extracting(IncomingFileGroup::getName)
+					.containsExactly(FIM_ATTACHMENT_GROUP_NAME);
+		}
+
+		@DisplayName("should return group with files")
+		@Test
+		void shouldReturnGroupWithFiles() {
+			var result = mapper.getAttachmentGroups(message);
+
+			assertThat(result)
+					.flatExtracting(IncomingFileGroup::getFiles)
+					.containsExactly(attachmentIncomingFile1, attachmentIncomingFile2);
+		}
+	}
+
+	@DisplayName("get representations")
+	@Nested
+	class TestGetRepresentations {
+		@Mock
+		private IncomingFile representationIncomingFile;
+
+		@BeforeEach
+		void mock() {
+			when(xtaIncomingFilesMapper.toIncomingFile(any())).thenReturn(representationIncomingFile);
+		}
+
+		@DisplayName("should call toIncomingFile")
+		@Test
+		void shouldCallToIncomingFile() {
+			mapper.getRepresentations(message);
+
+			verify(xtaIncomingFilesMapper).toIncomingFile(primaryFormDataFile);
+		}
+
+		@DisplayName("should return")
+		@Test
+		void shouldReturn() {
+			var result = mapper.getRepresentations(message);
+
+			assertThat(result).containsExactly(representationIncomingFile);
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/src/test/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapperTest.java b/src/test/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapperTest.java
index a82bd209f46b9e00bc6312445ad8cb9cc6528441..d3ba9dbe2038ad1ba6dbb37e264198ab9c9417b5 100644
--- a/src/test/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapperTest.java
+++ b/src/test/java/de/ozgcloud/eingang/xdomea/XdomeaMessageDataMapperTest.java
@@ -46,16 +46,174 @@ import de.ozgcloud.eingang.common.errorhandling.TechnicalException;
 import de.ozgcloud.eingang.common.formdata.IncomingFile;
 import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
 import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory;
+import de.ozgcloud.eingang.xta.EingangRepresentationsAndAttachments;
+import de.ozgcloud.eingang.xta.XtaIncomingFilesMapper;
+import de.ozgcloud.eingang.xta.XtaMessageTestFactory;
+import de.ozgcloud.eingang.xta.zip.ZipFileExtractor;
+import de.ozgcloud.xta.client.model.XtaMessage;
 
 class XdomeaMessageDataMapperTest {
 
 	@Spy
 	@InjectMocks
-	private XdomeaMessageDataMapper fileClassifier;
+	private XdomeaMessageDataMapper mapper;
 
 	@Mock
 	private XdomeaXMLValueReader valueReader;
 
+	@Mock
+	private ZipFileExtractor zipFileExtractor;
+
+	@Mock
+	private XtaIncomingFilesMapper xtaIncomingFilesMapper;
+
+	@DisplayName("extract EingangRepresentationsAndAttachments")
+	@Nested
+	class TestExtractEingangRepresentationsAndAttachments {
+
+		private final XtaMessage message = XtaMessageTestFactory.create();
+
+		@Mock
+		private IncomingFile zipFile;
+
+		@Mock
+		private EingangRepresentationsAndAttachments eingang;
+
+		@BeforeEach
+		void mock() {
+			when(xtaIncomingFilesMapper.toIncomingFile(any())).thenReturn(zipFile);
+		}
+
+		@DisplayName("without exception")
+		@Nested
+		class TestWithoutException {
+			@BeforeEach
+			void mock() {
+				doReturn(eingang).when(mapper).tryExtractEingangRepresentationsAndAttachments(any());
+			}
+
+			@DisplayName("should call toIncomingFile")
+			@Test
+			void shouldCallToIncomingFile() {
+				extractEingangRepresentationsAndAttachments();
+
+				verify(xtaIncomingFilesMapper).toIncomingFile(message.messageFile());
+			}
+
+			@DisplayName("should call tryExtractEingangRepresentationsAndAttachments")
+			@Test
+			void shouldCallTryExtractEingangRepresentationsAndAttachments() {
+				extractEingangRepresentationsAndAttachments();
+
+				verify(mapper).tryExtractEingangRepresentationsAndAttachments(zipFile);
+			}
+
+			@DisplayName("should return")
+			@Test
+			void shouldReturn() {
+				var result = extractEingangRepresentationsAndAttachments();
+
+				assertThat(result).isEqualTo(eingang);
+			}
+		}
+
+		@DisplayName("with exception")
+		@Nested
+		class TestWithException {
+			@Mock
+			private RuntimeException exception;
+
+			@BeforeEach
+			void mock() {
+				doThrow(exception).when(mapper).tryExtractEingangRepresentationsAndAttachments(any());
+			}
+
+			@DisplayName("should map primaryFormDataFileName to empty")
+			@Test
+			void shouldMapPrimaryFormDataFileNameToEmpty() {
+				var result = extractEingangRepresentationsAndAttachments();
+
+				assertThat(result.primaryFormDataFileName()).isEmpty();
+			}
+
+			@DisplayName("should map primaryFormDataPdfFileName to empty")
+			@Test
+			void shouldMapPrimaryFormDataPdfFileNameToEmpty() {
+				var result = extractEingangRepresentationsAndAttachments();
+
+				assertThat(result.primaryFormDataPdfFileName()).isEmpty();
+			}
+
+			@DisplayName("should map representations")
+			@Test
+			void shouldMapRepresentations() {
+				var result = extractEingangRepresentationsAndAttachments();
+
+				assertThat(result.representations()).containsExactly(zipFile);
+			}
+
+			@DisplayName("should map attachments to empty")
+			@Test
+			void shouldMapAttachmentsToEmpty() {
+				var result = extractEingangRepresentationsAndAttachments();
+
+				assertThat(result.attachments()).isEmpty();
+			}
+		}
+
+		private EingangRepresentationsAndAttachments extractEingangRepresentationsAndAttachments() {
+			return mapper.extractEingangRepresentationsAndAttachments(message);
+		}
+	}
+
+	@DisplayName("try extract EingangRepresentationsAndAttachments")
+	@Nested
+	class TestTryExtractEingangRepresentationsAndAttachments {
+
+		@Mock
+		private IncomingFile zipFile;
+
+		@Mock
+		private IncomingFile xdomeaXmlFile;
+
+		@Mock
+		private EingangRepresentationsAndAttachments eingang;
+
+		@BeforeEach
+		void mock() {
+			when(zipFileExtractor.extractIncomingFilesSafely(any())).thenReturn(List.of(xdomeaXmlFile));
+			doReturn(eingang).when(mapper).mapEingangRepresentationsAndAttachments(any());
+		}
+
+		@DisplayName("should call extractIncomingFilesSafely")
+		@Test
+		void shouldCallExtractIncomingFilesSafely() {
+			tryExtractEingangRepresentationsAndAttachments();
+
+			verify(zipFileExtractor).extractIncomingFilesSafely(zipFile);
+		}
+
+		@DisplayName("should call mapEingangRepresentationsAndAttachments")
+		@Test
+		void shouldCallMapEingangRepresentationsAndAttachments() {
+			tryExtractEingangRepresentationsAndAttachments();
+
+			verify(mapper).mapEingangRepresentationsAndAttachments(List.of(xdomeaXmlFile));
+		}
+
+		@DisplayName("should return")
+		@Test
+		void shouldReturn() {
+			var result = tryExtractEingangRepresentationsAndAttachments();
+
+			assertThat(result).isEqualTo(eingang);
+		}
+
+		private EingangRepresentationsAndAttachments tryExtractEingangRepresentationsAndAttachments() {
+			return mapper.tryExtractEingangRepresentationsAndAttachments(zipFile);
+		}
+	}
+
 	@DisplayName("map EingangRepresentationsAndAttachments")
 	@Nested
 	class TestMapEingangRepresentationsAndAttachments {
@@ -69,7 +227,7 @@ class XdomeaMessageDataMapperTest {
 		void shouldMapRepresentations(boolean useUuidPrefix) {
 			mockXdomeaMessageData(useUuidPrefix);
 
-			var pair = fileClassifier.mapEingangRepresentationsAndAttachments(incomingFileList);
+			var pair = mapper.mapEingangRepresentationsAndAttachments(incomingFileList);
 
 			var representationFilenames = pair.representations().stream().map(IncomingFile::getName).toList();
 			assertThat(representationFilenames).containsExactly(XDOMEA_XML_NAME, REPR_XML_NAME, REPR_PDF_NAME);
@@ -81,7 +239,7 @@ class XdomeaMessageDataMapperTest {
 		void shouldMapAttachments(boolean useUuidPrefix) {
 			mockXdomeaMessageData(useUuidPrefix);
 
-			var pair = fileClassifier.mapEingangRepresentationsAndAttachments(incomingFileList);
+			var pair = mapper.mapEingangRepresentationsAndAttachments(incomingFileList);
 
 			var attachmentFilenames = pair.attachments().stream()
 					.map(IncomingFileGroup::getFiles)
@@ -97,7 +255,7 @@ class XdomeaMessageDataMapperTest {
 		void shouldMapPrimaryFormDataFileName(boolean useUuidPrefix) {
 			mockXdomeaMessageData(useUuidPrefix);
 
-			var pair = fileClassifier.mapEingangRepresentationsAndAttachments(incomingFileList);
+			var pair = mapper.mapEingangRepresentationsAndAttachments(incomingFileList);
 
 			assertThat(pair.primaryFormDataFileName()).isEqualTo(REPR_XML_NAME);
 		}
@@ -108,13 +266,13 @@ class XdomeaMessageDataMapperTest {
 		void shouldMapPrimaryFormPdfDataFileName(boolean useUuidPrefix) {
 			mockXdomeaMessageData(useUuidPrefix);
 
-			var pair = fileClassifier.mapEingangRepresentationsAndAttachments(incomingFileList);
+			var pair = mapper.mapEingangRepresentationsAndAttachments(incomingFileList);
 
 			assertThat(pair.primaryFormDataPdfFileName()).isEqualTo(REPR_PDF_NAME);
 		}
 
 		private void mockXdomeaMessageData(boolean useUuidPrefix) {
-			doReturn(XdomeaMessageDataTestFactory.create(useUuidPrefix)).when(fileClassifier).mapIncomingFilesToXdomeaMessageData(incomingFileList);
+			doReturn(XdomeaMessageDataTestFactory.create(useUuidPrefix)).when(mapper).mapIncomingFilesToXdomeaMessageData(incomingFileList);
 		}
 
 	}
@@ -131,7 +289,7 @@ class XdomeaMessageDataMapperTest {
 		void shouldThrowIfNotFound() {
 			var incomingFilesWithout = List.of(IncomingFileTestFactory.createBuilder().name(FILE_NAME_WITHOUT_SUFFIX).build());
 
-			assertThatThrownBy(() -> fileClassifier.findXdomeaXMLFile(incomingFilesWithout))
+			assertThatThrownBy(() -> mapper.findXdomeaXMLFile(incomingFilesWithout))
 					.isInstanceOf(TechnicalException.class);
 		}
 
@@ -144,7 +302,7 @@ class XdomeaMessageDataMapperTest {
 					targetIncomingFile
 			);
 
-			var primaryRepresentation = fileClassifier.findXdomeaXMLFile(incomingFilesWith);
+			var primaryRepresentation = mapper.findXdomeaXMLFile(incomingFilesWith);
 
 			assertThat(primaryRepresentation).isEqualTo(targetIncomingFile);
 		}
@@ -163,7 +321,7 @@ class XdomeaMessageDataMapperTest {
 		void shouldReturnEmptyIfNoXmlSuffix() {
 			var namesWithSuffix = List.of(PDF_FILE_NAME, PDF_FILE_NAME2);
 
-			var fileName = fileClassifier.findRepresentationFileNameBySuffix(namesWithSuffix, ".xml");
+			var fileName = mapper.findRepresentationFileNameBySuffix(namesWithSuffix, ".xml");
 
 			assertThat(fileName).isEmpty();
 		}
@@ -174,7 +332,7 @@ class XdomeaMessageDataMapperTest {
 			var namesWithSuffix = List.of(PDF_FILE_NAME, XML_FILE_NAME, PDF_FILE_NAME2,
 					XML_FILE_NAME2);
 
-			var fileName = fileClassifier.findRepresentationFileNameBySuffix(namesWithSuffix, ".xml");
+			var fileName = mapper.findRepresentationFileNameBySuffix(namesWithSuffix, ".xml");
 
 			assertThat(fileName).isEqualTo(XML_FILE_NAME);
 		}
@@ -184,7 +342,7 @@ class XdomeaMessageDataMapperTest {
 		void shouldReturnEmptyIfNoPdfSuffix() {
 			var namesWithoutSuffix = List.of(XML_FILE_NAME, XML_FILE_NAME2);
 
-			var fileName = fileClassifier.findRepresentationFileNameBySuffix(namesWithoutSuffix, ".pdf");
+			var fileName = mapper.findRepresentationFileNameBySuffix(namesWithoutSuffix, ".pdf");
 
 			assertThat(fileName).isEmpty();
 		}
@@ -194,7 +352,7 @@ class XdomeaMessageDataMapperTest {
 		void shouldReturnFirstWithPdfSuffix() {
 			var namesWithSuffix = List.of(PDF_FILE_NAME, XML_FILE_NAME, PDF_FILE_NAME2, XML_FILE_NAME2);
 
-			var fileName = fileClassifier.findRepresentationFileNameBySuffix(namesWithSuffix, ".pdf");
+			var fileName = mapper.findRepresentationFileNameBySuffix(namesWithSuffix, ".pdf");
 
 			assertThat(fileName).isEqualTo(PDF_FILE_NAME);
 		}
@@ -221,7 +379,7 @@ class XdomeaMessageDataMapperTest {
 					)
 					.map(name -> IncomingFileTestFactory.createBuilder().name(name).build())
 					.toList();
-			doReturn(xdomeaXMLFile).when(fileClassifier).findXdomeaXMLFile(incomingFileList);
+			doReturn(xdomeaXMLFile).when(mapper).findXdomeaXMLFile(incomingFileList);
 
 			when(xdomeaXMLFile.getName()).thenReturn(XDOMEA_XML_NAME);
 
@@ -275,7 +433,7 @@ class XdomeaMessageDataMapperTest {
 		}
 
 		private XdomeaMessageData doClassify() {
-			return fileClassifier.mapIncomingFilesToXdomeaMessageData(incomingFileList);
+			return mapper.mapIncomingFilesToXdomeaMessageData(incomingFileList);
 		}
 	}
 
diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaFileTestFactory.java b/src/test/java/de/ozgcloud/eingang/xta/XtaFileTestFactory.java
index b98ea399ed2d4a5a02719c2d80c16e8f7e0fba7d..7c37a307ca179fbf72d2ddb49741296777797448 100644
--- a/src/test/java/de/ozgcloud/eingang/xta/XtaFileTestFactory.java
+++ b/src/test/java/de/ozgcloud/eingang/xta/XtaFileTestFactory.java
@@ -31,22 +31,23 @@ import java.nio.charset.StandardCharsets;
 import jakarta.activation.DataHandler;
 import jakarta.activation.DataSource;
 import jakarta.activation.FileDataSource;
-import lombok.SneakyThrows;
+
 import org.apache.commons.io.FileUtils;
 
 import de.ozgcloud.xta.client.model.XtaFile;
+import lombok.SneakyThrows;
 
-class XtaFileTestFactory {
+public class XtaFileTestFactory {
 
-	static final String NAME = "Test_File";
-	static final String CONTENT = "slkafj3jifsdasx";
-	static final String ZIP_CONTENT_TYPE = "application/zip";
+	public static final String NAME = "Test_File";
+	public static final String CONTENT = "slkafj3jifsdasx";
+	public static final String ZIP_CONTENT_TYPE = "application/zip";
 
-	static XtaFile create() {
+	public static XtaFile create() {
 		return createBuilder().build();
 	}
 
-	static XtaFile.XtaFileBuilder createBuilder() {
+	public static XtaFile.XtaFileBuilder createBuilder() {
 		return XtaFile.builder()
 				.name(NAME)
 				.contentType(ZIP_CONTENT_TYPE)
diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapperTest.java b/src/test/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapperTest.java
index b2c837e73036e840146cfc5453591a9a5d24063a..ab25888db1d8ae8efa75421b2081e3668c7c1c21 100644
--- a/src/test/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapperTest.java
+++ b/src/test/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapperTest.java
@@ -23,53 +23,17 @@
 package de.ozgcloud.eingang.xta;
 
 import static org.assertj.core.api.Assertions.*;
-import static org.mockito.Mockito.*;
-
-import java.util.List;
-import java.util.stream.Stream;
 
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.mockito.InjectMocks;
-import org.mockito.Mock;
 import org.mockito.Spy;
 
-import de.ozgcloud.eingang.common.formdata.IncomingFile;
-import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory;
-import de.ozgcloud.eingang.xta.zip.ZipFileExtractor;
-
 class XtaIncomingFilesMapperTest {
 	@Spy
 	@InjectMocks
 	private XtaIncomingFilesMapper mapper;
 
-	@Mock
-	private ZipFileExtractor extractor;
-
-	@Nested
-	class TestToIncomingFiles {
-
-		@Test
-		void shouldMapToIncomingFiles() {
-			var xtaFile = XtaFileTestFactory.create();
-			var incomingFile = IncomingFileTestFactory.create();
-			when(mapper.toIncomingFile(xtaFile)).thenReturn(incomingFile);
-			when(mapper.tryToExtractZip(incomingFile)).thenAnswer(x -> Stream.of(incomingFile));
-
-			mapper.toIncomingFiles(xtaFile);
-
-			inOrder(mapper).verify(mapper, calls(1)).toIncomingFile(xtaFile);
-			inOrder(mapper).verify(mapper, calls(1)).tryToExtractZip(incomingFile);
-		}
-
-		@Test
-		void shouldHandleMissingMessageFile() {
-			var fileGroup = mapper.toIncomingFiles(null);
-
-			assertThat(fileGroup).isEmpty();
-		}
-	}
-
 	@Nested
 	class ToIncomingFile {
 		@Test
@@ -101,38 +65,4 @@ class XtaIncomingFilesMapperTest {
 		}
 	}
 
-	@Nested
-	class TestTryToExtractZip {
-
-		@Mock
-		IncomingFile outFile1;
-
-		@Mock
-		IncomingFile outFile2;
-
-		private final IncomingFile zipFile = IncomingFileTestFactory.createBuilder()
-				.name("attachments.zip")
-				.build();
-
-		@Test
-		void shouldExtractZipFiles() {
-			var expectedExtractedFiles = List.of(outFile1, outFile2);
-			when(extractor.extractIncomingFilesSafely(zipFile)).thenReturn(expectedExtractedFiles);
-
-			var extractedFiles = mapper.tryToExtractZip(zipFile).toList();
-
-			assertThat(extractedFiles).isEqualTo(expectedExtractedFiles);
-		}
-
-		@Test
-		void shouldIgnoreNonZipFiles() {
-			when(extractor.extractIncomingFilesSafely(zipFile)).thenThrow(new RuntimeException());
-			var incomingFile = IncomingFileTestFactory.create();
-
-			var extractedFiles = mapper.tryToExtractZip(incomingFile).toList();
-
-			assertThat(extractedFiles).containsExactly(incomingFile);
-		}
-	}
-
 }
diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMapperTest.java b/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMapperTest.java
index c20bccddb711109dec7bd81c4df3bebeafb18a3f..b079535d610027ed391c7625a73dde62f76f58b8 100644
--- a/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMapperTest.java
+++ b/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMapperTest.java
@@ -28,6 +28,7 @@ import static org.assertj.core.api.Assertions.*;
 import static org.mockito.Mockito.*;
 
 import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.mapstruct.factory.Mappers;
@@ -36,6 +37,7 @@ import org.mockito.Mock;
 import org.mockito.Spy;
 
 import de.ozgcloud.eingang.common.formdata.FormData;
+import de.ozgcloud.eingang.common.formdata.FormMetaData;
 import de.ozgcloud.eingang.common.formdata.FormMetaDataTestFactory;
 import de.ozgcloud.eingang.common.vorgang.VorgangNummerSupplier;
 import de.ozgcloud.xta.client.model.XtaMessageMetaData;
@@ -105,69 +107,93 @@ class XtaMessageMapperTest {
 		}
 
 		@Test
-		void shouldSetFormEngineName() {
+		void shouldSetDesinationId() {
 			var formData = doMapping();
 
-			assertThat(formData.getHeader().getFormEngineName()).isEqualTo(FormHeaderTestFactory.XDOMEA_FORM_ENGINE_NAME);
+			assertThat(formData.getControl().getMetaData()).isPresent().get()
+					.extracting(metaData -> metaData.getEntry(XtaFormMetaData.XTA_IDENTIFIER_ENTRY_NAME))
+					.isEqualTo(FormMetaDataTestFactory.XTA_IDENTIFIER);
 		}
 
+		@DisplayName("should map XtaFormMetaData service")
 		@Test
-		void shouldSetDesinationId() {
+		void shouldMapXtaFormMetaDataService() {
 			var formData = doMapping();
 
 			assertThat(formData.getControl().getMetaData()).isPresent().get()
-					.extracting(metaData -> metaData.getEntry(XtaFormMetaData.XTA_IDENTIFIER_ENTRY_NAME))
-					.isEqualTo(FormMetaDataTestFactory.XTA_IDENTIFIER);
+					.extracting(metaData -> metaData.getEntry(XtaFormMetaData.SERVICE_ENTRY_NAME))
+					.isEqualTo(xtaMessageMetaData.service());
 		}
 
-		private FormData doMapping() {
-			return mapper.toFormData(eingangRepresentationsAndAttachments, xtaMessageMetaData, vorgangNummerSupplier);
+		@DisplayName("should map XtaFormMetaData origin")
+		@Test
+		void shouldMapXtaFormMetaDataOrigin() {
+			var formData = doMapping();
+
+			assertThat(formData.getControl().getMetaData()).isPresent().get()
+					.extracting(FormMetaData::getOrigin)
+					.isEqualTo(xtaMessageMetaData.deliveryAttributesOrigin());
 		}
-	}
 
-	@Nested
-	class TestFormMetaDataFromMetaData {
-		private XtaMessageMetaData metaData;
+		@DisplayName("should map XtaFormMetaData delivery")
+		@Test
+		void shouldMapXtaFormMetaDataDelivery() {
+			var formData = doMapping();
 
-		@BeforeEach
-		void before() {
-			metaData = XtaMessageMetaDataTestFactory.create();
+			assertThat(formData.getControl().getMetaData()).isPresent().get()
+					.extracting(FormMetaData::getDelivery)
+					.isEqualTo(xtaMessageMetaData.deliveryAttributesDelivery());
 		}
 
+		@DisplayName("should map XtaFormMetaData messageId")
 		@Test
-		void shouldSetOrigin() {
-			var formMetaData = mapper.formMetaDataFromMetaData(metaData);
+		void shouldMapXtaFormMetaDataMessageId() {
+			var formData = doMapping();
 
-			assertThat(formMetaData.getOrigin()).isEqualTo(metaData.deliveryAttributesOrigin());
+			assertThat(formData.getControl().getMetaData()).isPresent().get()
+					.extracting(metaData -> metaData.getEntry(XtaFormMetaData.MESSAGE_ID_ENTRY_NAME))
+					.isEqualTo(xtaMessageMetaData.messageId());
 		}
 
+		@DisplayName("should map XtaFormMetaData messageType")
 		@Test
-		void shouldSetDelivery() {
-			var formMetaData = mapper.formMetaDataFromMetaData(metaData);
+		void shouldMapXtaFormMetaDataMessageType() {
+			var formData = doMapping();
 
-			assertThat(formMetaData.getDelivery()).isEqualTo(metaData.deliveryAttributesDelivery());
+			assertThat(formData.getControl().getMetaData()).isPresent().get()
+					.extracting(metaData -> metaData.getEntry(XtaFormMetaData.MESSAGE_TYPE_ENTRY_NAME))
+					.isEqualTo(xtaMessageMetaData.messageTypeCode());
 		}
-	}
 
-	@Nested
-	class TestToFimFormData {
+		@DisplayName("should map XtaFormMetaData xtaIdentifier")
+		@Test
+		void shouldMapXtaFormMetaDataXtaIdentifier() {
+			var formData = doMapping();
 
-		private XtaMessageMetaData xtaMessageMetaData;
-		private EingangRepresentationsAndAttachments eingangRepresentationsAndAttachments;
+			assertThat(formData.getControl().getMetaData()).isPresent().get()
+					.extracting(metaData -> metaData.getEntry(XtaFormMetaData.XTA_IDENTIFIER_ENTRY_NAME))
+					.isEqualTo(xtaMessageMetaData.readerIdentifier().value());
+		}
 
-		@BeforeEach
-		void mock() {
-			xtaMessageMetaData = XtaMessageMetaDataTestFactory.createFim();
-			eingangRepresentationsAndAttachments = EingangRepresentationsAndAttachmentsTestFactory.create();
-			when(vorgangNummerSupplier.get(VORGANG_NUMMER_SUFFIX_LENGTH)).thenReturn(FormHeaderTestFactory.VORGANGNUMMER);
+		@DisplayName("should map formEngineName")
+		@Test
+		void shouldMapFormEngineName() {
+			var formData = doMapping();
+
+			assertThat(formData.getHeader().getFormEngineName()).isEqualTo(FormHeaderTestFactory.XDOMEA_FORM_ENGINE_NAME);
 		}
 
+		@DisplayName("should map formEngineName for fim")
 		@Test
-		void shouldSetFormEngineName() {
-			var formData = mapper.toFormData(eingangRepresentationsAndAttachments, xtaMessageMetaData, vorgangNummerSupplier);
+		void shouldMapFormEngineNameForFim() {
+			var formData = mapper.toFormData(eingangRepresentationsAndAttachments, XtaMessageMetaDataTestFactory.createFim(), vorgangNummerSupplier);
 
 			assertThat(formData.getHeader().getFormEngineName()).isEqualTo(FormHeaderTestFactory.FIM_FORM_ENGINE_NAME);
 		}
 
+		private FormData doMapping() {
+			return mapper.toFormData(eingangRepresentationsAndAttachments, xtaMessageMetaData, vorgangNummerSupplier);
+		}
 	}
+
 }
diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaMessageTestFactory.java b/src/test/java/de/ozgcloud/eingang/xta/XtaMessageTestFactory.java
index 77712b7a2823da8a8a9fc2126f780370cba1d1cb..e38025031a958a041d342d7f08655e00c3103777 100644
--- a/src/test/java/de/ozgcloud/eingang/xta/XtaMessageTestFactory.java
+++ b/src/test/java/de/ozgcloud/eingang/xta/XtaMessageTestFactory.java
@@ -28,18 +28,18 @@ import java.util.List;
 import de.ozgcloud.xta.client.model.XtaFile;
 import de.ozgcloud.xta.client.model.XtaMessage;
 
-class XtaMessageTestFactory {
+public class XtaMessageTestFactory {
 
 	static final XtaMessageId MESSAGE_ID = XtaMessageId.from("urn:de:xta:messageid:dataport_xta_210:81e40808-91c6-4765-aaf4-1aa62fec8be9");
 
 	static final XtaFile attachment = XtaFileTestFactory.create();
 	static final String PRIMARY_FORM_DATA_MESSAGE = XtaFileTestFactory.NAME;
 
-	static XtaMessage create() {
+	public static XtaMessage create() {
 		return createBuilder().build();
 	}
 
-	static XtaMessage.XtaMessageBuilder createBuilder() {
+	public static XtaMessage.XtaMessageBuilder createBuilder() {
 		return XtaMessage.builder()
 				.metaData(XtaMessageMetaDataTestFactory.create())
 				.messageFile(XtaFileTestFactory.create())
diff --git a/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java b/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java
index 7959874bcc2db472b5224680b550a2427ef3a16b..1e94fa3ae298172f25c5298a665270063fd1a954 100644
--- a/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java
+++ b/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java
@@ -28,34 +28,28 @@ import static org.assertj.core.api.Assertions.*;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
-import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 
-import lombok.SneakyThrows;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Spy;
 
 import de.ozgcloud.eingang.common.errorhandling.TechnicalException;
 import de.ozgcloud.eingang.common.formdata.FormData;
-import de.ozgcloud.eingang.common.formdata.FormData.Representations;
-import de.ozgcloud.eingang.common.formdata.FormDataControlTestFactory;
-import de.ozgcloud.eingang.common.formdata.IncomingFile;
-import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory;
 import de.ozgcloud.eingang.common.vorgang.VorgangNummerSupplier;
+import de.ozgcloud.eingang.fim.FimMessageDataMapper;
 import de.ozgcloud.eingang.semantik.SemantikAdapter;
 import de.ozgcloud.eingang.xdomea.XdomeaMessageDataMapper;
 import de.ozgcloud.xta.client.XtaClient;
 import de.ozgcloud.xta.client.model.XtaMessage;
 import de.ozgcloud.xta.client.model.XtaMessageMetaData;
 import de.ozgcloud.xta.client.model.XtaTransportReport;
+import lombok.SneakyThrows;
 
 class XtaServiceTest {
 
@@ -73,10 +67,10 @@ class XtaServiceTest {
 	private SemantikAdapter semantikAdapter;
 
 	@Mock
-	private XtaIncomingFilesMapper incomingFilesMapper;
+	private XdomeaMessageDataMapper xdomeaMessageDataMapper;
 
 	@Mock
-	private XdomeaMessageDataMapper xdomeaMessageDataMapper;
+	private FimMessageDataMapper fimMessageDataMapper;
 
 	@Mock
 	private FormData formData;
@@ -199,187 +193,123 @@ class XtaServiceTest {
 		private final XtaMessage message = XtaMessageTestFactory.create();
 		private final XtaMessageMetaData messageMetaData = XtaMessageMetaDataTestFactory.create();
 		private final FormData mappedFormData = FormDataTestFactory.create();
-		private EingangRepresentationsAndAttachments classification;
-
-		@Captor
-		private ArgumentCaptor<XtaMessageMetaData> messageMetaDataCaptor;
-
-		@Captor
-		private ArgumentCaptor<EingangRepresentationsAndAttachments> classificationCaptor;
+		private final EingangRepresentationsAndAttachments eingang = EingangRepresentationsAndAttachmentsTestFactory.create();
 
 		@BeforeEach
-		void init() {
-			classification = EingangRepresentationsAndAttachmentsTestFactory.create();
-			var incomingFiles = List.of(IncomingFileTestFactory.create(), IncomingFileTestFactory.create());
-			when(incomingFilesMapper.toIncomingFiles(message.messageFile())).thenReturn(incomingFiles);
-			doReturn(classification).when(service).getRepresentationsAttachmentsPair(messageMetaData, incomingFiles);
-		}
-
-		@BeforeEach
-		void mockMessageMapping() {
+		void mock() {
+			doReturn(eingang).when(service).getRepresentationsAndAttachments(any());
 			when(mapper.toFormData(any(), any(), any())).thenReturn(mappedFormData);
 		}
 
+		@DisplayName("should call getRepresentationsAndAttachments")
 		@Test
-		void shouldCallMapper() {
+		void shouldCallGetRepresentationsAndAttachments() {
 			service.getFormData(message);
 
-			verify(mapper).toFormData(classification, messageMetaData, vorgangNummerSupplier);
+			verify(service).getRepresentationsAndAttachments(message);
 		}
 
+		@DisplayName("should call toFormData")
 		@Test
-		void shouldCallMapperToFormData() {
+		void shouldCallToFormData() {
 			service.getFormData(message);
 
-			verify(mapper).toFormData(classificationCaptor.capture(), messageMetaDataCaptor.capture(), eq(vorgangNummerSupplier));
-			assertThat(messageMetaDataCaptor.getValue()).isEqualTo(messageMetaData);
-			assertThat(classificationCaptor.getValue()).isEqualTo(classification);
+			verify(mapper).toFormData(eingang, messageMetaData, vorgangNummerSupplier);
 		}
 
+		@DisplayName("should return")
 		@Test
-		void shouldCallAddAttachments() {
-			service.getFormData(message);
-
-			verify(service).addAttachments(message, mappedFormData);
-		}
-
-		@Test
-		void shouldReturnMappedResult() {
-			doReturn(mappedFormData).when(service).addRepresentations(any(), any());
-
+		void shouldReturn() {
 			var result = service.getFormData(message);
 
 			assertThat(result).isEqualTo(mappedFormData);
 		}
 	}
 
-	@DisplayName("add attachments")
+	@DisplayName("get representations and attachments")
 	@Nested
-	class TestAddAttachments {
-
-		private final FormData inFormData = FormDataTestFactory.createBuilder().clearAttachments().numberOfAttachments(0).build();
+	class TestGetRepresentationsAndAttachments {
 
-		@Test
-		void shouldAddAttachments() {
-			var result = service.addAttachments(XtaMessageTestFactory.create(), inFormData);
+		@Mock
+		private EingangRepresentationsAndAttachments eingang;
 
-			assertThat(result.getAttachments()).hasSize(1);
-			assertThat(result.getNumberOfAttachments()).isEqualTo(1);
-		}
+		@DisplayName("with xdomea type")
+		@Nested
+		class TestWithXdomeaType {
 
-		@Test
-		void shouldWorkWithoutAnyAttachment() {
-			var result = service.addAttachments(XtaMessageTestFactory.createBuilder().attachmentFiles(Collections.emptyList()).build(), inFormData);
+			private final XtaMessage xdomeaMessage = XtaMessageTestFactory.createBuilder()
+					.metaData(XtaMessageMetaDataTestFactory.createBuilder()
+							.messageTypeCode(XtaService.XDOMEA_0201_MESSAGE_TYPE)
+							.build())
+					.build();
 
-			assertThat(result.getAttachments()).isEmpty();
-			assertThat(result.getNumberOfAttachments()).isZero();
-		}
-	}
+			@BeforeEach
+			void mock() {
+				when(xdomeaMessageDataMapper.extractEingangRepresentationsAndAttachments(any())).thenReturn(eingang);
+			}
 
-	@DisplayName("get representations attachments pair")
-	@Nested
-	class TestGetEingangRepresentationsAndAttachments {
-		@Mock
-		private XtaMessageMetaData messageMetaData;
+			@DisplayName("should call extractEingangRepresentationsAndAttachments")
+			@Test
+			void shouldCallExtractEingangRepresentationsAndAttachments() {
+				service.getRepresentationsAndAttachments(xdomeaMessage);
 
-		@Mock
-		private EingangRepresentationsAndAttachments classification;
+				verify(xdomeaMessageDataMapper).extractEingangRepresentationsAndAttachments(xdomeaMessage);
+			}
 
-		private List<IncomingFile> incomingFiles;
+			@DisplayName("should return")
+			@Test
+			void shouldReturn() {
+				var result = service.getRepresentationsAndAttachments(xdomeaMessage);
 
-		@BeforeEach
-		void mock() {
-			incomingFiles = List.of(IncomingFileTestFactory.create(), IncomingFileTestFactory.create());
+				assertThat(result).isEqualTo(eingang);
+			}
 		}
 
-		@DisplayName("should use correct mapper xdomea message type")
-		@Test
-		void shouldUseCorrectMapperXdomeaMessageType() {
-			when(messageMetaData.messageTypeCode()).thenReturn(XtaService.XDOMEA_0201_MESSAGE_TYPE);
-			when(xdomeaMessageDataMapper.mapEingangRepresentationsAndAttachments(incomingFiles))
-					.thenReturn(classification);
-
-			var result = service.getRepresentationsAttachmentsPair(messageMetaData, incomingFiles);
+		@DisplayName("with fim type")
+		@Nested
+		class TestWithFimType {
+			private final XtaMessage fimMessage = XtaMessageTestFactory.createBuilder()
+					.metaData(XtaMessageMetaDataTestFactory.createBuilder()
+							.messageTypeCode(FIM_MESSAGE_TYPE_PREFIX + "836487")
+							.build())
+					.build();
+
+			@BeforeEach
+			void mock() {
+				when(fimMessageDataMapper.mapEingangRepresentationsAndAttachments(any())).thenReturn(eingang);
+			}
 
-			assertThat(result).isEqualTo(classification);
-		}
+			@DisplayName("should call mapIncomingFilesToRepresentations")
+			@Test
+			void shouldCallMapIncomingFilesToRepresentations() {
+				service.getRepresentationsAndAttachments(fimMessage);
 
-		@DisplayName("should use correct mapping for FIM message")
-		@Test
-		void shouldUseCorrectMappingForFimMessage() {
-			when(messageMetaData.messageTypeCode()).thenReturn(FIM_MESSAGE_TYPE_PREFIX + "836487");
-			doReturn(classification).when(service).mapIncomingFilesToRepresentations(incomingFiles);
+				verify(fimMessageDataMapper).mapEingangRepresentationsAndAttachments(fimMessage);
+			}
 
-			var result = service.getRepresentationsAttachmentsPair(messageMetaData, incomingFiles);
+			@DisplayName("should return")
+			@Test
+			void shouldReturn() {
+				var result = service.getRepresentationsAndAttachments(fimMessage);
 
-			assertThat(result).isEqualTo(classification);
+				assertThat(result).isEqualTo(eingang);
+			}
 		}
 
 		@DisplayName("should throw exception for unexpected message type")
 		@Test
 		void shouldThrowExceptionForUnexpectedMessageType() {
-			when(messageMetaData.messageTypeCode()).thenReturn("unexpected");
+			var unexpectedMessage = XtaMessageTestFactory.createBuilder()
+					.metaData(XtaMessageMetaDataTestFactory.createBuilder()
+							.messageTypeCode("unexpected")
+							.build())
+					.build();
 
-			assertThatThrownBy(() -> service.getRepresentationsAttachmentsPair(messageMetaData, incomingFiles))
+			assertThatThrownBy(() -> service.getRepresentationsAndAttachments(unexpectedMessage))
 					.isInstanceOf(TechnicalException.class);
 		}
 	}
 
-	@DisplayName("map incoming files to representations")
-	@Nested
-	class TestMapIncomingFilesToRepresentations {
-
-		private List<IncomingFile> incomingFiles;
-
-		@BeforeEach
-		void mock() {
-			incomingFiles = List.of(IncomingFileTestFactory.create(), IncomingFileTestFactory.create());
-
-		}
-
-		@DisplayName("should return representations with incoming files")
-		@Test
-		void shouldReturnRepresentationsWithIncomingFiles() {
-			var result = service.mapIncomingFilesToRepresentations(incomingFiles);
-
-			assertThat(result.representations()).isEqualTo(incomingFiles);
-		}
-
-		@DisplayName("should return attachments with empty list")
-		@Test
-		void shouldReturnAttachmentsWithEmptyList() {
-			var result = service.mapIncomingFilesToRepresentations(incomingFiles);
-
-			assertThat(result.attachments()).isEmpty();
-		}
-	}
-
-	@DisplayName("add representations")
-	@Nested
-	class TestAddRepresentations {
-		@Test
-		void shouldAddPrimaryRepresentation() {
-			var result = service.addRepresentations(FormDataTestFactory.create(), XtaMessageTestFactory.PRIMARY_FORM_DATA_MESSAGE);
-
-			assertThat(result.getControl().getRepresentations()).isPresent().get()
-					.extracting(Representations::getPrimaryFormDataRepresentation).isEqualTo(XtaMessageTestFactory.PRIMARY_FORM_DATA_MESSAGE);
-		}
-
-		@Test
-		void shouldRespectExistingRepresentation() {
-			var formDataWithRepresentation = FormDataTestFactory.createBuilder().control(FormDataControlTestFactory.createBuilder()
-					.representations(Optional.of(
-							Representations.builder().primaryFormDataPdfRepresentation("PDF_FILE").build()))
-					.build()).build();
-
-			var result = service.addRepresentations(formDataWithRepresentation, XtaMessageTestFactory.PRIMARY_FORM_DATA_MESSAGE);
-
-			var baseAssert = assertThat(result.getControl().getRepresentations()).isPresent().get();
-			baseAssert.extracting(Representations::getPrimaryFormDataRepresentation).isEqualTo(XtaMessageTestFactory.PRIMARY_FORM_DATA_MESSAGE);
-			baseAssert.extracting(Representations::getPrimaryFormDataPdfRepresentation).isEqualTo("PDF_FILE");
-		}
-	}
-
 	@DisplayName("process semantik")
 	@Nested
 	class TestProcessSemantik {