diff --git a/common/pom.xml b/common/pom.xml
index 7bcf1e69a7d60e3ba3f330eb38d46ddb401ff291..8c856ccd354a3ad583f589207700677fc4358541 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -31,7 +31,7 @@
 	<parent>
 		<groupId>de.ozgcloud.eingang</groupId>
 		<artifactId>eingang-manager</artifactId>
-		<version>2.13.0-SNAPSHOT</version>
+		<version>2.15.0-SNAPSHOT</version>
 		<relativePath>../</relativePath>
 	</parent>
 	<artifactId>common</artifactId>
diff --git a/common/src/main/java/de/ozgcloud/eingang/EingangAspectPointcuts.java b/common/src/main/java/de/ozgcloud/eingang/EingangAspectPointcuts.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a4eafc31fba2d3e5913e47c6e41207412276d10
--- /dev/null
+++ b/common/src/main/java/de/ozgcloud/eingang/EingangAspectPointcuts.java
@@ -0,0 +1,26 @@
+package de.ozgcloud.eingang;
+
+import org.aspectj.lang.annotation.Pointcut;
+
+public class EingangAspectPointcuts {
+
+	@Pointcut("execution(public * *(..))")
+	void anyPublicMethods() {
+		// aspect pointcut - no implementation needed
+	}
+
+	@Pointcut("within(de.ozgcloud..*)")
+	void anythingInOzgCloud() {
+		// aspect pointcut - no implementation needed
+	}
+
+	@Pointcut("anyPublicMethods() && anythingInOzgCloud()")
+	void anyPublicMethodInOzgCloud() {
+		// aspect pointcut - no implementation needed
+	}
+
+	@Pointcut("anyPublicMethodInOzgCloud() && target(de.ozgcloud.eingang.semantik.enginebased.EngineBasedMapper)")
+	void publicMethodInEngineBasedMapper() {
+		// aspect pointcut - no implementation needed
+	}
+}
diff --git a/common/src/main/java/de/ozgcloud/eingang/EingangLoggingAspect.java b/common/src/main/java/de/ozgcloud/eingang/EingangLoggingAspect.java
new file mode 100644
index 0000000000000000000000000000000000000000..584acf3a329f1b2e79b62184c861b1b79f1e783c
--- /dev/null
+++ b/common/src/main/java/de/ozgcloud/eingang/EingangLoggingAspect.java
@@ -0,0 +1,25 @@
+package de.ozgcloud.eingang;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.springframework.stereotype.Component;
+
+import de.ozgcloud.common.logging.AspectLoggingUtils;
+
+@Aspect
+@Component
+public class EingangLoggingAspect extends EingangAspectPointcuts {
+
+	@Before("publicMethodInEngineBasedMapper()")
+	public void onEngineBasedMapper(JoinPoint joinPoint) {
+		AspectLoggingUtils.log(joinPoint);
+	}
+
+	@AfterReturning(pointcut = "publicMethodInEngineBasedMapper()", returning = "returnValue")
+	public void afterServiceMethod(JoinPoint joinPoint, Object returnValue) {
+		AspectLoggingUtils.logReturnValue(joinPoint, returnValue);
+	}
+
+}
diff --git a/common/src/main/java/de/ozgcloud/eingang/common/formdata/FormData.java b/common/src/main/java/de/ozgcloud/eingang/common/formdata/FormData.java
index 474be54dfd8c56eb60f5d9b2fb535742273f0fe8..26ff0c888125264f81d9d31ea6c8ba5ae8381384 100644
--- a/common/src/main/java/de/ozgcloud/eingang/common/formdata/FormData.java
+++ b/common/src/main/java/de/ozgcloud/eingang/common/formdata/FormData.java
@@ -48,7 +48,8 @@ public class FormData {
 	@Builder.Default
 	private FormHeader header = FormHeader.builder().build();
 
-	private ZustaendigeStelle zustaendigeStelle;
+	@Singular
+	private List<ZustaendigeStelle> zustaendigeStelles;
 	@ToString.Exclude
 	private Antragsteller antragsteller;
 	@ToString.Exclude
@@ -63,16 +64,21 @@ public class FormData {
 	@Singular
 	private List<IncomingFile> representations;
 
-	private FormDataControl control;
+	@Builder.Default
+	private FormDataControl control = FormDataControl.builder().build();
 
 	@Getter
-	@Builder
+	@Builder(toBuilder = true)
+	@ToString
 	public static class FormDataControl {
-		private Optional<Representations> representations;
+		@Builder.Default
+		private Optional<Representations> representations = Optional.empty();
+		@Builder.Default
+		private Optional<FormMetaData> metaData = Optional.empty();
 	}
 
 	@Getter
-	@Builder
+	@Builder(toBuilder = true)
 	public static class Representations {
 		private String primaryFormDataRepresentation;
 		private String primaryFormDataPdfRepresentation;
diff --git a/common/src/main/java/de/ozgcloud/eingang/common/formdata/FormMetaData.java b/common/src/main/java/de/ozgcloud/eingang/common/formdata/FormMetaData.java
new file mode 100644
index 0000000000000000000000000000000000000000..c84b8b634ee20fc695a27e194a6ed3bae0554621
--- /dev/null
+++ b/common/src/main/java/de/ozgcloud/eingang/common/formdata/FormMetaData.java
@@ -0,0 +1,19 @@
+package de.ozgcloud.eingang.common.formdata;
+
+import java.time.ZonedDateTime;
+
+public interface FormMetaData {
+
+	ZonedDateTime getOrigin();
+	ZonedDateTime getDelivery();
+
+	/**
+	 * Returns the value of the Entry, or null if this MetaData contains no Entry
+	 * for the name.
+	 * 
+	 * @param name Name of the requested Entry
+	 * @return Value of the Entry
+	 */
+	String getEntry(String name);
+
+}
diff --git a/common/src/test/java/de/ozgcloud/eingang/common/formdata/FormDataControlTestFactory.java b/common/src/test/java/de/ozgcloud/eingang/common/formdata/FormDataControlTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..e95c1e0fccf66519d23c26008a3a145bf562a2ff
--- /dev/null
+++ b/common/src/test/java/de/ozgcloud/eingang/common/formdata/FormDataControlTestFactory.java
@@ -0,0 +1,23 @@
+package de.ozgcloud.eingang.common.formdata;
+
+import java.util.Optional;
+
+import de.ozgcloud.eingang.common.formdata.FormData.FormDataControl;
+import de.ozgcloud.eingang.common.formdata.FormData.Representations;
+
+public class FormDataControlTestFactory {
+
+	public static String PRIMARY_FORM_DATA_REPRESENTATION = "Antrag.xml";
+
+	public static FormDataControl create() {
+		return createBuilder().build();
+	}
+
+	public static FormDataControl.FormDataControlBuilder createBuilder() {
+		return FormDataControl.builder()
+				.representations(Optional.of(Representations.builder()
+						.primaryFormDataRepresentation(PRIMARY_FORM_DATA_REPRESENTATION)
+						.build()))
+				.metaData(Optional.of(FormMetaDataTestFactory.create()));
+	}
+}
diff --git a/common/src/test/java/de/ozgcloud/eingang/common/formdata/FormDataTestFactory.java b/common/src/test/java/de/ozgcloud/eingang/common/formdata/FormDataTestFactory.java
index 05bdcffff581a6e8ce7e4f56fe5d86cb53054bb0..52dcddeaf62afa188e0716294bf84d615eb5c945 100644
--- a/common/src/test/java/de/ozgcloud/eingang/common/formdata/FormDataTestFactory.java
+++ b/common/src/test/java/de/ozgcloud/eingang/common/formdata/FormDataTestFactory.java
@@ -51,6 +51,8 @@ public class FormDataTestFactory {
 
 	public static final String ATTACHMENT_GROUP_2 = "FileGroup2";
 
+	public static final String VORGANG_ID = "vorgangId";
+
 	public static FormData create() {
 		return createBuilder().build();
 	}
@@ -60,6 +62,7 @@ public class FormDataTestFactory {
 				.header(FormHeaderTestFactory.create())
 				.antragsteller(AntragstellerTestFactory.create())
 				.zustaendigeStelle(ZustaendigeStelleTestFactory.create())
+				.control(FormDataControlTestFactory.create())
 				.formData(Map.of(
 						SIMPLE_VALUE_KEY, SIMPLE_VALUE,
 						SUBFORM_KEY, SUBFORM_VALUE,
diff --git a/common/src/test/java/de/ozgcloud/eingang/common/formdata/FormMetaDataTestFactory.java b/common/src/test/java/de/ozgcloud/eingang/common/formdata/FormMetaDataTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..987fef7dde61f9d310b1700c9b927119a6af6105
--- /dev/null
+++ b/common/src/test/java/de/ozgcloud/eingang/common/formdata/FormMetaDataTestFactory.java
@@ -0,0 +1,36 @@
+package de.ozgcloud.eingang.common.formdata;
+
+import java.time.ZonedDateTime;
+
+public class FormMetaDataTestFactory {
+
+	public static final String XTA_IDENTIFIER_ENTRY_NAME = "xtaIdentifier";
+
+	public static final String XTA_IDENTIFIER = "vbe:010550120100";
+	public static final String OE_ID = "010550120100";
+
+	public static FormMetaData create() {
+		return new FormMetaData() {
+
+			@Override
+			public ZonedDateTime getOrigin() {
+				return ZonedDateTime.now();
+			}
+
+			@Override
+			public ZonedDateTime getDelivery() {
+				return ZonedDateTime.now();
+			}
+
+			@Override
+			public String getEntry(String name) {
+				switch (name) {
+				case XTA_IDENTIFIER_ENTRY_NAME:
+					return XTA_IDENTIFIER;
+				}
+				return null;
+			}
+
+		};
+	}
+}
diff --git a/enterprise-adapter/pom.xml b/enterprise-adapter/pom.xml
index 2b493a100ac22855b3428759f89b1748c29dadce..00e281f9f923419d7cf6863b94ce5a3fd627c25b 100644
--- a/enterprise-adapter/pom.xml
+++ b/enterprise-adapter/pom.xml
@@ -4,7 +4,7 @@
 	<parent>
 		<groupId>de.ozgcloud.eingang</groupId>
 		<artifactId>eingang-manager</artifactId>
-		<version>2.13.0-SNAPSHOT</version>
+		<version>2.15.0-SNAPSHOT</version>
 	</parent>
 	<artifactId>enterprise-adapter</artifactId>
 	<name>EM - Enterprise Interface Adapter</name>
@@ -87,10 +87,9 @@
 						<executions>
 							<execution>
 								<id>build-image</id>
-								<phase>
-									install</phase>
+								<phase>install</phase>
 								<goals>
-									<goal>build-image</goal>
+									<goal>build-image-no-fork</goal>
 								</goals>
 							</execution>
 						</executions>
diff --git a/enterprise-adapter/src/test/java/de/ozgcloud/eingang/enterprise/entry/EnterpriseEntryITCase.java b/enterprise-adapter/src/test/java/de/ozgcloud/eingang/enterprise/entry/EnterpriseEntryITCase.java
index 86d4309910b98191d19bfc9a33b8b97fed0f33c9..edde8e256ad108a7458f4325b7444c4a585f776d 100644
--- a/enterprise-adapter/src/test/java/de/ozgcloud/eingang/enterprise/entry/EnterpriseEntryITCase.java
+++ b/enterprise-adapter/src/test/java/de/ozgcloud/eingang/enterprise/entry/EnterpriseEntryITCase.java
@@ -64,6 +64,7 @@ class EnterpriseEntryITCase {
 			assertThat(formData).isNotNull();
 		}
 
+		@Test
 		void shouldHaveNoOfRepresentations() {
 			var formData = doPostRequest();
 
diff --git a/fim-adapter/pom.xml b/fim-adapter/pom.xml
index e7dde98a9f4d4cb33a1b755810a51be5287675d5..ea5d7e81c9b3605dfa58ed04af46467360b80100 100644
--- a/fim-adapter/pom.xml
+++ b/fim-adapter/pom.xml
@@ -4,7 +4,7 @@
     <parent>
         <groupId>de.ozgcloud.eingang</groupId>
         <artifactId>eingang-manager</artifactId>
-        <version>2.13.0-SNAPSHOT</version>
+        <version>2.15.0-SNAPSHOT</version>
     </parent>
     <artifactId>fim-adapter</artifactId>
     <name>Eingangs Adapter - FIM</name>
diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/AntragstellerExtractor.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/AntragstellerExtractor.java
deleted file mode 100644
index 94a0b6821db48548ad8f82c65b06129e6262d0ab..0000000000000000000000000000000000000000
--- a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/AntragstellerExtractor.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package de.ozgcloud.eingang.fim;
-
-import de.ozgcloud.eingang.common.formdata.Antragsteller;
-import de.ozgcloud.eingang.common.formdata.FormData;
-
-import java.util.Map;
-
-public interface AntragstellerExtractor {
-
-    default void extractAntragsteller(final FormData.FormDataBuilder builder, final FormData initialFormData) {
-        final FormData current = builder.build();
-        final Map<String, Object> anzeigenErsteller = FimDataUtil.getSubmap(current.getFormData(), "G17002112");
-        final Map<String, Object> anschrift = FimDataUtil.getSubmap(anzeigenErsteller, "G60000086");
-
-        Antragsteller antragsteller = Antragsteller.builder()
-                .vorname(FimDataUtil.getValue(anzeigenErsteller, "F60000228").orElse(null))
-                .nachname(FimDataUtil.getValue(anzeigenErsteller, "F60000227").orElse(null))
-                .email(FimDataUtil.getValue(anzeigenErsteller, "F60000242").orElse(null))
-                .strasse(FimDataUtil.getValue(anschrift, "F60000243").orElse(null))
-                .hausnummer(FimDataUtil.getValue(anschrift, "F60000244").orElse(null))
-                .plz(FimDataUtil.getValue(anschrift, "F60000246").orElse(null))
-                .ort(FimDataUtil.getValue(anschrift, "F60000247").orElse(null))
-
-                .build();
-        builder.antragsteller(antragsteller);
-    }
-}
diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimBasedAdapter.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimBasedAdapter.java
index 5849cf8e8f9e1f9ad90bb87fa28ef75ed75d71cd..6a6a8ce22f230439482be03567c495388c3a8915 100644
--- a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimBasedAdapter.java
+++ b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimBasedAdapter.java
@@ -1,74 +1,96 @@
 package de.ozgcloud.eingang.fim;
 
-import de.ozgcloud.eingang.common.formdata.FormData;
-import de.ozgcloud.eingang.common.formdata.FormHeader;
-import de.ozgcloud.eingang.common.formdata.IncomingFile;
-import de.ozgcloud.eingang.semantik.enginebased.EngineBasedSemantikAdapter;
-import lombok.extern.log4j.Log4j2;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import java.io.IOException;
-import java.util.Optional;
+import de.ozgcloud.eingang.common.formdata.FormData;
+import de.ozgcloud.eingang.common.formdata.FormData.FormDataControl;
+import de.ozgcloud.eingang.common.formdata.FormData.Representations;
+import de.ozgcloud.eingang.common.formdata.IncomingFile;
+import de.ozgcloud.eingang.semantik.enginebased.EngineBasedSemantikAdapter;
+import lombok.NonNull;
+import lombok.extern.log4j.Log4j2;
 
 @Log4j2
 @Component
 public class FimBasedAdapter implements EngineBasedSemantikAdapter {
 
-    static final String FIM_FORM_ENGINE_NAME = "FIM";
-
-    @Autowired
-    private FimService fimService;
-
-    @Override
-    public boolean isResponsible(final FormData formData) {
-        final String formEngineName = formData.getHeader().getFormEngineName();
-        return FIM_FORM_ENGINE_NAME.equals(formEngineName);
-    }
-
-    @Override
-    public FormData parseFormData(final FormData initialFormData) {
-        LOG.info("FIM Mapper running to map formData");
-        final Optional<String> entryPointOpt = getEntryPoint(initialFormData.getHeader());
-        if (entryPointOpt.isEmpty()) {
-            LOG.error("No entry point found in metadata file for fim data mapping");
-            return initialFormData;
-        }
-        final Optional<IncomingFile> fileOpt = findFile(initialFormData, entryPointOpt.get());
-        if (fileOpt.isEmpty()) {
-            LOG.error("Entry point file not found for fim data mapping");
-            return initialFormData;
-        }
-        try {
-            final Document document = loadDocument(fileOpt.get());
-            return fimService.transformDocument(document, initialFormData);
-        } catch (ParserConfigurationException | SAXException | IOException | FimException e) {
-            LOG.error("Can't transform document into fim formdata");
-            return initialFormData;
-        }
-    }
-
-    private Optional<IncomingFile> findFile(final FormData formData, final String name) {
-        for (IncomingFile file : formData.getRepresentations()) {
-            if (file.getName().endsWith(name)) {
-                return Optional.of(file);
-            }
-        }
-        return Optional.empty();
-    }
-
-    private Optional<String> getEntryPoint(final FormHeader formHeader) {
-        // FIXME OZG-5778 sollte über formdata metadaten kommen statt aus dem meta file geparsed zu werden
-        return Optional.of("Antrag.xml");
-    }
-
-    private Document loadDocument(final IncomingFile incomingFile) throws ParserConfigurationException, IOException, SAXException {
-        final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
-        return builder.parse(incomingFile.getContentStream());
-    }
+	static final String FIM_FORM_ENGINE_NAME = "FIM";
+
+	static final String DEFAULT_FORMDATA_REPRESENTATION_NAME = "Antrag.xml";
+
+	@Autowired
+	private FimService fimService;
+
+	@Autowired(required = false)
+	private List<FimEngineBasedMapper> mappers = Collections.emptyList();
+
+	@Override
+	public boolean isResponsible(final FormData formData) {
+		final String formEngineName = formData.getHeader().getFormEngineName();
+		return FIM_FORM_ENGINE_NAME.equals(formEngineName);
+	}
+
+	@Override
+	public FormData parseFormData(final FormData initialFormData) {
+		var mapped = useMappers(initialFormData);
+		LOG.info("FIM Mapper running to map formData");
+
+		return findFile(initialFormData, getEntryPoint(initialFormData.getControl()))
+				.map(primaryRepresentation -> doParsing(mapped, primaryRepresentation))
+				.orElseGet(() -> {
+					LOG.error("Entry point file not found for fim data mapping");
+					return mapped;
+				});
+	}
+
+	private FormData useMappers(FormData inFormData) {
+		var processedFormData = inFormData;
+
+		for (var mapper : mappers) {
+			processedFormData = mapper.parseFormData(processedFormData);
+		}
+
+		return processedFormData;
+	}
+
+	private Optional<IncomingFile> findFile(final FormData formData, final String name) {
+		return formData.getRepresentations().stream()
+				.filter(file -> file.getName().endsWith(name))
+				.findFirst();
+	}
+
+	private FormData doParsing(@NonNull FormData formData, @NonNull IncomingFile formDataPrimaryRepresentation) {
+		try {
+			return fimService.transformDocument(loadDocument(formDataPrimaryRepresentation), formData);
+		} catch (ParserConfigurationException | SAXException | IOException | FimException e) {
+			LOG.error("Can't transform document into fim formdata.", e);
+			return formData;
+		}
+	}
+
+	String getEntryPoint(FormDataControl formDataControl) {
+		return formDataControl.getRepresentations().map(Representations::getPrimaryFormDataRepresentation)
+				.orElseGet(() -> {
+					LOG.error("No entry point found in metadata file for fim data mapping. Trying default.");
+					return DEFAULT_FORMDATA_REPRESENTATION_NAME;
+				});
+	}
+
+	private Document loadDocument(final IncomingFile incomingFile) throws ParserConfigurationException, IOException, SAXException {
+		final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+		return builder.parse(incomingFile.getContentStream());
+	}
+
 }
diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimDataMapper.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimDataMapper.java
index d7f0af4144888172fa1c9f6600efb7d95faf5b0c..84ea086db65f80050e41f253694a1c674f017285 100644
--- a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimDataMapper.java
+++ b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimDataMapper.java
@@ -1,9 +1,9 @@
 package de.ozgcloud.eingang.fim;
 
-import de.ozgcloud.eingang.common.formdata.FormData;
-import de.ozgcloud.eingang.common.formdata.IncomingFile;
-import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
-import lombok.extern.log4j.Log4j2;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Optional;
+
 import org.apache.commons.lang3.function.TriFunction;
 import org.springframework.stereotype.Service;
 import org.w3c.dom.Document;
@@ -12,7 +12,8 @@ import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.w3c.dom.Text;
 
-import java.util.*;
+import de.ozgcloud.eingang.common.formdata.FormData;
+import lombok.extern.log4j.Log4j2;
 
 @Service
 @Log4j2
diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimEngineBasedMapper.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimEngineBasedMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..f01ac99cc7eebb80f297041f7edba27bf91b2c23
--- /dev/null
+++ b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimEngineBasedMapper.java
@@ -0,0 +1,7 @@
+package de.ozgcloud.eingang.fim;
+
+import de.ozgcloud.eingang.semantik.enginebased.EngineBasedMapper;
+
+public interface FimEngineBasedMapper extends EngineBasedMapper {
+
+}
diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimSchemeAdapter.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimSchemeAdapter.java
index 943d50fe215ddc943476628a18926e726af7db2e..95e74004a0062effcd03e05c58bb2638d3f5ad40 100644
--- a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimSchemeAdapter.java
+++ b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimSchemeAdapter.java
@@ -1,14 +1,15 @@
 package de.ozgcloud.eingang.fim;
 
-import lombok.extern.log4j.Log4j2;
+import java.util.Map;
+import java.util.Optional;
+
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
-import java.util.Map;
-import java.util.Optional;
+import lombok.extern.log4j.Log4j2;
 
 @Log4j2
-public abstract class FimSchemeAdapter implements ZustaendigeStelleExtractor, AntragstellerExtractor, VorgangsnameExtractor {
+public abstract class FimSchemeAdapter {
 
     public abstract FimSchemeIdentifier forIdentifier();
 
diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimService.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimService.java
index 5f3160fa21540964c2c9e049c07d2117590abd1f..381cb4e04896e27ae780605187fc041ebdd943e0 100644
--- a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimService.java
+++ b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimService.java
@@ -1,107 +1,139 @@
 package de.ozgcloud.eingang.fim;
 
-import de.ozgcloud.eingang.common.formdata.FormData;
-import de.ozgcloud.eingang.common.formdata.FormHeader;
-import io.micrometer.common.util.StringUtils;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
 import jakarta.annotation.PostConstruct;
-import lombok.extern.log4j.Log4j2;
-import org.apache.logging.log4j.util.Strings;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.io.ResourceLoader;
 import org.springframework.stereotype.Service;
 import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
+import de.ozgcloud.eingang.common.formdata.Antragsteller;
+import de.ozgcloud.eingang.common.formdata.FormData;
+import de.ozgcloud.eingang.common.formdata.FormHeader;
+import io.micrometer.common.util.StringUtils;
+import lombok.extern.log4j.Log4j2;
 
 @Service
 @Log4j2
 public class FimService {
-    public static final String UNKNOWN_SCHEME_NAME = "unknown";
-
-    @Autowired
-    private FimProperties fimProperties;
-
-    @Autowired
-    private FimDataMapper fimDataMapper;
-
-    @Autowired
-    private ResourceLoader resourceLoader;
-
-    @Autowired
-    private final List<FimSchemeAdapter> fimSchemeAdapters = new ArrayList<>();
-
-    private final FimSchemeCatalogue fimSchemeCatalogue = new FimSchemeCatalogue();
-    private final FimSchemeAdapterCatalogue fimSchemeAdapterCatalogue = new FimSchemeAdapterCatalogue();
-
-    private static final FimSchemeAdapter DEFAULT_FIM_SCHEME_ADAPTER = new FimSchemeAdapter() {
-        @Override
-        public FimSchemeIdentifier forIdentifier() { return null; }
-    };
-
-    @PostConstruct
-    private void postConstruct() throws ParserConfigurationException, IOException, SAXException {
-        for (final FimSchemeAdapter fimSchemeAdapter : fimSchemeAdapters) {
-            fimSchemeAdapterCatalogue.put(fimSchemeAdapter.forIdentifier(), fimSchemeAdapter);
-        }
-        for (final String fimSchemaLocation : fimProperties.getSchemeLocations()) {
-            final FimScheme fimScheme = loadFimScheme(fimSchemaLocation.trim());
-            fimSchemeCatalogue.put(fimScheme.getIdentifier(), fimScheme);
-        }
-        final FimScheme unknownScheme = buildUnknownScheme();
-        fimSchemeCatalogue.put(unknownScheme.getIdentifier(), unknownScheme);
-    }
-
-    private FimScheme loadFimScheme(final String path) throws ParserConfigurationException, IOException, SAXException {
-        LOG.debug("Load FIM schema: " + path);
-        final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
-        final Document doc = builder.parse(resourceLoader.getResource("classpath:" + path).getFile());
-        final String targetNamespace = doc.getDocumentElement().getAttribute("targetNamespace");
-        final FimSchemeIdentifier fimSchemeIdentifier = FimSchemeIdentifier.fromString(targetNamespace);
-        final FimSchemeAdapter fimSchemeAdapter = fimSchemeAdapterCatalogue.getOrDefault(fimSchemeIdentifier, DEFAULT_FIM_SCHEME_ADAPTER);
-        return new FimScheme(doc, fimSchemeIdentifier, fimSchemeAdapter);
-    }
-
-    private FimScheme buildUnknownScheme() throws ParserConfigurationException {
-        final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
-        final FimSchemeIdentifier unknownFimSchemeIdentifier = FimSchemeIdentifier.fromString(UNKNOWN_SCHEME_NAME);
-        final FimSchemeAdapter fimSchemeAdapter = fimSchemeAdapterCatalogue.get(unknownFimSchemeIdentifier);
-        return new FimScheme(doc, unknownFimSchemeIdentifier, fimSchemeAdapter);
-    }
-
-    public FormData transformDocument(final Document document, final FormData initialFormData) {
-        final String[] tagParts = document.getDocumentElement().getTagName().split(":");
-        final String namespacePrefix = tagParts.length < 2 ? "" : (":" + tagParts[0]);
-        final String schemeName = document.getDocumentElement().getAttribute("xmlns" + namespacePrefix);
-        if (StringUtils.isEmpty(schemeName)) {
-            throw new FimException("XML Document does not provide a scheme");
-        }
-        final FimScheme scheme = getSchemeForIdentifier(schemeName);
-        final FormData.FormDataBuilder builder = fimDataMapper.apply(document, scheme, initialFormData);
-
-        final FimSchemeAdapter adapter = scheme.getSchemeAdapter();
-
-        adapter.extractVorgangsname(builder, initialFormData);
-        adapter.extractAntragsteller(builder, initialFormData);
-        adapter.extractZustaendigeStelle(builder, initialFormData);
-
-        return builder.build();
-    }
-
-     FimScheme getSchemeForIdentifier(final String fimSchemaName) {
-        final FimSchemeIdentifier fimSchemeIdentifier = FimSchemeIdentifier.fromString(fimSchemaName);
-        final FimScheme fimScheme = fimSchemeCatalogue.get(fimSchemeIdentifier);
-        if (fimScheme == null) {
-            LOG.error("Cannot find schema for: " + fimSchemaName);
-            return fimSchemeCatalogue.get(FimSchemeIdentifier.fromString(UNKNOWN_SCHEME_NAME));
-        }
-        return fimScheme;
-    }
-}
+	public static final String UNKNOWN_SCHEME_NAME = "unknown";
+
+	@Autowired
+	private FimProperties fimProperties;
+
+	@Autowired
+	private FimDataMapper fimDataMapper;
+
+	@Autowired
+	private ResourceLoader resourceLoader;
+
+	@Autowired
+	private final List<FimSchemeAdapter> fimSchemeAdapters = new ArrayList<>();
+
+	private final FimSchemeCatalogue fimSchemeCatalogue = new FimSchemeCatalogue();
+	private final FimSchemeAdapterCatalogue fimSchemeAdapterCatalogue = new FimSchemeAdapterCatalogue();
+
+	private static final FimSchemeAdapter DEFAULT_FIM_SCHEME_ADAPTER = new FimSchemeAdapter() {
+		@Override
+		public FimSchemeIdentifier forIdentifier() {
+			return null;
+		}
+	};
+
+	@PostConstruct
+	private void postConstruct() throws ParserConfigurationException, IOException, SAXException {
+		for (final FimSchemeAdapter fimSchemeAdapter : fimSchemeAdapters) {
+			fimSchemeAdapterCatalogue.put(fimSchemeAdapter.forIdentifier(), fimSchemeAdapter);
+		}
+		for (final String fimSchemaLocation : fimProperties.getSchemeLocations()) {
+			final FimScheme fimScheme = loadFimScheme(fimSchemaLocation.trim());
+			fimSchemeCatalogue.put(fimScheme.getIdentifier(), fimScheme);
+		}
+		final FimScheme unknownScheme = buildUnknownScheme();
+		fimSchemeCatalogue.put(unknownScheme.getIdentifier(), unknownScheme);
+	}
+
+	private FimScheme loadFimScheme(final String path) throws ParserConfigurationException, IOException, SAXException {
+		LOG.debug("Load FIM schema: " + path);
+		final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+		final Document doc = builder.parse(resourceLoader.getResource("classpath:" + path).getFile());
+		final String targetNamespace = doc.getDocumentElement().getAttribute("targetNamespace");
+		final FimSchemeIdentifier fimSchemeIdentifier = FimSchemeIdentifier.fromString(targetNamespace);
+		final FimSchemeAdapter fimSchemeAdapter = fimSchemeAdapterCatalogue.getOrDefault(fimSchemeIdentifier, DEFAULT_FIM_SCHEME_ADAPTER);
+		return new FimScheme(doc, fimSchemeIdentifier, fimSchemeAdapter);
+	}
+
+	private FimScheme buildUnknownScheme() throws ParserConfigurationException {
+		final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+		final FimSchemeIdentifier unknownFimSchemeIdentifier = FimSchemeIdentifier.fromString(UNKNOWN_SCHEME_NAME);
+		final FimSchemeAdapter fimSchemeAdapter = fimSchemeAdapterCatalogue.get(unknownFimSchemeIdentifier);
+		return new FimScheme(doc, unknownFimSchemeIdentifier, fimSchemeAdapter);
+	}
+
+	public FormData transformDocument(final Document document, final FormData initialFormData) {
+		final String[] tagParts = document.getDocumentElement().getTagName().split(":");
+		final String namespacePrefix = tagParts.length < 2 ? "" : (":" + tagParts[0]);
+		final String schemeName = document.getDocumentElement().getAttribute("xmlns" + namespacePrefix);
+		if (StringUtils.isEmpty(schemeName)) {
+			throw new FimException("XML Document does not provide a scheme");
+		}
+		final FimScheme scheme = getSchemeForIdentifier(schemeName);
+		final FormData.FormDataBuilder builder = fimDataMapper.apply(document, scheme, initialFormData);
+
+		builder.header(initialFormData.getHeader());
+
+		extractAntragsteller(builder, initialFormData);
+		extractVorgangsname(builder, initialFormData);
+
+		return builder.build();
+	}
+
+	FimScheme getSchemeForIdentifier(final String fimSchemaName) {
+		final FimSchemeIdentifier fimSchemeIdentifier = FimSchemeIdentifier.fromString(fimSchemaName);
+		final FimScheme fimScheme = fimSchemeCatalogue.get(fimSchemeIdentifier);
+		if (fimScheme == null) {
+			LOG.error("Cannot find schema for: " + fimSchemaName);
+			return fimSchemeCatalogue.get(FimSchemeIdentifier.fromString(UNKNOWN_SCHEME_NAME));
+		}
+		return fimScheme;
+	}
+
+	private void extractAntragsteller(final FormData.FormDataBuilder builder, final FormData initialFormData) {
+		final FormData current = builder.build();
+		final Map<String, Object> anzeigenErsteller = FimDataUtil.getSubmap(current.getFormData(), "G17002112");
+		final Map<String, Object> anschrift = FimDataUtil.getSubmap(anzeigenErsteller, "G60000086");
+
+		Antragsteller antragsteller = Antragsteller.builder()
+				.vorname(FimDataUtil.getValue(anzeigenErsteller, "F60000228").orElse(null))
+				.nachname(FimDataUtil.getValue(anzeigenErsteller, "F60000227").orElse(null))
+				.email(FimDataUtil.getValue(anzeigenErsteller, "F60000242").orElse(null))
+				.strasse(FimDataUtil.getValue(anschrift, "F60000243").orElse(null))
+				.hausnummer(FimDataUtil.getValue(anschrift, "F60000244").orElse(null))
+				.plz(FimDataUtil.getValue(anschrift, "F60000246").orElse(null))
+				.ort(FimDataUtil.getValue(anschrift, "F60000247").orElse(null))
+
+				.build();
+		builder.antragsteller(antragsteller);
+	}
+
+	private void extractVorgangsname(final FormData.FormDataBuilder builder, final FormData initialFormData) {
+		final FormData current = builder.build();
+		final Optional<String> vorgangsname = FimDataUtil.getValue(current.getFormData(), "G17003529", "G05001479", "G05001480", "F05002753");
+
+		final FormHeader.FormHeaderBuilder headerBuilder = current.getHeader().toBuilder();
+
+		headerBuilder.formName(vorgangsname.orElse(null));
+		builder.header(headerBuilder.build());
+	}
+}
\ No newline at end of file
diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/ZustaendigeStelleExtractor.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/ZustaendigeStelleExtractor.java
deleted file mode 100644
index a77d159562ec8bf49d40025ff7b9c96bfc722b6b..0000000000000000000000000000000000000000
--- a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/ZustaendigeStelleExtractor.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package de.ozgcloud.eingang.fim;
-
-import de.ozgcloud.eingang.common.formdata.FormData;
-
-public interface ZustaendigeStelleExtractor {
-    default void extractZustaendigeStelle (final FormData.FormDataBuilder builder, final FormData initialFormData) {}
-}
diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/ZustaendigeStelleMapper.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/ZustaendigeStelleMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..72146cb778999343ef393a5d78365c1801893a0d
--- /dev/null
+++ b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/ZustaendigeStelleMapper.java
@@ -0,0 +1,44 @@
+package de.ozgcloud.eingang.fim;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+import org.springframework.stereotype.Component;
+
+import de.ozgcloud.eingang.common.formdata.FormData;
+import de.ozgcloud.eingang.common.formdata.ZustaendigeStelle;
+import lombok.NonNull;
+
+@Component
+class ZustaendigeStelleMapper implements FimEngineBasedMapper {
+
+	static final String XTA_IDENTIFIER_ENTRY_NAME = "xtaIdentifier";
+
+	// TODO OZG-7086 umstellen auf FIM Headerdaten
+
+	@Override
+	public FormData parseFormData(FormData formData) {
+		return formData.getControl().getMetaData()
+				.map(metaData -> metaData.getEntry(XTA_IDENTIFIER_ENTRY_NAME))
+				.filter(Objects::nonNull)
+				.map(oeId -> setOrganisationsEinheitId(formData.getZustaendigeStelles(), oeId))
+				.map(zustStelle -> formData.toBuilder().zustaendigeStelle(zustStelle).build())
+				.orElse(formData);
+	}
+
+	private ZustaendigeStelle setOrganisationsEinheitId(List<ZustaendigeStelle> stelles, @NonNull String oeid) {
+		var builder = stelles.isEmpty() ? ZustaendigeStelle.builder() : stelles.getFirst().toBuilder();
+
+		extractOrganisationsEinheitId(oeid).ifPresent(builder::organisationseinheitenId);
+		return builder.build();
+	}
+
+	Optional<String> extractOrganisationsEinheitId(@NonNull String xtaIdentifier) {
+		var idx = xtaIdentifier.indexOf(":");
+		if (idx < 0) {
+			return Optional.empty();
+		}
+		return Optional.of(xtaIdentifier.substring(idx + 1));
+	}
+}
diff --git a/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimBasedAdapterTest.java b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimBasedAdapterTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..1a09b6a2ef3428543a3981d71f8aa8d38aaf5235
--- /dev/null
+++ b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimBasedAdapterTest.java
@@ -0,0 +1,46 @@
+package de.ozgcloud.eingang.fim;
+
+import static org.assertj.core.api.Assertions.*;
+
+import java.util.Optional;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+
+import de.ozgcloud.eingang.common.formdata.FormData.Representations;
+import de.ozgcloud.eingang.common.formdata.FormDataControlTestFactory;
+
+class FimBasedAdapterTest {
+
+	@InjectMocks
+	private FimBasedAdapter adapter;
+
+	@Nested
+	class TestGetEntryPoint {
+
+		@Test
+		void shouldReturnPrimaryRepresentation() {
+			var result = adapter.getEntryPoint(FormDataControlTestFactory.create());
+
+			assertThat(result).isEqualTo(FormDataControlTestFactory.PRIMARY_FORM_DATA_REPRESENTATION);
+		}
+
+		@Test
+		void shouldReturnDefaultOnMissingRepresentations() {
+			var result = adapter.getEntryPoint(FormDataControlTestFactory.createBuilder().representations(Optional.empty()).build());
+
+			assertThat(result).isEqualTo(FimBasedAdapter.DEFAULT_FORMDATA_REPRESENTATION_NAME);
+		}
+
+		@Test
+		void shouldReturnDefaultOnMissingPrimary() {
+			var control = FormDataControlTestFactory.createBuilder().representations(Optional.of(Representations.builder().build())).build();
+
+			var result = adapter.getEntryPoint(control);
+
+			assertThat(result).isEqualTo(FimBasedAdapter.DEFAULT_FORMDATA_REPRESENTATION_NAME);
+		}
+	}
+
+}
diff --git a/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimServiceITCase.java b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimServiceITCase.java
index 970e470d8fae2a989611b2f51545667827ca9d3d..38075e210282b91976041e1365b61603eadc2a3d 100644
--- a/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimServiceITCase.java
+++ b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimServiceITCase.java
@@ -1,241 +1,231 @@
 package de.ozgcloud.eingang.fim;
 
-import de.ozgcloud.common.test.ITCase;
-import de.ozgcloud.eingang.common.formdata.FormData;
-import de.ozgcloud.eingang.common.formdata.FormHeader;
-import de.ozgcloud.eingang.common.formdata.IncomingFile;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
-
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.ActiveProfiles;
-
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
 import java.io.File;
 import java.io.IOException;
 import java.util.List;
 import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
 import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
+import de.ozgcloud.common.test.ITCase;
+import de.ozgcloud.eingang.common.formdata.FormData;
+import de.ozgcloud.eingang.common.formdata.FormHeader;
+import de.ozgcloud.eingang.common.formdata.IncomingFile;
 
 @ITCase
 @ActiveProfiles({ "itcase", "test" })
 @ImportAutoConfiguration
-@SpringBootTest(classes= FimTestConfig.class)
+@SpringBootTest(classes = FimTestConfig.class)
 public class FimServiceITCase {
 
-    @Autowired
-    private FimService fimService;
-
-    @Autowired
-    private FimBasedAdapter fimBasedAdapter;
-
-    @Test
-    void shouldFailOnEmptyScheme() {
-        assertThatThrownBy(() -> {
-            final Document document = loadDocument("src/test/resources/test1.xml");
-            fimService.transformDocument(document, FormData.builder().build());
-        }).isInstanceOf(FimException.class).hasMessage("XML Document does not provide a scheme");
-    }
-
-    @Test
-    void shouldNoFindInvalidScheme() {
-        final FimScheme scheme = fimService.getSchemeForIdentifier("test");
-
-        assertThat(FimSchemeIdentifier.fromString("unknown")).isEqualTo(scheme.getIdentifier());
-    }
-
-    @Test
-    void shouldFindVersammlungsScheme() {
-        final FimScheme scheme = fimService.getSchemeForIdentifier("urn:xoev-de:xfall:standard:fim-s17000652_1.4");
-        assertThat(scheme).isNotNull();
-    }
-
-    @Test
-    void shouldFindTest2Scheme() {
-        final FimScheme scheme = fimService.getSchemeForIdentifier("test2");
-        assertThat(scheme).isNotNull();
-    }
-
-    @Test
-    void shouldTransformSimpleDocument() throws ParserConfigurationException, IOException, SAXException {
-        final Document document = loadDocument("src/test/resources/test2.xml");
-        final FormData formData = fimService.transformDocument(document, FormData.builder().build());
-
-        final Map<String, Object> expected = Map.of(
-                "fim.S1235", Map.of("label", "Testkey", "value", "Testvalue"),
-                "fim.S1236", Map.of("label", "fim.S1236", "value", "Testvalue 2")
-        );
-        assertThat(expected).isEqualTo(formData.getFormData());
-    }
-
-    @Test
-    void shouldTransformSimpleDocumentWithoutNamespace() throws ParserConfigurationException, IOException, SAXException {
-        final Document document = loadDocument("src/test/resources/test3.xml");
-        final FormData formData = fimService.transformDocument(document, FormData.builder().build());
-
-        final Map<String, Object> expected = Map.of(
-                "fim.S1235", Map.of("label", "Testkey", "value", "Testvalue"),
-                "fim.S1236", Map.of("label", "fim.S1236", "value", "Testvalue 2")
-        );
-        assertThat(expected).isEqualTo(formData.getFormData());
-    }
-
-    @Test
-    void shouldTransformDocument() throws ParserConfigurationException, IOException, SAXException {
-        final Document document = loadDocument("src/test/resources/S17000652V1.4_test01.xml");
-        FormData formData = fimService.transformDocument(document, FormData.builder().build());
-
-        assertThat(formData).isNotNull();
-
-        final Map<String, Object> expected = Map.of(
-                "G17003529", Map.of(
-                        "label","EfA|SH Standard",
-                        "value", Map.of(
-                                "G05001479", Map.of(
-                                        "label","nachrichtenkopf",
-                                        "value", Map.of(
-                                                "G05001480", Map.of(
-                                                        "label","identifikation.nachricht",
-                                                        "value", Map.of(
-                                                                "F05002750", Map.of("label", "nachrichtenUUID", "value", "d447e43a-5723-4821-a170-cb44d2dbf143"),
-                                                                "F05002751", Map.of("label", "erstellungszeitpunkt", "value", "2022-08-15T09:30:47"),
-                                                                "F05002752", Map.of("label", "nachrichtentyp", "value", "fim.S17000652.17000652001004"),
-                                                                "F05002753", Map.of("label", "dienstname", "value", "urn:fim:Versammlungsanzeige:1.4")
-                                                        )
-                                                ),
-                                                "G05001481", Map.of(
-                                                        "label","Leser",
-                                                        "value", Map.of(
-                                                                "F05002754", Map.of("label", "Organisationsname", "value", "Celle"),
-                                                                "F05002755", Map.of("label", "Organisationsschlüssel", "value", "vbe:010550120100"),
-                                                                "F05002756", Map.of("label", "Kategorie", "value", "Versammlungsbehörde")
-                                                        )
-                                                ),
-                                                "G05001482", Map.of(
-                                                        "label","Autor",
-                                                        "value", Map.of(
-                                                                "F05002754", Map.of("label", "Organisationsname", "value", "OSI-Onlinedienst Niedersachsen Versammlungsanzeige"),
-                                                                "F05002755", Map.of("label", "Organisationsschlüssel", "value", "vbe:010550120100"),
-                                                                "F05002756", Map.of("label", "Kategorie", "value", "Engagement- und Hobbyportal")
-                                                        )
-                                                )
-                                        )
-                                ),
-                                "F17005454", Map.of("label", "Datenschutzhinweis DSGVO", "value", "true"),
-                                "F17005455", Map.of("label", "Zustimmung zu einem digitalen Bescheid", "value", "true"),
-                                "F17005533", Map.of("label", "UUID", "value", "String")
-                        )
-                ),
-                "F17009191", Map.of("label", "Anzeige durch Person", "value", "true"),
-                "F17003371", Map.of("label", "Anzeigenart", "value", "String")
-        );
-
-        assertThat(expected).isEqualTo(formData.getFormData());
-    }
-
-    @Test
-    void shouldHaveNameInHeader() throws ParserConfigurationException, IOException, SAXException {
-        final Document document = loadDocument("src/test/resources/antrag.xml");
-        FormData formData = fimService.transformDocument(document, FormData.builder().build());
-
-        assertThat(formData).isNotNull();
-
-        assertThat(formData.getHeader().getFormName()).isEqualTo("urn:fim:Versammlungsanzeige:1.4");
-    }
-
-    @Test
-    void shouldHaveAntragsteller() throws ParserConfigurationException, IOException, SAXException {
-        final Document document = loadDocument("src/test/resources/antrag.xml");
-        FormData formData = fimService.transformDocument(document, FormData.builder().build());
-
-        assertThat(formData).isNotNull();
-
-        assertThat(formData.getAntragsteller()).isNotNull();
-    }
-
-    @Test
-    void shouldHaveAntragstellerAntragstellerData() throws ParserConfigurationException, IOException, SAXException {
-        final Document document = loadDocument("src/test/resources/antrag.xml");
-        FormData formData = fimService.transformDocument(document, FormData.builder().build());
-
-        assertThat(formData).isNotNull();
-
-        assertThat(formData.getAntragsteller().getVorname()).isEqualTo("Jörg");
-        assertThat(formData.getAntragsteller().getNachname()).isEqualTo("Bolay");
-        assertThat(formData.getAntragsteller().getStrasse()).isEqualTo("Muster");
-        assertThat(formData.getAntragsteller().getHausnummer()).isEqualTo("1");
-        assertThat(formData.getAntragsteller().getPlz()).isEqualTo("12345");
-        assertThat(formData.getAntragsteller().getOrt()).isEqualTo("Muster");
-    }
-
-    @Test
-    void shouldFallbackUnknownScheme() {
-        IncomingFile r1 = IncomingFile.builder().name("src/test/resources/test3/Antrag.xml").file(new File("src/test/resources/test3/Antrag.xml")).build();
-        IncomingFile r2 = IncomingFile.builder().name("src/test/resources/test3/fim_xtaMetadata.xml").build();
-        final FormData initialFormData = FormData.builder()
-                .header(FormHeader.builder().channel("XTA").formEngineName("FIM").build())
-                .representations(List.of(r1, r2)).build();
-
-        FormData formData = fimBasedAdapter.parseFormData(initialFormData);
-
-        assertThat(formData).isNotNull();
-
-        final Map<String, Object> expected = Map.of(
-                "G17003529", Map.of(
-                        "label","G17003529",
-                        "value", Map.of(
-                                "G05001479", Map.of(
-                                        "label","G05001479",
-                                        "value", Map.of(
-                                                "G05001480", Map.of(
-                                                        "label","G05001480",
-                                                        "value", Map.of(
-                                                                "F05002750", Map.of("label", "F05002750", "value", "d447e43a-5723-4821-a170-cb44d2dbf143"),
-                                                                "F05002751", Map.of("label", "F05002751", "value", "2022-08-15T09:30:47"),
-                                                                "F05002752", Map.of("label", "F05002752", "value", "fim.S17000652.17000652001004"),
-                                                                "F05002753", Map.of("label", "F05002753", "value", "urn:fim:Versammlungsanzeige:1.4")
-                                                        )
-                                                ),
-                                                "G05001481", Map.of(
-                                                        "label","G05001481",
-                                                        "value", Map.of(
-                                                                "F05002754", Map.of("label", "F05002754", "value", "Celle"),
-                                                                "F05002755", Map.of("label", "F05002755", "value", "vbe:010550120100"),
-                                                                "F05002756", Map.of("label", "F05002756", "value", "Versammlungsbehörde")
-                                                        )
-                                                ),
-                                                "G05001482", Map.of(
-                                                        "label","G05001482",
-                                                        "value", Map.of(
-                                                                "F05002754", Map.of("label", "F05002754", "value", "OSI-Onlinedienst Niedersachsen Versammlungsanzeige"),
-                                                                "F05002755", Map.of("label", "F05002755", "value", "vbe:010550120100"),
-                                                                "F05002756", Map.of("label", "F05002756", "value", "Engagement- und Hobbyportal")
-                                                        )
-                                                )
-                                        )
-                                ),
-                                "F17005454", Map.of("label", "F17005454", "value", "true"),
-                                "F17005455", Map.of("label", "F17005455", "value", "true"),
-                                "F17005533", Map.of("label", "F17005533", "value", "String")
-                        )
-                ),
-                "F17009191", Map.of("label", "F17009191", "value", "true"),
-                "F17003371", Map.of("label", "F17003371", "value", "String")
-        );
-
-        assertThat(expected).isEqualTo(formData.getFormData());
-    }
-
-    private Document loadDocument(final String path) throws ParserConfigurationException, IOException, SAXException {
-        final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
-        return builder.parse(new File(path));
-    }
+	@Autowired
+	private FimService fimService;
+
+	@Autowired
+	private FimBasedAdapter fimBasedAdapter;
+
+	@Test
+	void shouldFailOnEmptyScheme() {
+		assertThatThrownBy(() -> {
+			final Document document = loadDocument("src/test/resources/test1.xml");
+			fimService.transformDocument(document, FormData.builder().build());
+		}).isInstanceOf(FimException.class).hasMessage("XML Document does not provide a scheme");
+	}
+
+	@Test
+	void shouldNoFindInvalidScheme() {
+		final FimScheme scheme = fimService.getSchemeForIdentifier("test");
+
+		assertThat(FimSchemeIdentifier.fromString("unknown")).isEqualTo(scheme.getIdentifier());
+	}
+
+	@Test
+	void shouldFindVersammlungsScheme() {
+		final FimScheme scheme = fimService.getSchemeForIdentifier("urn:xoev-de:xfall:standard:fim-s17000652_1.4");
+		assertThat(scheme).isNotNull();
+	}
+
+	@Test
+	void shouldFindTest2Scheme() {
+		final FimScheme scheme = fimService.getSchemeForIdentifier("test2");
+		assertThat(scheme).isNotNull();
+	}
+
+	@Test
+	void shouldTransformSimpleDocument() throws ParserConfigurationException, IOException, SAXException {
+		final Document document = loadDocument("src/test/resources/test2.xml");
+		final FormData formData = fimService.transformDocument(document, FormData.builder().build());
+
+		final Map<String, Object> expected = Map.of(
+				"fim.S1235", Map.of("label", "Testkey", "value", "Testvalue"),
+				"fim.S1236", Map.of("label", "fim.S1236", "value", "Testvalue 2"));
+		assertThat(expected).isEqualTo(formData.getFormData());
+	}
+
+	@Test
+	void shouldTransformSimpleDocumentWithoutNamespace() throws ParserConfigurationException, IOException, SAXException {
+		final Document document = loadDocument("src/test/resources/test3.xml");
+		final FormData formData = fimService.transformDocument(document, FormData.builder().build());
+
+		final Map<String, Object> expected = Map.of(
+				"fim.S1235", Map.of("label", "Testkey", "value", "Testvalue"),
+				"fim.S1236", Map.of("label", "fim.S1236", "value", "Testvalue 2"));
+		assertThat(expected).isEqualTo(formData.getFormData());
+	}
+
+	@Test
+	void shouldTransformDocument() throws ParserConfigurationException, IOException, SAXException {
+		final Document document = loadDocument("src/test/resources/S17000652V1.4_test01.xml");
+		FormData formData = fimService.transformDocument(document, FormData.builder().build());
+
+		assertThat(formData).isNotNull();
+
+		final Map<String, Object> expected = Map.of(
+				"G17003529", Map.of(
+						"label", "EfA|SH Standard",
+						"value", Map.of(
+								"G05001479", Map.of(
+										"label", "nachrichtenkopf",
+										"value", Map.of(
+												"G05001480", Map.of(
+														"label", "identifikation.nachricht",
+														"value", Map.of(
+																"F05002750",
+																Map.of("label", "nachrichtenUUID", "value", "d447e43a-5723-4821-a170-cb44d2dbf143"),
+																"F05002751",
+																Map.of("label", "erstellungszeitpunkt", "value", "2022-08-15T09:30:47"),
+																"F05002752",
+																Map.of("label", "nachrichtentyp", "value", "fim.S17000652.17000652001004"),
+																"F05002753",
+																Map.of("label", "dienstname", "value", "urn:fim:Versammlungsanzeige:1.4"))),
+												"G05001481", Map.of(
+														"label", "Leser",
+														"value", Map.of(
+																"F05002754", Map.of("label", "Organisationsname", "value", "Celle"),
+																"F05002755",
+																Map.of("label", "Organisationsschlüssel", "value", "vbe:010550120100"),
+																"F05002756", Map.of("label", "Kategorie", "value", "Versammlungsbehörde"))),
+												"G05001482", Map.of(
+														"label", "Autor",
+														"value", Map.of(
+																"F05002754",
+																Map.of("label", "Organisationsname", "value",
+																		"OSI-Onlinedienst Niedersachsen Versammlungsanzeige"),
+																"F05002755",
+																Map.of("label", "Organisationsschlüssel", "value", "vbe:010550120100"),
+																"F05002756",
+																Map.of("label", "Kategorie", "value", "Engagement- und Hobbyportal"))))),
+								"F17005454", Map.of("label", "Datenschutzhinweis DSGVO", "value", "true"),
+								"F17005455", Map.of("label", "Zustimmung zu einem digitalen Bescheid", "value", "true"),
+								"F17005533", Map.of("label", "UUID", "value", "String"))),
+				"F17009191", Map.of("label", "Anzeige durch Person", "value", "true"),
+				"F17003371", Map.of("label", "Anzeigenart", "value", "String"));
+
+		assertThat(expected).isEqualTo(formData.getFormData());
+	}
+
+	@Test
+	void shouldHaveNameInHeader() throws ParserConfigurationException, IOException, SAXException {
+		final Document document = loadDocument("src/test/resources/antrag.xml");
+		FormData formData = fimService.transformDocument(document, FormData.builder().build());
+
+		assertThat(formData).isNotNull();
+
+		assertThat(formData.getHeader().getFormName()).isEqualTo("urn:fim:Versammlungsanzeige:1.4");
+	}
+
+	@Test
+	void shouldHaveAntragsteller() throws ParserConfigurationException, IOException, SAXException {
+		final Document document = loadDocument("src/test/resources/antrag.xml");
+		FormData formData = fimService.transformDocument(document, FormData.builder().build());
+
+		assertThat(formData).isNotNull();
+
+		assertThat(formData.getAntragsteller()).isNotNull();
+	}
+
+	@Test
+	void shouldHaveAntragstellerAntragstellerData() throws ParserConfigurationException, IOException, SAXException {
+		final Document document = loadDocument("src/test/resources/antrag.xml");
+		FormData formData = fimService.transformDocument(document, FormData.builder().build());
+
+		assertThat(formData).isNotNull();
+
+		assertThat(formData.getAntragsteller().getVorname()).isEqualTo("Jörg");
+		assertThat(formData.getAntragsteller().getNachname()).isEqualTo("Bolay");
+		assertThat(formData.getAntragsteller().getStrasse()).isEqualTo("Muster");
+		assertThat(formData.getAntragsteller().getHausnummer()).isEqualTo("1");
+		assertThat(formData.getAntragsteller().getPlz()).isEqualTo("12345");
+		assertThat(formData.getAntragsteller().getOrt()).isEqualTo("Muster");
+	}
+
+	@Test
+	void shouldFallbackUnknownScheme() {
+		IncomingFile r1 = IncomingFile.builder().name("src/test/resources/test3/Antrag.xml").file(new File("src/test/resources/test3/Antrag.xml"))
+				.build();
+		IncomingFile r2 = IncomingFile.builder().name("src/test/resources/test3/fim_xtaMetadata.xml").build();
+		final FormData initialFormData = FormData.builder()
+				.header(FormHeader.builder().channel("XTA").formEngineName("FIM").build())
+				.representations(List.of(r1, r2)).build();
+
+		FormData formData = fimBasedAdapter.parseFormData(initialFormData);
+
+		assertThat(formData).isNotNull();
+
+		final Map<String, Object> expected = Map.of(
+				"G17003529", Map.of(
+						"label", "G17003529",
+						"value", Map.of(
+								"G05001479", Map.of(
+										"label", "G05001479",
+										"value", Map.of(
+												"G05001480", Map.of(
+														"label", "G05001480",
+														"value", Map.of(
+																"F05002750",
+																Map.of("label", "F05002750", "value", "d447e43a-5723-4821-a170-cb44d2dbf143"),
+																"F05002751", Map.of("label", "F05002751", "value", "2022-08-15T09:30:47"),
+																"F05002752", Map.of("label", "F05002752", "value", "fim.S17000652.17000652001004"),
+																"F05002753",
+																Map.of("label", "F05002753", "value", "urn:fim:Versammlungsanzeige:1.4"))),
+												"G05001481", Map.of(
+														"label", "G05001481",
+														"value", Map.of(
+																"F05002754", Map.of("label", "F05002754", "value", "Celle"),
+																"F05002755", Map.of("label", "F05002755", "value", "vbe:010550120100"),
+																"F05002756", Map.of("label", "F05002756", "value", "Versammlungsbehörde"))),
+												"G05001482", Map.of(
+														"label", "G05001482",
+														"value", Map.of(
+																"F05002754",
+																Map.of("label", "F05002754", "value",
+																		"OSI-Onlinedienst Niedersachsen Versammlungsanzeige"),
+																"F05002755", Map.of("label", "F05002755", "value", "vbe:010550120100"),
+																"F05002756", Map.of("label", "F05002756", "value", "Engagement- und Hobbyportal"))))),
+								"F17005454", Map.of("label", "F17005454", "value", "true"),
+								"F17005455", Map.of("label", "F17005455", "value", "true"),
+								"F17005533", Map.of("label", "F17005533", "value", "String"))),
+				"F17009191", Map.of("label", "F17009191", "value", "true"),
+				"F17003371", Map.of("label", "F17003371", "value", "String"));
+
+		assertThat(expected).isEqualTo(formData.getFormData());
+	}
+
+	private Document loadDocument(final String path) throws ParserConfigurationException, IOException, SAXException {
+		final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+		return builder.parse(new File(path));
+	}
 }
diff --git a/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimTestConfig.java b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimTestConfig.java
index f0a28ec4b7be509a0de6663720ab2f2964546065..8e88e6f0ae161bffefca00daaef61bb3871a508a 100644
--- a/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimTestConfig.java
+++ b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimTestConfig.java
@@ -6,6 +6,6 @@ import org.springframework.context.annotation.Configuration;
 
 @Configuration
 @EnableAutoConfiguration
-@ComponentScan("de.ozgcloud.eingang.fim")
+@ComponentScan("de.ozgcloud.eingang")
 public class FimTestConfig {
 }
diff --git a/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/ZustaendigeStelleMapperTest.java b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/ZustaendigeStelleMapperTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..23fa26757fccee0f45863f256e9f34522ccae81c
--- /dev/null
+++ b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/ZustaendigeStelleMapperTest.java
@@ -0,0 +1,44 @@
+package de.ozgcloud.eingang.fim;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+
+import de.ozgcloud.eingang.common.formdata.FormDataTestFactory;
+import de.ozgcloud.eingang.common.formdata.FormMetaDataTestFactory;
+import de.ozgcloud.eingang.common.formdata.ZustaendigeStelle;
+
+class ZustaendigeStelleMapperTest {
+
+	@InjectMocks
+	private ZustaendigeStelleMapper mapper;
+
+	@Test
+	void shouldSetOrganisationsEinheitId() {
+		var parsed = mapper.parseFormData(FormDataTestFactory.createBuilder().clearZustaendigeStelles().build());
+
+		assertThat(parsed.getZustaendigeStelles()).hasSize(1).first().extracting(ZustaendigeStelle::getOrganisationseinheitenId)
+				.isEqualTo(FormMetaDataTestFactory.OE_ID);
+
+//		assertThat(parsed.getZustaendigeStelle().getOrganisationseinheitenId()).isEqualTo(FormMetaDataTestFactory.OE_ID);
+	}
+
+	@Test
+	void shouldWorkWithoutGivenZustaendigeStelle() {
+		var parsed = mapper.parseFormData(FormDataTestFactory.createBuilder().clearZustaendigeStelles().build());
+
+		assertThat(parsed.getZustaendigeStelles()).hasSize(1).first().extracting(ZustaendigeStelle::getOrganisationseinheitenId)
+				.isNotNull();
+
+//		assertThat(parsed.getZustaendigeStelle()).isNotNull();
+	}
+
+	@Test
+	void shouldIgnoreMalformedDestinationId() {
+		var oeid = mapper.extractOrganisationsEinheitId("quatsch");
+
+		assertThat(oeid).isEmpty();
+	}
+
+}
diff --git a/formcycle-adapter/formcycle-adapter-impl/pom.xml b/formcycle-adapter/formcycle-adapter-impl/pom.xml
index 4f85d9512aabbbe2a758a5893be9762303ff656e..3d5699205b4bcd63f2c78fe66dfbbda3fe5be060 100644
--- a/formcycle-adapter/formcycle-adapter-impl/pom.xml
+++ b/formcycle-adapter/formcycle-adapter-impl/pom.xml
@@ -29,7 +29,7 @@
 	<parent>
 		<groupId>de.ozgcloud.eingang</groupId>
 		<artifactId>formcycle-adapter</artifactId>
-		<version>2.13.0-SNAPSHOT</version>
+		<version>2.15.0-SNAPSHOT</version>
 		<relativePath>../</relativePath>
 	</parent>
 
@@ -123,7 +123,7 @@
 								<id>build-image</id>
 								<phase>install</phase>
 								<goals>
-									<goal>build-image</goal>
+									<goal>build-image-no-fork</goal>
 								</goals>
 							</execution>
 						</executions>
diff --git a/formcycle-adapter/formcycle-adapter-impl/src/main/java/de/ozgcloud/eingang/formcycle/FormCycleServiceKontoMapper.java b/formcycle-adapter/formcycle-adapter-impl/src/main/java/de/ozgcloud/eingang/formcycle/FormCycleServiceKontoMapper.java
index 3aceb97490468096ade62e9803525e90f0cf8a03..5185c70c92b3dff61db99fa0458be3019195a840 100644
--- a/formcycle-adapter/formcycle-adapter-impl/src/main/java/de/ozgcloud/eingang/formcycle/FormCycleServiceKontoMapper.java
+++ b/formcycle-adapter/formcycle-adapter-impl/src/main/java/de/ozgcloud/eingang/formcycle/FormCycleServiceKontoMapper.java
@@ -12,11 +12,13 @@ import org.mapstruct.ReportingPolicy;
 import de.ozgcloud.eingang.common.formdata.ServiceKonto;
 import de.ozgcloud.eingang.common.formdata.ServiceKonto.PostfachAddress;
 import de.ozgcloud.eingang.common.formdata.StringBasedIdentifier;
+import de.ozgcloud.eingang.semantik.common.ServiceKontoFactory;
 
 @Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED, unmappedTargetPolicy = ReportingPolicy.WARN)
 interface FormCycleServiceKontoMapper {
 
 	@Mapping(target = "postfachAddress", ignore = true)
+	@Mapping(target = "type", constant = ServiceKontoFactory.POSTFACH_TYPE_BAYERN_ID)
 	@Mapping(target = "postfachAddresses", expression = "java(fromGrpcPostfachAddresses(serviceKonto))")
 	ServiceKonto fromGrpc(FormCycleServiceKonto serviceKonto);
 
diff --git a/formcycle-adapter/formcycle-adapter-impl/src/test/java/de/ozgcloud/eingang/formcycle/FormCycleFormDataMapperTest.java b/formcycle-adapter/formcycle-adapter-impl/src/test/java/de/ozgcloud/eingang/formcycle/FormCycleFormDataMapperTest.java
index feb214cccd2dca6533c39109f6f85619be567304..077a22039a5d9da064404d03e2ec4c24b6584915 100644
--- a/formcycle-adapter/formcycle-adapter-impl/src/test/java/de/ozgcloud/eingang/formcycle/FormCycleFormDataMapperTest.java
+++ b/formcycle-adapter/formcycle-adapter-impl/src/test/java/de/ozgcloud/eingang/formcycle/FormCycleFormDataMapperTest.java
@@ -32,6 +32,7 @@ import org.mockito.InjectMocks;
 import org.mockito.Spy;
 
 import de.ozgcloud.eingang.common.formdata.FormHeaderTestFactory;
+import de.ozgcloud.eingang.common.formdata.ZustaendigeStelle;
 import de.ozgcloud.vorgang.common.grpc.GrpcFormDataMapper;
 
 class FormCycleFormDataMapperTest {
@@ -59,7 +60,9 @@ class FormCycleFormDataMapperTest {
 		void shouldMapZustaendigeStelle() {
 			var mapped = mapper.toFormData(FormCycleFormDataTestFactory.create());
 
-			assertThat(mapped.getZustaendigeStelle().getOrganisationseinheitenId()).isEqualTo(FormCycleFormHeaderTestFactory.ORGANISATIONSEINHEIT_ID);
+			assertThat(mapped.getZustaendigeStelles())
+					.extracting(ZustaendigeStelle::getOrganisationseinheitenId)
+					.containsExactly(FormCycleFormHeaderTestFactory.ORGANISATIONSEINHEIT_ID);
 		}
 	}
 
diff --git a/formcycle-adapter/formcycle-adapter-impl/src/test/java/de/ozgcloud/eingang/formcycle/FormCycleServiceKontoMapperTest.java b/formcycle-adapter/formcycle-adapter-impl/src/test/java/de/ozgcloud/eingang/formcycle/FormCycleServiceKontoMapperTest.java
index b328284eb6b3ab4fdf010dd4240d4726ebd13209..562bd419be832ff41a59fd1eb2215ed32961d2bd 100644
--- a/formcycle-adapter/formcycle-adapter-impl/src/test/java/de/ozgcloud/eingang/formcycle/FormCycleServiceKontoMapperTest.java
+++ b/formcycle-adapter/formcycle-adapter-impl/src/test/java/de/ozgcloud/eingang/formcycle/FormCycleServiceKontoMapperTest.java
@@ -11,6 +11,7 @@ import org.mapstruct.factory.Mappers;
 import de.ozgcloud.eingang.common.formdata.ServiceKonto.PostfachAddress;
 import de.ozgcloud.eingang.common.formdata.ServiceKontoTestFactory;
 import de.ozgcloud.eingang.common.formdata.StringBasedIdentifier;
+import de.ozgcloud.eingang.semantik.common.ServiceKontoFactory;
 
 class FormCycleServiceKontoMapperTest {
 
@@ -20,6 +21,13 @@ class FormCycleServiceKontoMapperTest {
 	@Nested
 	class TestFromGrpcServiceKonto {
 
+		@Test
+		void shouldMapType() {
+			var result = mapper.fromGrpc(FormCycleServiceKontoTestFactory.create());
+
+			assertThat(result.getType()).isEqualTo(ServiceKontoFactory.POSTFACH_TYPE_BAYERN_ID);
+		}
+
 		@DisplayName("trustLevel")
 		@Nested
 		class TestTrustLevel {
diff --git a/formcycle-adapter/formcycle-adapter-interface/pom.xml b/formcycle-adapter/formcycle-adapter-interface/pom.xml
index d396e859955e6fe0fc0bead6994fb69e852e668f..917fad48d21b8e902c5ae8ba18941556cf984731 100644
--- a/formcycle-adapter/formcycle-adapter-interface/pom.xml
+++ b/formcycle-adapter/formcycle-adapter-interface/pom.xml
@@ -36,7 +36,7 @@
 	<groupId>de.ozgcloud.eingang</groupId>
 	<artifactId>formcycle-adapter-interface</artifactId>
 	<name>EM - Formcycle Adapter - Interface</name>
-	<version>2.13.0-SNAPSHOT</version>
+	<version>2.15.0-SNAPSHOT</version>
 	
 	<properties>
 		<vorgang-manager.version>2.0.0</vorgang-manager.version>
diff --git a/formcycle-adapter/pom.xml b/formcycle-adapter/pom.xml
index 6c060d69a936ed7a12926cd27db9f4788e720fb4..82c4f6bf13ce8340f6d24dd10a32103ed3f5fbfc 100644
--- a/formcycle-adapter/pom.xml
+++ b/formcycle-adapter/pom.xml
@@ -29,7 +29,7 @@
 	<parent>
 		<groupId>de.ozgcloud.eingang</groupId>
 		<artifactId>eingang-manager</artifactId>
-		<version>2.13.0-SNAPSHOT</version>
+		<version>2.15.0-SNAPSHOT</version>
 	</parent>
 
 	<artifactId>formcycle-adapter</artifactId>
diff --git a/formsolutions-adapter/pom.xml b/formsolutions-adapter/pom.xml
index 325327a0b108097786653edf290990debcae1c97..61a100c3ea25a117167baf6a2d84014a30d9cac3 100644
--- a/formsolutions-adapter/pom.xml
+++ b/formsolutions-adapter/pom.xml
@@ -30,7 +30,7 @@
 	<parent>
 		<groupId>de.ozgcloud.eingang</groupId>
 		<artifactId>eingang-manager</artifactId>
-		<version>2.13.0-SNAPSHOT</version>
+		<version>2.15.0-SNAPSHOT</version>
 		<relativePath>../</relativePath>
 	</parent>
 
@@ -174,27 +174,14 @@
 				<groupId>pl.project13.maven</groupId>
 				<artifactId>git-commit-id-plugin</artifactId>
 			</plugin>
-
 			<plugin>
 				<groupId>org.springframework.boot</groupId>
 				<artifactId>spring-boot-maven-plugin</artifactId>
-				<configuration>
-					<image>
-						<!-- cann be removed when using common lib > 2.3.2-->
-						<builder>paketobuildpacks/builder-jammy-base</builder>
-						<env>
-							<BPE_DELIM_JAVA_TOOL_OPTIONS xml:space="preserve"> </BPE_DELIM_JAVA_TOOL_OPTIONS>
-							<BPE_APPEND_JAVA_TOOL_OPTIONS>-Dfile.encoding=UTF-8</BPE_APPEND_JAVA_TOOL_OPTIONS>
-						</env>
-					</image>
-				</configuration>
-			</plugin>
-
+            </plugin>
 			<plugin>
 				<groupId>org.jacoco</groupId>
 				<artifactId>jacoco-maven-plugin</artifactId>
 			</plugin>
-
 		</plugins>
 	</build>
 
@@ -211,7 +198,7 @@
 								<id>build-image</id>
 								<phase>install</phase>
 								<goals>
-									<goal>build-image</goal>
+									<goal>build-image-no-fork</goal>
 								</goals>
 							</execution>
 						</executions>
diff --git a/forwarder/pom.xml b/forwarder/pom.xml
index 39605a3df67fbdb757c543b6b89f4484b043dbb7..e0b5a6be46401028b29abd5a62ecf63cc59a8231 100644
--- a/forwarder/pom.xml
+++ b/forwarder/pom.xml
@@ -29,7 +29,7 @@
 	<parent>
 		<groupId>de.ozgcloud.eingang</groupId>
 		<artifactId>eingang-manager</artifactId>
-		<version>2.13.0-SNAPSHOT</version>
+		<version>2.15.0-SNAPSHOT</version>
 		<relativePath>../</relativePath>
 	</parent>
 
diff --git a/intelliform-adapter/pom.xml b/intelliform-adapter/pom.xml
index a3dfe80bb8058225d880fe2b0fb834ad91f00ab9..3d8c9820d3501241aa7d069deac51cd92bb3de93 100644
--- a/intelliform-adapter/pom.xml
+++ b/intelliform-adapter/pom.xml
@@ -31,7 +31,7 @@
 	<parent>
 		<groupId>de.ozgcloud.eingang</groupId>
 		<artifactId>eingang-manager</artifactId>
-		<version>2.13.0-SNAPSHOT</version>
+		<version>2.15.0-SNAPSHOT</version>
 		<relativePath>../</relativePath>
 	</parent>
 
@@ -244,7 +244,7 @@
 								<id>build-image</id>
 								<phase>install</phase>
 								<goals>
-									<goal>build-image</goal>
+									<goal>build-image-no-fork</goal>
 								</goals>
 							</execution>
 						</executions>
diff --git a/intelliform-adapter/src/test/java/de/ozgcloud/eingang/intelliform/FormDataEndpointITCase.java b/intelliform-adapter/src/test/java/de/ozgcloud/eingang/intelliform/FormDataEndpointITCase.java
index 54523201fd281dea6af56fdf32489b5e0ead3316..9860796131f316f3e145390f8c1b0de0f0d057b4 100644
--- a/intelliform-adapter/src/test/java/de/ozgcloud/eingang/intelliform/FormDataEndpointITCase.java
+++ b/intelliform-adapter/src/test/java/de/ozgcloud/eingang/intelliform/FormDataEndpointITCase.java
@@ -382,15 +382,6 @@ class FormDataEndpointITCase {
 				assertThat(file.getContent().size()).isZero();
 			}
 
-			@Test
-			void checkForAttachmentFileContentStream() {
-				sendRequest();
-
-				var fileStream = formDataCaptor.getValue().getAttachments().get(0).getFiles().get(0).getContentStream();
-
-				assertThat(fileStream).isNotNull();
-			}
-
 			@Test
 			void checkAttachmentGroup2Count() {
 				sendRequest();
@@ -437,14 +428,6 @@ class FormDataEndpointITCase {
 				assertThat(file.getContent().size()).isZero();
 			}
 
-			@Test
-			void checkForRepresentationFileContentStream() {
-				sendRequest();
-
-				var fileStream = formDataCaptor.getValue().getRepresentations().get(0).getContentStream();
-
-				assertThat(fileStream).isNotNull();
-			}
 		}
 
 		@DisplayName("service konto")
diff --git a/intelliform-adapter/src/test/java/de/ozgcloud/eingang/intelliform/FormDataEndpointTest.java b/intelliform-adapter/src/test/java/de/ozgcloud/eingang/intelliform/FormDataEndpointTest.java
index b58584e84b0ccf8362a448a506449d67bc7a23c2..caa77acc9a6d0b07d8d084c96ea7251df1341d96 100644
--- a/intelliform-adapter/src/test/java/de/ozgcloud/eingang/intelliform/FormDataEndpointTest.java
+++ b/intelliform-adapter/src/test/java/de/ozgcloud/eingang/intelliform/FormDataEndpointTest.java
@@ -64,15 +64,13 @@ class FormDataEndpointTest {
 	}
 
 	private Deposit buildRequest(String fileName) throws SAXException, IOException, ParserConfigurationException, URISyntaxException {
-
 		var depositData = new DepositData();
 
 		var attachment = new Attachment();
 		attachment.setName("XML-Daten.xml");
 		attachment.setContent(TestUtils.loadTextFile(fileName).getBytes());
 
-		depositData.getAttachments()
-				.add(attachment);
+		depositData.getAttachments().add(attachment);
 
 		var deposit = new Deposit();
 		deposit.setData(depositData);
diff --git a/pom.xml b/pom.xml
index e8c8ec64c40f1795975863be8bc7a4fe76ef4549..507bba28c75ff92d74e2dacf54de22bf169913ab 100644
--- a/pom.xml
+++ b/pom.xml
@@ -31,13 +31,13 @@
 	<parent>
 		<groupId>de.ozgcloud.common</groupId>
 		<artifactId>ozgcloud-common-parent</artifactId>
-		<version>4.3.1</version>
+		<version>4.7.0-SNAPSHOT</version>
 		<relativePath/> <!-- lookup parent from repository -->
 	</parent>
 
 	<groupId>de.ozgcloud.eingang</groupId>
 	<artifactId>eingang-manager</artifactId>
-	<version>2.13.0-SNAPSHOT</version>
+	<version>2.15.0-SNAPSHOT</version>
 	<packaging>pom</packaging>
 	<name>OZG-Cloud Eingang Manager</name>
 
diff --git a/router/pom.xml b/router/pom.xml
index 2ace78948a637913a36b0f781609cfaaca7843fb..92d6bf3f783ccc8dafc687ca6755e2891b980d5d 100644
--- a/router/pom.xml
+++ b/router/pom.xml
@@ -29,7 +29,7 @@
 	<parent>
 		<groupId>de.ozgcloud.eingang</groupId>
 		<artifactId>eingang-manager</artifactId>
-		<version>2.13.0-SNAPSHOT</version>
+		<version>2.15.0-SNAPSHOT</version>
 		<relativePath>../</relativePath>
 	</parent>
 
diff --git a/router/src/main/java/de/ozgcloud/eingang/router/GrpcEingangMapper.java b/router/src/main/java/de/ozgcloud/eingang/router/GrpcEingangMapper.java
index 74607f148396fb856dd86a4716f5f67f0d2f4019..c69b8397708151fa0c71aec866f6c2a5aeaceb4f 100644
--- a/router/src/main/java/de/ozgcloud/eingang/router/GrpcEingangMapper.java
+++ b/router/src/main/java/de/ozgcloud/eingang/router/GrpcEingangMapper.java
@@ -23,6 +23,7 @@
  */
 package de.ozgcloud.eingang.router;
 
+import java.util.Optional;
 import java.util.UUID;
 
 import org.mapstruct.CollectionMappingStrategy;
@@ -32,8 +33,6 @@ import org.mapstruct.NullValueCheckStrategy;
 import org.mapstruct.NullValuePropertyMappingStrategy;
 import org.mapstruct.ReportingPolicy;
 
-import com.google.protobuf.ByteString;
-
 import de.ozgcloud.eingang.common.formdata.Antragsteller;
 import de.ozgcloud.eingang.common.formdata.FormData;
 import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
@@ -52,17 +51,17 @@ import de.ozgcloud.vorgang.vorgang.GrpcZustaendigeStelle;
 		uses = { GrpcFormDataMapper.class, ServiceKontoMapper.class })
 public interface GrpcEingangMapper {
 
-	@Mapping(source = "antragsteller.data", target = "antragsteller.otherData")
-	@Mapping(source = "attachments", target = "attachmentsList")
-	@Mapping(source = "representations", target = "representationsList")
-	GrpcEingang toEingang(FormData formData);
-
-	default ByteString byteArrayToByteString(byte[] byteArray) {
-		if (byteArray == null) {
-			return null;
-		}
+	@Mapping(target = "antragsteller.otherData", source = "formData.antragsteller.data")
+	@Mapping(target = "attachmentsList", source = "formData.attachments")
+	@Mapping(target = "representationsList", source = "formData.representations")
+	@Mapping(target = "zustaendigeStelle", expression = "java( toZustaendigeStelle(getZustaendigeStelle(formData, organisationsEinheitenId)) )")
+	GrpcEingang toEingang(FormData formData, Optional<String> organisationsEinheitenId);
 
-		return ByteString.copyFrom(byteArray);
+	default ZustaendigeStelle getZustaendigeStelle(FormData formData, Optional<String> organisationsEinheitenId) {
+		return organisationsEinheitenId.flatMap(oeId -> formData.getZustaendigeStelles().stream()
+						.filter(zustaendigeStelle -> zustaendigeStelle.getOrganisationseinheitenId().equals(oeId))
+						.findFirst())
+				.orElseGet(() -> ZustaendigeStelle.builder().build());
 	}
 
 	@Mapping(source = "files", target = "filesList")
diff --git a/router/src/main/java/de/ozgcloud/eingang/router/VorgangRemoteService.java b/router/src/main/java/de/ozgcloud/eingang/router/VorgangRemoteService.java
index 2a50225927053555819bbd1ac937ed0598088dd4..260cdc3818a4af61e2f93d632a66afb75a31062f 100644
--- a/router/src/main/java/de/ozgcloud/eingang/router/VorgangRemoteService.java
+++ b/router/src/main/java/de/ozgcloud/eingang/router/VorgangRemoteService.java
@@ -75,7 +75,7 @@ public class VorgangRemoteService {
 		logConnection(organisationsEinheitenId, vorgangServiceStub.get());
 
 		try {
-			return createVorgang(formData, grpcEingangMapper.toEingang(formData), vorgangServiceStub.get(), binaryFileServiceStub.get());
+			return createVorgang(formData, grpcEingangMapper.toEingang(formData, organisationsEinheitenId), vorgangServiceStub.get(), binaryFileServiceStub.get());
 		} finally {
 			finishStubConnections(List.of(vorgangServiceStub, binaryFileServiceStub));
 		}
@@ -159,7 +159,7 @@ public class VorgangRemoteService {
 		}
 
 		String uploadIncomingFile(IncomingFile incomingFile) {
-			var fileContentStream = incomingFile.getContentStreamForFinalRead();
+			var fileContentStream = incomingFile.getContentStream();
 
 			var resultFuture = GrpcFileUploadUtils.createSender(this::buildChunkRequest, fileContentStream,
 					this::buildCallStreamObserver)
diff --git a/router/src/main/java/de/ozgcloud/eingang/router/VorgangService.java b/router/src/main/java/de/ozgcloud/eingang/router/VorgangService.java
index de97243af9a356da303522e4555b1509b540dc16..a5ae891ce8936a906686b30057301f893e3da193 100644
--- a/router/src/main/java/de/ozgcloud/eingang/router/VorgangService.java
+++ b/router/src/main/java/de/ozgcloud/eingang/router/VorgangService.java
@@ -23,31 +23,86 @@
  */
 package de.ozgcloud.eingang.router;
 
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Stream;
 
 import org.springframework.stereotype.Service;
 
 import de.ozgcloud.eingang.common.formdata.FormData;
 import de.ozgcloud.eingang.common.formdata.FormHeader;
+import de.ozgcloud.eingang.common.formdata.IncomingFile;
+import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
 import de.ozgcloud.eingang.common.formdata.ServiceKonto;
 import de.ozgcloud.eingang.common.formdata.ZustaendigeStelle;
 import lombok.AllArgsConstructor;
+import lombok.extern.log4j.Log4j2;
 
 @AllArgsConstructor
 @Service
+@Log4j2
 public class VorgangService {
 
 	private final VorgangRemoteService remoteService;
 
 	public String createVorgang(FormData formData) {
-		var preparedFormData = preserveConsistency(formData);
+		var vorgangId = createVorgangForOrganisationsEinheitIds(getOrganisationsEinheitIds(formData), preserveConsistency(formData));
+		cleanupFormDataFiles(formData);
+		return vorgangId;
+	}
+
+	void cleanupFormDataFiles(FormData formData) {
+		getFormDataFiles(formData)
+				.map(IncomingFile::getFile)
+				.map(File::toPath)
+				.forEach(this::deleteIncomingFile);
+	}
+
+	void deleteIncomingFile(Path path) {
+		try {
+			Files.deleteIfExists(path);
+		} catch (IOException e) {
+			logErrorOnDeleteFailure(e);
+		}
+	}
+
+	void logErrorOnDeleteFailure(Exception e) {
+		LOG.error("Failed to delete temp-file of incoming file!", e);
+	}
+
+	Stream<IncomingFile> getFormDataFiles(FormData formData) {
+		return Stream.concat(
+				formData.getRepresentations().stream(),
+				formData.getAttachments().stream()
+						.map(IncomingFileGroup::getFiles)
+						.flatMap(List::stream)
+		);
+	}
+
+	String createVorgangForOrganisationsEinheitIds(List<String> organisationsEinheitIds, FormData preparedFormData) {
+		return organisationsEinheitIds.isEmpty()
+				? createVorgangOnMissingZustaendigeStelle(preparedFormData)
+				: createMultipleVorgangs(preparedFormData, organisationsEinheitIds).getFirst();
+	}
+
+	String createVorgangOnMissingZustaendigeStelle(FormData formData) {
+		return remoteService.createVorgang(formData, Optional.empty());
+	}
 
-		return remoteService.createVorgang(preparedFormData, getOrganisationsEinheitId(preparedFormData));
+	List<String> createMultipleVorgangs(FormData formData, List<String> organisationseinheitIds) {
+		return organisationseinheitIds.stream()
+				.map(oeId -> remoteService.createVorgang(formData, Optional.of(oeId)))
+				.toList();
 	}
 
-	private Optional<String> getOrganisationsEinheitId(FormData formData) {
-		return Optional.ofNullable(formData.getZustaendigeStelle()).map(ZustaendigeStelle::getOrganisationseinheitenId);
+	List<String> getOrganisationsEinheitIds(FormData formData) {
+		return formData.getZustaendigeStelles().stream()
+				.map(ZustaendigeStelle::getOrganisationseinheitenId)
+				.toList();
 	}
 
 	FormData preserveConsistency(FormData formData) {
diff --git a/router/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/router/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
deleted file mode 100644
index 099d759980592d22435720bf65909618aa0d3c2a..0000000000000000000000000000000000000000
--- a/router/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ /dev/null
@@ -1,6 +0,0 @@
-net.devh.boot.grpc.client.autoconfigure.GrpcClientAutoConfiguration
-net.devh.boot.grpc.client.autoconfigure.GrpcClientMetricAutoConfiguration
-net.devh.boot.grpc.client.autoconfigure.GrpcClientHealthAutoConfiguration
-net.devh.boot.grpc.client.autoconfigure.GrpcClientSecurityAutoConfiguration
-net.devh.boot.grpc.client.autoconfigure.GrpcClientTraceAutoConfiguration
-net.devh.boot.grpc.client.autoconfigure.GrpcDiscoveryClientAutoConfiguration
\ No newline at end of file
diff --git a/router/src/test/java/de/ozgcloud/eingang/router/GrpcEingangMapperITCase.java b/router/src/test/java/de/ozgcloud/eingang/router/GrpcEingangMapperITCase.java
index 4150f6cef6d0574b78c6db89d9b61c068cd620e2..f3c15dea9839888f9895a6e440489ee6f09b9b8e 100644
--- a/router/src/test/java/de/ozgcloud/eingang/router/GrpcEingangMapperITCase.java
+++ b/router/src/test/java/de/ozgcloud/eingang/router/GrpcEingangMapperITCase.java
@@ -27,6 +27,7 @@ import static org.assertj.core.api.Assertions.*;
 
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
@@ -58,8 +59,7 @@ class GrpcEingangMapperITCase {
 
 			@Test
 			void antragstellerShouldBeMapped() {
-
-				var antragSteller = grpcEingangMapper.toEingang(FormDataTestFactory.create()).getAntragsteller();
+				var antragSteller = grpcEingangMapper.toEingang(FormDataTestFactory.create(), Optional.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)).getAntragsteller();
 
 				assertThat(antragSteller.getPostfachId()).isEqualTo(AntragstellerTestFactory.POSTFACH_ID);
 				assertThat(antragSteller.getVorname()).isEqualTo(AntragstellerTestFactory.VORNAME);
@@ -68,8 +68,7 @@ class GrpcEingangMapperITCase {
 
 			@Test
 			void dataShouldBeMapped() {
-
-				var antragsteller = grpcEingangMapper.toEingang(FormDataTestFactory.create()).getAntragsteller();
+				var antragsteller = grpcEingangMapper.toEingang(FormDataTestFactory.create(), Optional.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)).getAntragsteller();
 
 				assertThat(antragsteller.getOtherData().getFieldList()).hasSize(1);
 				assertThat(antragsteller.getOtherData().getField(0).getName()).isEqualTo(AntragstellerTestFactory.GEBIET_BEZEICHNUNG_KEY);
@@ -82,13 +81,21 @@ class GrpcEingangMapperITCase {
 		class TestZustaendigeStelle {
 			@Test
 			void eingangShouldHaveZustaendigeStelle() {
-
-				var zustaendigeStelle = grpcEingangMapper.toEingang(FormDataTestFactory.create()).getZustaendigeStelle();
+				var zustaendigeStelle = grpcEingangMapper.toEingang(FormDataTestFactory.create(), Optional.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID)).getZustaendigeStelle();
 
 				assertThat(zustaendigeStelle).isNotNull();
 				assertThat(zustaendigeStelle.getOrganisationseinheitenId()).isEqualTo(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID);
 				assertThat(zustaendigeStelle.getEmail()).isEqualTo(ZustaendigeStelleTestFactory.EMAIL);
 			}
+
+			@DisplayName("should map empty organisationeinheitId if missing")
+			@Test
+			void shouldMapEmptyOrganisationeinheitIdIfMissing() {
+				var zustaendigeStelle = grpcEingangMapper.toEingang(FormDataTestFactory.create(), Optional.empty()).getZustaendigeStelle();
+
+				assertThat(zustaendigeStelle).isNotNull();
+				assertThat(zustaendigeStelle.getOrganisationseinheitenId()).isEmpty();
+			}
 		}
 
 		@Nested
@@ -100,7 +107,7 @@ class GrpcEingangMapperITCase {
 			@BeforeEach
 			void init() {
 
-				eingang = grpcEingangMapper.toEingang(FormDataTestFactory.create());
+				eingang = grpcEingangMapper.toEingang(FormDataTestFactory.create(), Optional.empty());
 			}
 
 			@Test
@@ -159,7 +166,7 @@ class GrpcEingangMapperITCase {
 			@Test
 			void testRepresentations() {
 
-				GrpcEingang eingang = grpcEingangMapper.toEingang(FormDataTestFactory.create());
+				GrpcEingang eingang = grpcEingangMapper.toEingang(FormDataTestFactory.create(), Optional.empty());
 
 				assertThat(eingang.getRepresentationsCount()).isEqualTo(1);
 
@@ -180,7 +187,7 @@ class GrpcEingangMapperITCase {
 			void valueListShouldGenerateFields() {
 
 				GrpcEingang eingang = grpcEingangMapper
-						.toEingang(FormDataTestFactory.createBuilder().formData(Map.of("key", List.of("value1", "value2"))).build());
+						.toEingang(FormDataTestFactory.createBuilder().formData(Map.of("key", List.of("value1", "value2"))).build(), Optional.empty());
 
 				assertThat(eingang.getFormData().getFieldCount()).isEqualTo(2);
 			}
@@ -190,7 +197,7 @@ class GrpcEingangMapperITCase {
 
 				GrpcEingang eingang = grpcEingangMapper
 						.toEingang(FormDataTestFactory.createBuilder()
-								.formData(Map.of("key-1", List.of(Map.of("sub_key", "value1"), Map.of("sub_key", "value2")))).build());
+								.formData(Map.of("key-1", List.of(Map.of("sub_key", "value1"), Map.of("sub_key", "value2")))).build(), Optional.empty());
 
 				assertThat(eingang.getFormData().getFormCount()).isEqualTo(2);
 				assertThat(eingang.getFormData().getForm(0).getFieldCount()).isEqualTo(1);
diff --git a/router/src/test/java/de/ozgcloud/eingang/router/GrpcEingangMapperTest.java b/router/src/test/java/de/ozgcloud/eingang/router/GrpcEingangMapperTest.java
index 3909125566b6f297d16633590aa4dcc05644611b..df68e82b76e4175a69dde4153eceb108cde21872 100644
--- a/router/src/test/java/de/ozgcloud/eingang/router/GrpcEingangMapperTest.java
+++ b/router/src/test/java/de/ozgcloud/eingang/router/GrpcEingangMapperTest.java
@@ -27,6 +27,8 @@ import static org.assertj.core.api.Assertions.*;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
+import java.util.Optional;
+
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Nested;
@@ -212,7 +214,7 @@ class GrpcEingangMapperTest {
 		}
 
 		private GrpcEingang toEingang() {
-			return mapper.toEingang(FormDataTestFactory.create());
+			return mapper.toEingang(FormDataTestFactory.create(), Optional.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID));
 		}
 	}
 }
\ No newline at end of file
diff --git a/router/src/test/java/de/ozgcloud/eingang/router/VorgangRemoteServiceTest.java b/router/src/test/java/de/ozgcloud/eingang/router/VorgangRemoteServiceTest.java
index 993c973ca2f71c645734db5ab5039151b9a0543f..0fd01eaa035fb5ceeb124fffc5f32e5dc66a0c2b 100644
--- a/router/src/test/java/de/ozgcloud/eingang/router/VorgangRemoteServiceTest.java
+++ b/router/src/test/java/de/ozgcloud/eingang/router/VorgangRemoteServiceTest.java
@@ -117,7 +117,7 @@ class VorgangRemoteServiceTest {
 			when(resolver.resolveBinaryFileServiceStubByOrganisationsEinheitId(any())).thenReturn(managableBinaryFileServiceStub);
 			when(managableBinaryFileServiceStub.get()).thenReturn(binaryFileServiceStub);
 
-			when(eingangMapper.toEingang(any())).thenReturn(eingang);
+			when(eingangMapper.toEingang(any(), any())).thenReturn(eingang);
 
 			doNothing().when(remoteService).logConnection(any(), any());
 			doNothing().when(remoteService).finishStubConnections(any());
@@ -159,7 +159,7 @@ class VorgangRemoteServiceTest {
 			void shouldCallEingangMapper() {
 				createVorgang();
 
-				verify(eingangMapper).toEingang(formData);
+				verify(eingangMapper).toEingang(formData, organisationsEinheitId);
 			}
 
 			@Test
@@ -431,6 +431,55 @@ class VorgangRemoteServiceTest {
 			}
 		}
 
+		@DisplayName("update incoming file")
+		@Nested
+		class TestUpdateIncomingFile {
+
+			@Mock
+			private IncomingFile incomingFile;
+
+			@Mock
+			private InputStream inputStream;
+
+			@Mock
+			private GrpcUploadBinaryFileResponse response;
+
+			@Mock
+			private GrpcUploadBinaryFileRequest request;
+
+			@BeforeEach
+			void mock() {
+				doReturn(response).when(vorgangCreator).waitUntilFutureToComplete(any(), any());
+				when(incomingFile.getContentStream()).thenReturn(inputStream);
+				doReturn(request).when(vorgangCreator).buildMetaDataRequest(any());
+			}
+
+			@DisplayName("should call get content stream")
+			@Test
+			void shouldCallGetContentStream() {
+				vorgangCreator.uploadIncomingFile(incomingFile);
+
+				verify(incomingFile).getContentStream();
+			}
+
+			@DisplayName("should call build request with incoming file")
+			@Test
+			void shouldCallBuildRequestWithIncomingFile() {
+				vorgangCreator.uploadIncomingFile(incomingFile);
+
+				verify(vorgangCreator).buildMetaDataRequest(incomingFile);
+			}
+
+			@DisplayName("should call wait until future complete")
+			@Test
+			void shouldCallWaitUntilFutureComplete() {
+				vorgangCreator.uploadIncomingFile(incomingFile);
+
+				verify(vorgangCreator).waitUntilFutureToComplete(any(), eq(inputStream));
+			}
+
+		}
+
 		@Nested
 		class TestWaitUntilFutureToComplete {
 
diff --git a/router/src/test/java/de/ozgcloud/eingang/router/VorgangServiceTest.java b/router/src/test/java/de/ozgcloud/eingang/router/VorgangServiceTest.java
index 2db3d04b7e3ad7bdb2240c7a1a66d8b39cbb4ca8..74cd1e901ea5260c9ab606fd0f7b00d00fd6fb23 100644
--- a/router/src/test/java/de/ozgcloud/eingang/router/VorgangServiceTest.java
+++ b/router/src/test/java/de/ozgcloud/eingang/router/VorgangServiceTest.java
@@ -23,11 +23,18 @@
  */
 package de.ozgcloud.eingang.router;
 
+import static de.ozgcloud.eingang.common.formdata.FormDataTestFactory.*;
+import static java.util.Collections.*;
 import static org.assertj.core.api.Assertions.*;
 import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.Mockito.*;
 
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
 import java.util.Optional;
+import java.util.stream.Stream;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
@@ -41,6 +48,8 @@ import de.ozgcloud.eingang.common.formdata.FormData;
 import de.ozgcloud.eingang.common.formdata.FormDataTestFactory;
 import de.ozgcloud.eingang.common.formdata.FormHeader;
 import de.ozgcloud.eingang.common.formdata.FormHeaderTestFactory;
+import de.ozgcloud.eingang.common.formdata.IncomingFile;
+import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory;
 import de.ozgcloud.eingang.common.formdata.ServiceKonto;
 import de.ozgcloud.eingang.common.formdata.ServiceKontoTestFactory;
 import de.ozgcloud.eingang.common.formdata.ZustaendigeStelleTestFactory;
@@ -51,20 +60,22 @@ class VorgangServiceTest {
 	@InjectMocks
 	private VorgangService service;
 	@Mock
-	private GrpcEingangMapper eingangMapper;
-	@Mock
 	private VorgangRemoteService remoteService;
 
+	private final FormData formData = FormDataTestFactory.create();
+
 	@DisplayName("Create vorgang")
 	@Nested
 	class TestCreateVorgang {
-
-		private final FormData formData = FormDataTestFactory.create();
 		private final FormData preservedFormData = FormDataTestFactory.create();
+		private final List<String> organisationseinheitIds = List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID);
 
 		@BeforeEach
 		void mockEingangMapper() {
-			doReturn(preservedFormData).when(service).preserveConsistency(formData);
+			doReturn(preservedFormData).when(service).preserveConsistency(any());
+			doReturn(organisationseinheitIds).when(service).getOrganisationsEinheitIds(any());
+			doReturn(VORGANG_ID).when(service).createVorgangForOrganisationsEinheitIds(any(), any());
+			doNothing().when(service).cleanupFormDataFiles(any());
 		}
 
 		@Test
@@ -74,15 +85,231 @@ class VorgangServiceTest {
 			verify(service).preserveConsistency(formData);
 		}
 
+		@DisplayName("should call create vorgang for organisationseinheitIds")
 		@Test
-		void shouldCallRemoteService() {
+		void shouldCallCreateVorgangForOrganisationseinheitIds() {
 			callCreateVorgang();
 
-			verify(remoteService).createVorgang(preservedFormData, Optional.ofNullable(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID));
+			verify(service).createVorgangForOrganisationsEinheitIds(organisationseinheitIds, preservedFormData);
+		}
+
+		@DisplayName("should call get organisationseinheit ids")
+		@Test
+		void shouldCallGetOrganisationseinheitIds() {
+			callCreateVorgang();
+
+			verify(service).getOrganisationsEinheitIds(formData);
+		}
+
+		@DisplayName("should return vorgang id")
+		@Test
+		void shouldReturn() {
+			var vorgangId = callCreateVorgang();
+
+			assertThat(vorgangId).isEqualTo(VORGANG_ID);
+		}
+
+		@DisplayName("should call cleanup form data files")
+		@Test
+		void shouldCallCleanupFormDataFiles() {
+			callCreateVorgang();
+
+			verify(service).cleanupFormDataFiles(formData);
+		}
+
+		private String callCreateVorgang() {
+			return service.createVorgang(formData);
+		}
+	}
+
+	@DisplayName("cleanup form data files")
+	@Nested
+	class TestCleanupFormDataFiles {
+		private final IncomingFile incomingFile = IncomingFileTestFactory.create();
+
+		@BeforeEach
+		void mock() {
+			doReturn(Stream.of(incomingFile)).when(service).getFormDataFiles(formData);
+		}
+
+		@DisplayName("should call delete incoming file")
+		@Test
+		void shouldCallDeleteIncomingFile() {
+			service.cleanupFormDataFiles(formData);
+
+			verify(service).deleteIncomingFile(incomingFile.getFile().toPath());
 		}
+	}
+
+	@DisplayName("get form data files")
+	@Nested
+	class TestGetFormDataFiles {
+
+		private final FormData formData = FormDataTestFactory.create();
+
+		@DisplayName("should return attachments and representations")
+		@Test
+		void shouldReturnAttachmentsAndRepresentations() {
+			var files = service.getFormDataFiles(formData).toList();
+
+			assertThat(files).hasSize(3);
+		}
+	}
+
+	@DisplayName("delete incoming file")
+	@Nested
+	class TestDeleteIncomingFile {
+
+		@Mock
+		private Path path;
+
+		@DisplayName("should call deleteIfExists")
+		@Test
+		void shouldCallDeleteIfExists() {
+			try (var staticMock = mockStatic(Files.class)) {
+				service.deleteIncomingFile(path);
+
+				staticMock.verify(() -> Files.deleteIfExists(path));
+			}
+		}
+
+		@DisplayName("should return")
+		@Test
+		void shouldReturn() {
+			try (var staticMock = mockStatic(Files.class)) {
+				staticMock.when(() -> Files.deleteIfExists(path)).thenReturn(true);
+
+				service.deleteIncomingFile(path);
+			}
+		}
+
+		@DisplayName("should log on error")
+		@Test
+		void shouldLogOnError() {
+			var exception = new IOException();
+			try (var staticMock = mockStatic(Files.class)) {
+				staticMock.when(() -> Files.deleteIfExists(path)).thenThrow(exception);
+
+				service.deleteIncomingFile(path);
+
+				verify(service).logErrorOnDeleteFailure(exception);
+			}
+		}
+
+	}
+
+	@DisplayName("create vorgang for organisationsEinheitIds")
+	@Nested
+	class TestCreateVorgangForOrganisationsEinheitIds {
+		private final FormData preservedFormData = FormDataTestFactory.create();
+		private final List<String> organisationseinheitIds = List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID);
+
+		@DisplayName("should call create multiple vorgangs")
+		@Test
+		void shouldCallCreateMultipleVorgangs() {
+			service.createVorgangForOrganisationsEinheitIds(organisationseinheitIds, preservedFormData);
+
+			verify(service).createMultipleVorgangs(preservedFormData, organisationseinheitIds);
+		}
+
+		@DisplayName("should return first vorgang id with multiple organisationseinheits")
+		@Test
+		void shouldReturnFirstVorgangIdWithMultipleOrganisationseinheits() {
+			doReturn(List.of(VORGANG_ID)).when(service).createMultipleVorgangs(any(), any());
+
+			var vorgangId = service.createVorgangForOrganisationsEinheitIds(organisationseinheitIds, preservedFormData);
+
+			assertThat(vorgangId).isEqualTo(VORGANG_ID);
+		}
+
+		@DisplayName("should call create vorgang on missing zustaendige stelle if organisationseinheit is missing")
+		@Test
+		void shouldCallCreateVorgangOnMissingZustaendigeStelleIfOrganisationseinheitIsMissing() {
+			service.createVorgangForOrganisationsEinheitIds(emptyList(), preservedFormData);
+
+			verify(service).createVorgangOnMissingZustaendigeStelle(eq(preservedFormData));
+		}
+
+		@DisplayName("should return single vorgang id if organisationseinheit is missing")
+		@Test
+		void shouldReturnSingleVorgangIdIfOrganisationseinheitIsMissing() {
+			doReturn(VORGANG_ID).when(service).createVorgangOnMissingZustaendigeStelle(any());
+
+			var firstVorgangId = service.createVorgangForOrganisationsEinheitIds(emptyList(), preservedFormData);
+
+			assertThat(firstVorgangId).isEqualTo(VORGANG_ID);
+		}
+
+	}
+
+	@DisplayName("create vorgang on missing zustaendige stelle")
+	@Nested
+	class TestVorgangOnMissingZustaendigeStelle {
+		@Mock
+		private FormData formData;
+
+		@BeforeEach
+		void mock() {
+			when(remoteService.createVorgang(any(), any())).thenReturn(VORGANG_ID);
+		}
+
+		@DisplayName("should call create vorgang")
+		@Test
+		void shouldCallCreateVorgang() {
+			service.createVorgangOnMissingZustaendigeStelle(formData);
+
+			verify(remoteService).createVorgang(formData, Optional.empty());
+		}
+
+		@DisplayName("should return")
+		@Test
+		void shouldReturn() {
+			var vorgangId = service.createVorgangOnMissingZustaendigeStelle(formData);
+
+			assertThat(vorgangId).isEqualTo(VORGANG_ID);
+		}
+	}
+
+	@DisplayName("create multiple vorgangs")
+	@Nested
+	class TestCreateMultipleVorgangs {
+
+		@Mock
+		private FormData formData;
+
+		@BeforeEach
+		void mock() {
+			when(remoteService.createVorgang(any(), any())).thenReturn(VORGANG_ID);
+		}
+
+		@DisplayName("should call create vorgang twice")
+		@Test
+		void shouldCallCreateVorgangTwice() {
+			service.createMultipleVorgangs(formData, List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID));
+
+			verify(remoteService).createVorgang(formData, Optional.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID));
+		}
+
+		@DisplayName("should return")
+		@Test
+		void shouldReturn() {
+			var vorgangIds = service.createMultipleVorgangs(formData, List.of(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID));
+
+			assertThat(vorgangIds).containsExactly(VORGANG_ID);
+		}
+	}
+
+	@DisplayName("get organisationseinheit ids")
+	@Nested
+	class TestGetOrganisationseinheitIds {
+		private final FormData preservedFormData = FormDataTestFactory.create();
+
+		@DisplayName("should return")
+		@Test
+		void shouldReturn() {
+			var organisationseinheitIds = service.getOrganisationsEinheitIds(preservedFormData);
 
-		private void callCreateVorgang() {
-			service.createVorgang(formData);
+			assertThat(organisationseinheitIds).containsExactly(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID);
 		}
 	}
 
@@ -102,7 +329,7 @@ class VorgangServiceTest {
 			assertThat(consistentFormData.getHeader().getServiceKonto()).isNull();
 		}
 
-		@DisplayName("should keep serviceKonto if postfachAddress eixsts")
+		@DisplayName("should keep serviceKonto if postfachAddress exists")
 		@Test
 		void shouldKeepServiceKonto() {
 			var consistentFormData = service.preserveConsistency(FormDataTestFactory.create());
diff --git a/semantik-adapter/pom.xml b/semantik-adapter/pom.xml
index 18c5fe1bb8ace2afd5e890daf9196ed782046a29..1bc88f3a6f599fa7cee5c72324e261b5c6fa2c9a 100644
--- a/semantik-adapter/pom.xml
+++ b/semantik-adapter/pom.xml
@@ -30,7 +30,7 @@
 	<parent>
 		<groupId>de.ozgcloud.eingang</groupId>
 		<artifactId>eingang-manager</artifactId>
-		<version>2.13.0-SNAPSHOT</version>
+		<version>2.15.0-SNAPSHOT</version>
 	</parent>
 	
 	<artifactId>semantik-adapter</artifactId>
diff --git a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/SemantikAdapter.java b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/SemantikAdapter.java
index 9168807d8b4e2a6c52ae95c8bb509ffd04ecd1d8..65c69a87ebc51b3313b8b4ec84d24f7d10170cf0 100644
--- a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/SemantikAdapter.java
+++ b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/SemantikAdapter.java
@@ -34,7 +34,6 @@ import de.ozgcloud.eingang.semantik.enginebased.EngineBasedSemantikAdapter;
 import de.ozgcloud.eingang.semantik.formbased.FormBasedSemantikAdapter;
 import lombok.extern.log4j.Log4j2;
 
-
 @Log4j2
 @Service
 public class SemantikAdapter {
diff --git a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/AfmZustaendigeStelleMapper.java b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/AfmZustaendigeStelleMapper.java
index 1e057c6e81f5c937a429d8050c2c8996742026c9..4fff0ea90b799476bac4f0b3b3c39e4e8378935f 100644
--- a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/AfmZustaendigeStelleMapper.java
+++ b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/AfmZustaendigeStelleMapper.java
@@ -72,7 +72,9 @@ class AfmZustaendigeStelleMapper implements AfmEngineBasedMapper {
 				.organisationseinheitenId(organisationseinheitenID)
 				.build();
 
-		return formData.toBuilder().formData(addMetaDataFlag(formData)).zustaendigeStelle(zustaendigeStelle).build();
+		return formData.toBuilder()
+				.formData(addMetaDataFlag(formData))
+				.zustaendigeStelle(zustaendigeStelle).build();
 	}
 
 	String getOrganisationseinheitenId(FormData formData) {
diff --git a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataMapper.java b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataMapper.java
index 4b417bd36dc8421632a5e26447d1b7b669f249dd..a99ae318b214154314e9cf5752dcf13ce03d89fe 100644
--- a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataMapper.java
+++ b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataMapper.java
@@ -45,7 +45,8 @@ public class ZustaendigeStelleMetadataMapper {
 		return formData.getRepresentations().stream().filter(IS_BEHOERDE_METADATA).findAny()
 				.map(this::readZustaendigeStelleMetadata)
 				.map(this::mapZustaendigeStelle)
-				.map(zustaendigeStelle -> formData.toBuilder().zustaendigeStelle(zustaendigeStelle).build())
+				.map(zustaendigeStelle -> formData.toBuilder()
+						.zustaendigeStelle(zustaendigeStelle).build())
 				.orElse(formData);
 	}
 
diff --git a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/dfoerdermittel/DFoerdermittelEngineBasedSemantikAdapter.java b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/dfoerdermittel/DFoerdermittelEngineBasedSemantikAdapter.java
index a89ba548f5247f858cea72a3443f89d5cd014cda..82d0967071bcfcabad3b9a7803d0e23c77e69a7a 100644
--- a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/dfoerdermittel/DFoerdermittelEngineBasedSemantikAdapter.java
+++ b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/enginebased/dfoerdermittel/DFoerdermittelEngineBasedSemantikAdapter.java
@@ -2,6 +2,7 @@ package de.ozgcloud.eingang.semantik.enginebased.dfoerdermittel;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -100,22 +101,32 @@ public class DFoerdermittelEngineBasedSemantikAdapter implements EngineBasedSema
 
 	FormData addOrganisationsEinheitId(FormData formData) {
 		return Optional.ofNullable((String) getFachnachricht(formData).get(KEY_ORGANISATIONS_EINHEIT_ID))
-				.map(orgaId -> addOrganisationsEinheitId(orgaId, formData.getZustaendigeStelle()))
-				.map(zustStelle -> formData.toBuilder().zustaendigeStelle(zustStelle).build())
+				.map(orgaId -> addOrganisationsEinheitId(orgaId, formData.getZustaendigeStelles()))
+				.map(zustStelle -> formData.toBuilder()
+						.zustaendigeStelle(zustStelle)
+						.build())
 				.orElse(formData);
 	}
 
-	private ZustaendigeStelle addOrganisationsEinheitId(String orgaId, ZustaendigeStelle zustaendigeStelle) {
+	private ZustaendigeStelle addOrganisationsEinheitId(String orgaId, Collection<ZustaendigeStelle> zustaendigeStelles) {
 		ZustaendigeStelle.ZustaendigeStelleBuilder zustaendigeStelleBuilder;
-		if (Objects.isNull(zustaendigeStelle)) {
+		if (Objects.isNull(zustaendigeStelles) || zustaendigeStelles.isEmpty()) {
 			zustaendigeStelleBuilder = ZustaendigeStelle.builder();
 		} else {
+			var zustaendigeStellesIterator = zustaendigeStelles.iterator();
+			var zustaendigeStelle = zustaendigeStellesIterator.next();
+			logErrorForExistingZustaendigeStelle();
 			zustaendigeStelleBuilder = zustaendigeStelle.toBuilder();
 		}
 
 		return zustaendigeStelleBuilder.organisationseinheitenId(orgaId).build();
 	}
 
+	void logErrorForExistingZustaendigeStelle() {
+		LOG.error(
+				"Expect no existing ZustaendigeStelle for DFoerdermittel! Continuing with two ZustaendigeStelles, the original(s) and a copy of the first with overridden OrganisationsEinheitId.");
+	}
+
 	FormData addFormName(FormData formData) {
 		return mapWithModifiedHeader(formData, headerBuilder -> headerBuilder.formName(
 				getNonEmptyFachnachrichtValueByKey(formData, KEY_FORM_NAME)
diff --git a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragZustaendigeStelleMapper.java b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragZustaendigeStelleMapper.java
index 29e2c0834d9a05e11519f371cdd2686faa549ed4..d7fa85a1d87e3ac6776068e6a5a062a8b96de3d3 100644
--- a/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragZustaendigeStelleMapper.java
+++ b/semantik-adapter/src/main/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragZustaendigeStelleMapper.java
@@ -18,7 +18,6 @@ import org.springframework.boot.context.properties.bind.Binder;
 import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Component;
 
-import de.ozgcloud.eingang.common.errorhandling.TechnicalException;
 import de.ozgcloud.eingang.common.formdata.FormData;
 import de.ozgcloud.eingang.common.formdata.FormHeader;
 import de.ozgcloud.eingang.common.formdata.ZustaendigeStelle;
@@ -67,78 +66,52 @@ public class MantelantragZustaendigeStelleMapper implements FormBasedMapper {
 
 	@Override
 	public FormData parseFormData(FormData formData) {
-		try {
-			return adaptFormDataWithPossibleException(formData);
-		} catch (TechnicalException exception) {
-			logWarningForFailure(exception);
-			return formData;
-		}
+		return formData.toBuilder()
+				.clearZustaendigeStelles()
+				.zustaendigeStelles(getZustaendigeStelles(formData))
+				.build();
 	}
 
-	void logWarningForFailure(Exception exception) {
-		LOG.warn("Failed mapping Zustaendigestelle of Mantelantrag: %s".formatted(exception.getMessage()));
+	List<ZustaendigeStelle> getZustaendigeStelles(FormData formData) {
+		var fieldMap = formData.getFormData();
+		var matchingSlots = getMatchingSlots(fieldMap);
+		if (matchingSlots.isEmpty()) {
+			logErrorForNoMatchingIdentifiers();
+		}
+		return matchingSlots.stream()
+				.map(slotIndex -> getZustaendigeStelle(fieldMap, slotIndex))
+				.toList();
 	}
 
-	FormData adaptFormDataWithPossibleException(FormData formData) {
-		var fieldMap = formData.getFormData();
-		var slotIndex = findSlotIndex(fieldMap);
-		return adaptFormDataWithValueGetter(formData, field -> getFieldByKeyOrEmpty(
+	ZustaendigeStelle getZustaendigeStelle(Map<String, Object> fieldMap, int slotIndex) {
+		UnaryOperator<String> getValueOrEmpty = field -> getFieldByKeyOrEmpty(
 				fieldMap,
 				getNameForSlotIndex(field, slotIndex)
-		));
-	}
-
-	private FormData adaptFormDataWithValueGetter(FormData formData, UnaryOperator<String> getValueOrEmpty) {
-		return formData.toBuilder()
-				.zustaendigeStelle(ZustaendigeStelle.builder()
-						.organisationseinheitenId(getOrganisationseinheitId(getValueOrEmpty))
-						.bezeichnung(getValueOrEmpty.apply(BEZEICHNUNG_FIELD))
-						.email(getValueOrEmpty.apply(EMAIL_FIELD))
-						.hausanschriftStrasse(getValueOrEmpty.apply(HAUSANSCHRIFT_STRASSE_FIELD))
-						.hausanschriftPlz(getValueOrEmpty.apply(HAUSANSCHRIFT_PLZ_FIELD))
-						.hausanschriftOrt(getValueOrEmpty.apply(HAUSANSCHRIFT_ORT_FIELD))
-						.telefon(getValueOrEmpty.apply(TELEFON_FIELD))
-						.build())
-				.build();
-	}
-
-	private String getOrganisationseinheitId(UnaryOperator<String> getValueOrEmpty) {
+		);
 		var organisationseinheitId = getValueOrEmpty.apply(ORGANISATIONSEINHEIT_ID_FIELD);
-
 		if (organisationseinheitId.isBlank()) {
-			throw new TechnicalException("OrganistaionseinheitId not found!");
-		}
-
-		return organisationseinheitId;
-	}
-
-	int findSlotIndex(Map<String, Object> fieldMap) {
-		var matchingSlots = getMatchingSlots(fieldMap);
-		verifyOneMatchingIdentifier(matchingSlots);
-		return matchingSlots.getFirst();
-	}
-
-	private void verifyOneMatchingIdentifier(List<Integer> matchingSlots) {
-		if (matchingSlots.size() != 1) {
-			var message = getMultipleSlotsMessage(matchingSlots);
-			if (matchingSlots.isEmpty()) {
-				throw new TechnicalException(message);
-			} else {
-				logWarningForUnexpected(message);
-			}
+			logWarningForEmptyOrganisationseinheitId(slotIndex);
 		}
+		return ZustaendigeStelle.builder()
+				.organisationseinheitenId(organisationseinheitId)
+				.bezeichnung(getValueOrEmpty.apply(BEZEICHNUNG_FIELD))
+				.email(getValueOrEmpty.apply(EMAIL_FIELD))
+				.hausanschriftStrasse(getValueOrEmpty.apply(HAUSANSCHRIFT_STRASSE_FIELD))
+				.hausanschriftPlz(getValueOrEmpty.apply(HAUSANSCHRIFT_PLZ_FIELD))
+				.hausanschriftOrt(getValueOrEmpty.apply(HAUSANSCHRIFT_ORT_FIELD))
+				.telefon(getValueOrEmpty.apply(TELEFON_FIELD))
+				.build();
 	}
 
-	void logWarningForUnexpected(String message) {
-		LOG.warn("Unexpected Zustaendigestelle in Mantelantrag: %s".formatted(message));
+	void logWarningForEmptyOrganisationseinheitId(int slotIndex) {
+		LOG.warn("[Mantelantrag] OrganisationseinheitId for slot {} is empty!", slotIndex);
 	}
 
-	String getMultipleSlotsMessage(List<Integer> matchingSlots) {
-		return "Found %d matching nachrichtenbroker addresses! Expected one of '%s'.".formatted(matchingSlots.size(),
-				Strings.join(xtaIdentifiers, ','));
+	void logErrorForNoMatchingIdentifiers() {
+		LOG.error("[Mantelantrag] No matching Zustaendigestelle found! For identifiers: '{}'.", Strings.join(xtaIdentifiers, ','));
 	}
 
-	private List<Integer> getMatchingSlots(Map<String, Object> fieldMap) {
+	List<Integer> getMatchingSlots(Map<String, Object> fieldMap) {
 		return IntStream.range(0, 3)
 				.filter(slotIndex -> xtaIdentifiers.contains(getXtaIdentifierOfSlot(fieldMap, slotIndex)))
 				.boxed()
diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/SemantikAdapterTest.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/SemantikAdapterTest.java
index 754667f0298c9d867846cafee6f28d6b82677fd2..ea63f2379a7391af25178495e00d3af611cb04e4 100644
--- a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/SemantikAdapterTest.java
+++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/SemantikAdapterTest.java
@@ -23,6 +23,7 @@
  */
 package de.ozgcloud.eingang.semantik;
 
+import static de.ozgcloud.eingang.common.formdata.FormDataTestFactory.*;
 import static org.assertj.core.api.Assertions.*;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
@@ -98,6 +99,7 @@ class SemantikAdapterTest {
 			doReturn(List.of(engineAdapter)).when(adapter).getResponsibleEngineAdapters(formData);
 			when(engineAdapter.parseFormData(any())).thenReturn(engineAdapterResponse);
 			when(formAdapter.parseFormData(any())).thenReturn(formAdapterResponse);
+			when(vorgangService.createVorgang(any())).thenReturn(VORGANG_ID);
 		}
 
 		@Test
@@ -127,5 +129,13 @@ class SemantikAdapterTest {
 
 			verify(vorgangService).createVorgang(formAdapterResponse);
 		}
+
+		@DisplayName("should return first vorgang id")
+		@Test
+		void shouldReturnFirstVorgangId() {
+			var vorgangId = adapter.processFormData(formData);
+
+			assertThat(vorgangId).isEqualTo(VORGANG_ID);
+		}
 	}
 }
diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/FilesMapperHelperTest.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/FilesMapperHelperTest.java
index cfbf8d3481cd4679412ceceb84f886152467c30a..0375100ea49c6ac7f0c68bdff8a41d8d988bd3ad 100644
--- a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/FilesMapperHelperTest.java
+++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/FilesMapperHelperTest.java
@@ -171,7 +171,7 @@ class FilesMapperHelperTest {
 
 			assertThat(cleanedFormData.getId()).isEqualTo(formData.getId());
 			assertThat(cleanedFormData.getHeader()).isEqualTo(formData.getHeader());
-			assertThat(cleanedFormData.getZustaendigeStelle()).isEqualTo(formData.getZustaendigeStelle());
+			assertThat(cleanedFormData.getZustaendigeStelles()).isEqualTo(formData.getZustaendigeStelles());
 			assertThat(cleanedFormData.getAntragsteller()).isEqualTo(formData.getAntragsteller());
 			assertThat(cleanedFormData.getNumberOfAttachments()).isEqualTo(formData.getNumberOfAttachments());
 			assertThat(cleanedFormData.getAttachments()).isEqualTo(formData.getAttachments());
diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/AfmZustaendigeStelleMapperTest.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/AfmZustaendigeStelleMapperTest.java
index 4f83cb409499a33c332c3b8226012cf210949ae8..e9abbeff9c2dc8b2af9f03c35006fe667cc3acbc 100644
--- a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/AfmZustaendigeStelleMapperTest.java
+++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/AfmZustaendigeStelleMapperTest.java
@@ -37,6 +37,7 @@ import org.mockito.Spy;
 
 import de.ozgcloud.eingang.common.formdata.FormData;
 import de.ozgcloud.eingang.common.formdata.FormDataTestFactory;
+import de.ozgcloud.eingang.common.formdata.ZustaendigeStelle;
 
 class AfmZustaendigeStelleMapperTest {
 
@@ -78,22 +79,27 @@ class AfmZustaendigeStelleMapperTest {
 			void shouldMapOrganisationseinheitenId() {
 				var parsedFormData = parseZustaendigeStelleData(formData);
 
-				assertThat(parsedFormData.getZustaendigeStelle().getOrganisationseinheitenId())
-						.isEqualTo(AfmZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID);
+				assertThat(parsedFormData.getZustaendigeStelles())
+						.extracting(ZustaendigeStelle::getOrganisationseinheitenId)
+						.containsExactly(AfmZustaendigeStelleTestFactory.ORGANISATIONSEINHEITEN_ID);
 			}
 
 			@Test
 			void shouldMapBezeichnung() {
 				var parsedFormData = parseZustaendigeStelleData(formData);
 
-				assertThat(parsedFormData.getZustaendigeStelle().getBezeichnung()).isEqualTo(BEZEICHNUNG);
+				assertThat(parsedFormData.getZustaendigeStelles())
+						.extracting(ZustaendigeStelle::getBezeichnung)
+						.containsExactly(BEZEICHNUNG);
 			}
 
 			@Test
 			void shouldMapEmail() {
 				var parsedFormData = parseZustaendigeStelleData(formData);
 
-				assertThat(parsedFormData.getZustaendigeStelle().getEmail()).isEqualTo(AfmZustaendigeStelleTestFactory.EMAIL);
+				assertThat(parsedFormData.getZustaendigeStelles())
+						.extracting(ZustaendigeStelle::getEmail)
+						.containsExactly(AfmZustaendigeStelleTestFactory.EMAIL);
 			}
 
 			@Test
diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataMapperTest.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataMapperTest.java
index 5da34d86397802416e222b17f31722392944791d..56058ec127401eeff1744df316e1aa60ef62449e 100644
--- a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataMapperTest.java
+++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/afm/ZustaendigeStelleMetadataMapperTest.java
@@ -44,7 +44,7 @@ class ZustaendigeStelleMetadataMapperTest {
 			behoerdeMetadataFile = IncomingFileTestFactory.createBuilder().name(ZustaendigeStelleMetadataMapper.BEHOERDE_METADATA_FILE_NAME)
 					.build();
 			formData = FormDataTestFactory.createBuilder()
-					.zustaendigeStelle(null)
+					.clearZustaendigeStelles()
 					.representation(behoerdeMetadataFile).build();
 		}
 
@@ -76,17 +76,15 @@ class ZustaendigeStelleMetadataMapperTest {
 
 			var result = mapper.parseZustaendigeStelleData(formData);
 
-			assertThat(result.getZustaendigeStelle()).isEqualTo(zustaendigeStelle);
+			assertThat(result.getZustaendigeStelles()).containsExactly(zustaendigeStelle);
 		}
 	}
 
 	@Nested
 	class TestReadBehoerdeMetadata {
 
-
 		private File brokenFile;
 
-
 	}
 
 	@Nested
diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/dfoerdermittel/DFoerdermittelEngineBasedSemantikAdapterTest.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/dfoerdermittel/DFoerdermittelEngineBasedSemantikAdapterTest.java
index 2445fe3b2f3f7119bc53e33031595a02e6b7c20c..512d0a840d9c9018c5eb0b3c81495b470636f8e1 100644
--- a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/dfoerdermittel/DFoerdermittelEngineBasedSemantikAdapterTest.java
+++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/dfoerdermittel/DFoerdermittelEngineBasedSemantikAdapterTest.java
@@ -27,6 +27,7 @@ import de.ozgcloud.eingang.common.formdata.PostfachAddressTestFactory;
 import de.ozgcloud.eingang.common.formdata.ServiceKontoTestFactory;
 import de.ozgcloud.eingang.common.formdata.StringBasedIdentifier;
 import de.ozgcloud.eingang.common.formdata.ZustaendigeStelle;
+import de.ozgcloud.eingang.common.formdata.ZustaendigeStelleTestFactory;
 import de.ozgcloud.eingang.semantik.common.ServiceKontoFactory;
 
 class DFoerdermittelEngineBasedSemantikAdapterTest {
@@ -217,12 +218,44 @@ class DFoerdermittelEngineBasedSemantikAdapterTest {
 
 	@Nested
 	class TestAddOrganisationsEinheitId {
-		@Test
-		void shouldHaveOrganisationsEinheitId() {
-			var formData = adapter.addOrganisationsEinheitId(DFoerdermittelFormDataTestFactory.create());
 
-			assertThat(formData.getZustaendigeStelle()).isNotNull().extracting(ZustaendigeStelle::getOrganisationseinheitenId)
-					.isEqualTo(ORGANISATIONS_EINHEIT_ID);
+		@DisplayName("with no existing zustaendige stelles")
+		@Nested
+		class TestWithNoExistingZustaendigeStelles {
+			@Test
+			void shouldHaveOrganisationsEinheitId() {
+				var inputFormData = DFoerdermittelFormDataTestFactory.createBuilder()
+						.clearZustaendigeStelles()
+						.build();
+
+				var formData = adapter.addOrganisationsEinheitId(inputFormData);
+
+				assertThat(formData.getZustaendigeStelles())
+						.extracting(ZustaendigeStelle::getOrganisationseinheitenId)
+						.containsExactly(ORGANISATIONS_EINHEIT_ID);
+			}
+		}
+
+		@DisplayName("with one existing zustaendige stelle")
+		@Nested
+		class TestWithOneExistingZustaendigeStelle {
+
+			@Test
+			void shouldHaveOrganisationsEinheitId() {
+				var formData = adapter.addOrganisationsEinheitId(DFoerdermittelFormDataTestFactory.create());
+
+				assertThat(formData.getZustaendigeStelles())
+						.extracting(ZustaendigeStelle::getOrganisationseinheitenId)
+						.containsExactly(ZustaendigeStelleTestFactory.ORGANISATIONSEINHEIT_ID, ORGANISATIONS_EINHEIT_ID);
+			}
+
+			@DisplayName("should log error for existing zustaendige stelle")
+			@Test
+			void shouldLogErrorForExistingZustaendigeStelle() {
+				adapter.addOrganisationsEinheitId(DFoerdermittelFormDataTestFactory.create());
+
+				verify(adapter).logErrorForExistingZustaendigeStelle();
+			}
 		}
 	}
 
diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/dfoerdermittel/DFoerdermittelFormDataTestFactory.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/dfoerdermittel/DFoerdermittelFormDataTestFactory.java
index 8b8c9bf4103b13f085a7910361925a11e7b90297..7bd4cc6a52d36405595a47500be02c2919066c6f 100644
--- a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/dfoerdermittel/DFoerdermittelFormDataTestFactory.java
+++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/dfoerdermittel/DFoerdermittelFormDataTestFactory.java
@@ -8,6 +8,7 @@ import java.util.function.Predicate;
 import java.util.stream.IntStream;
 
 import de.ozgcloud.eingang.common.formdata.FormData;
+import de.ozgcloud.eingang.common.formdata.FormDataTestFactory;
 import de.ozgcloud.eingang.common.formdata.FormHeaderTestFactory;
 import lombok.Builder;
 
@@ -35,7 +36,7 @@ class DFoerdermittelFormDataTestFactory {
 	}
 
 	static FormData.FormDataBuilder createBuilderWithFachnachricht(Fachnachricht fachnachricht) {
-		return FormData.builder()
+		return FormDataTestFactory.createBuilder()
 				.header(FormHeaderTestFactory.create())
 				.formData(Map.of("Fachnachricht", createFachnachrichtMapWithFachnachricht(fachnachricht)));
 	}
diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/formsolutions/FormSolutionsEngineBasedAdapterITCase.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/formsolutions/FormSolutionsEngineBasedAdapterITCase.java
index 47c563508627226dac6341fe8d6e4b36f9062b70..b0535b604a7120b70b0b8803c8003cc038cb9ae1 100644
--- a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/formsolutions/FormSolutionsEngineBasedAdapterITCase.java
+++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/formsolutions/FormSolutionsEngineBasedAdapterITCase.java
@@ -50,6 +50,7 @@ import de.ozgcloud.eingang.common.formdata.FormData;
 import de.ozgcloud.eingang.common.formdata.FormDataTestFactory;
 import de.ozgcloud.eingang.common.formdata.IncomingFileGroupTestFactory;
 import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory;
+import de.ozgcloud.eingang.common.formdata.ZustaendigeStelle;
 import de.ozgcloud.eingang.semantik.SemantikAdapter;
 import lombok.SneakyThrows;
 
@@ -236,14 +237,16 @@ public class FormSolutionsEngineBasedAdapterITCase {
 			void shouldMap() {
 				var data = engineAdapter.parseFormData(formData);
 
-				assertThat(data.getZustaendigeStelle()).isNotNull();
+				assertThat(data.getZustaendigeStelles()).isNotNull().isNotEmpty();
 			}
 
 			@Test
 			void shouldMapOrganistaionseinheitenId() {
 				var data = engineAdapter.parseFormData(formData);
 
-				assertThat(data.getZustaendigeStelle().getOrganisationseinheitenId()).isEqualTo("test");
+				assertThat(data.getZustaendigeStelles())
+						.extracting(ZustaendigeStelle::getOrganisationseinheitenId)
+						.containsExactly("test");
 			}
 		}
 	}
diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/formsolutions/FormSolutionsZustaendigeStelleMapperTest.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/formsolutions/FormSolutionsZustaendigeStelleMapperTest.java
index 1e019f49a47345092a4c9c2b5e6196871c621417..bd31c4218074b8bc343d3327e10455885df7371a 100644
--- a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/formsolutions/FormSolutionsZustaendigeStelleMapperTest.java
+++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/enginebased/formsolutions/FormSolutionsZustaendigeStelleMapperTest.java
@@ -37,7 +37,6 @@ import org.mockito.Spy;
 
 import de.ozgcloud.eingang.common.formdata.FormData;
 import de.ozgcloud.eingang.common.formdata.FormDataTestFactory;
-import de.ozgcloud.eingang.semantik.enginebased.formsolutions.FormSolutionsZustaendigeStelleMapper;
 
 class FormSolutionsZustaendigeStelleMapperTest {
 
@@ -53,7 +52,6 @@ class FormSolutionsZustaendigeStelleMapperTest {
 		@BeforeEach
 		void setup() {
 			formData = FormDataTestFactory.createBuilder()
-					.zustaendigeStelle(null)
 					.formData(Map.of(
 							FormDataTestFactory.SIMPLE_VALUE_KEY, FormDataTestFactory.SIMPLE_VALUE,
 							FormSolutionsZustaendigeStelleMapper.ZUSTAENDIGE_STELLE, ORGANISATIONSEINHEIT_ID))
@@ -64,7 +62,7 @@ class FormSolutionsZustaendigeStelleMapperTest {
 		void shouldParseFormData() {
 			var resultFormData = mapper.parseFormData(formData);
 
-			assertThat(resultFormData.getZustaendigeStelle().getOrganisationseinheitenId()).isEqualTo(ORGANISATIONSEINHEIT_ID);
+			assertThat(resultFormData.getZustaendigeStelles().getFirst().getOrganisationseinheitenId()).isEqualTo(ORGANISATIONSEINHEIT_ID);
 			assertThat(resultFormData.getFormData()).doesNotContainKey(ZUSTAENDIGE_STELLE);
 		}
 
@@ -73,7 +71,7 @@ class FormSolutionsZustaendigeStelleMapperTest {
 		void shouldNotChangeAnother() {
 			var resultFormData = mapper.parseFormData(formData);
 
-			assertThat(resultFormData).usingRecursiveComparison().ignoringFields("zustaendigeStelle", "formData").isEqualTo(formData);
+			assertThat(resultFormData).usingRecursiveComparison().ignoringFields("zustaendigeStelles", "formData").isEqualTo(formData);
 			assertThat(resultFormData.getFormData())
 					.containsAllEntriesOf(Map.of(FormDataTestFactory.SIMPLE_VALUE_KEY, FormDataTestFactory.SIMPLE_VALUE));
 		}
diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragITCase.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragITCase.java
index a4951086c82837ebc3c01ef5f19b8833882b0e3c..e80eeca2598ef00dc45d827401744d80eb10ba4c 100644
--- a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragITCase.java
+++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragITCase.java
@@ -1,5 +1,6 @@
 package de.ozgcloud.eingang.semantik.formbased.mantelantrag;
 
+import static de.ozgcloud.eingang.common.formdata.FormDataTestFactory.*;
 import static org.assertj.core.api.Assertions.*;
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
@@ -7,69 +8,154 @@ import static org.mockito.Mockito.*;
 import java.io.File;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 
+import org.junit.jupiter.api.BeforeAll;
+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.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.boot.test.mock.mockito.SpyBean;
 import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.DynamicPropertyRegistry;
+import org.springframework.test.context.DynamicPropertySource;
 
 import de.ozgcloud.common.binaryfile.TempFileUtils;
 import de.ozgcloud.common.test.TestUtils;
 import de.ozgcloud.eingang.Application;
 import de.ozgcloud.eingang.common.formdata.FormData;
 import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory;
-import de.ozgcloud.eingang.router.VorgangService;
+import de.ozgcloud.eingang.router.VorgangRemoteService;
 import de.ozgcloud.eingang.semantik.SemantikAdapter;
 import de.ozgcloud.eingang.semantik.enginebased.formsolutions.FormSolutionsEngineBasedAdapterITCase;
 import lombok.SneakyThrows;
 
 @ActiveProfiles({ "local", "itcase" })
-@SpringBootTest(classes = Application.class, properties = { "ozgcloud.xta.identifiers=afmsh:ozg-cloud-utopia-test" })
+@SpringBootTest(classes = Application.class)
 public class MantelantragITCase {
 
 	private static final String FILE_NAME_XDOMEA = "mantelantrag/4620-EH6C_b3c9168a-6ae9-4361-8b2f-6837bb341021_Geschaeftsgang.Geschaeftsgang.0201.xml";
 	private static final String FILE_NAME_MANTELANTRAG = "mantelantrag/4620-EH6C_7d703670-15b6-42b2-8cd1-88a7e4c494b9_Antrag_Max_Mustermann_SGBXII.xml";
 
 	@MockBean
-	VorgangService vorgangService;
+	VorgangRemoteService vorgangRemoteService;
 
 	@SpyBean
 	SemantikAdapter semantikAdapter;
 
+	@Captor
+	ArgumentCaptor<FormData> formDataCaptor;
+	private FormData formData;
+
+	@Captor
+	ArgumentCaptor<Optional<String>> oeIdCaptor;
+
+	@Autowired
+	MantelantragZustaendigeStelleMapper mantelantragZustaendigeStelleMapper;
+
+	static List<String> xtaIdentifiers = Collections.emptyList();
+
+	@BeforeEach
+	void mock() {
+		clearInvocations(vorgangRemoteService);
+		doReturn(VORGANG_ID).when(vorgangRemoteService).createVorgang(any(FormData.class), any());
+		formData = prepareTestData();
+		mantelantragZustaendigeStelleMapper.init();
+	}
+
+	@DynamicPropertySource
+	static void dynamicProperties(DynamicPropertyRegistry registry) {
+		registry.add("ozgcloud.xta.identifiers", () -> xtaIdentifiers);
+	}
+
+	@DisplayName("without matching zustaendige stelle")
 	@Nested
-	class TestZustaendigeStelle {
+	class TestWithoutMatchingZustaendigeStelle {
 
-		@Captor
-		ArgumentCaptor<FormData> formDataCaptor;
+		@BeforeAll
+		static void setup() {
+			xtaIdentifiers = List.of("afmsh:unknown");
+		}
+
+		@DisplayName("should create one vorgang")
+		@Test
+		void shouldCreateOneVorgang() {
+			semantikAdapter.processFormData(formData);
+
+			verify(vorgangRemoteService, times(1)).createVorgang(formDataCaptor.capture(), oeIdCaptor.capture());
+			assertThat(oeIdCaptor.getValue()).isEmpty();
+		}
+	}
+
+	@DisplayName("with one matching zustaendige stelle")
+	@Nested
+	class TestWithOneMatchingZustaendigeStelle {
+		@BeforeAll
+		static void setup() {
+			xtaIdentifiers = List.of("afmsh:ozg-cloud-utopia-test");
+		}
 
+		@DisplayName("should create one vorgang")
 		@Test
-		void zustaendigeStelleExists() {
-			var formData = prepareTestData();
-			doReturn("test").when(vorgangService).createVorgang(any(FormData.class));
+		void shouldCreateOneVorgang() {
 			semantikAdapter.processFormData(formData);
 
-			verify(vorgangService).createVorgang(formDataCaptor.capture());
-			FormData capturedFormData = formDataCaptor.getValue();
-			assertThat(capturedFormData).isNotNull();
+			verify(vorgangRemoteService, times(1)).createVorgang(formDataCaptor.capture(), oeIdCaptor.capture());
+			assertThat(oeIdCaptor.getValue()).contains("123");
 		}
+	}
 
+	@DisplayName("with two matching zustaendige stelle")
+	@Nested
+	class TestWithTwoMatchingZustaendigeStelle {
+
+		@BeforeAll
+		static void setup() {
+			xtaIdentifiers = List.of("afmsh:ozg-cloud-utopia-test", "gae:ozg-cloud-itcase-test");
+		}
+
+		@DisplayName("should create two vorangs with partially matching zustaendigeStelle")
 		@Test
-		void zustaendigeStelleIsUtopia() {
-			var formData = prepareTestData();
-			doReturn("test").when(vorgangService).createVorgang(any(FormData.class));
+		void shouldCreateTwoVorangsWithPartiallyMatchingZustaendigeStelle() {
 			semantikAdapter.processFormData(formData);
 
-			verify(vorgangService).createVorgang(formDataCaptor.capture());
-			FormData capturedFormData = formDataCaptor.getValue();
+			verify(vorgangRemoteService, times(2)).createVorgang(formDataCaptor.capture(), oeIdCaptor.capture());
+			assertThat(oeIdCaptor.getAllValues()).contains(Optional.of("123"), Optional.of("444"));
+		}
+	}
 
-			assertThat(capturedFormData.getZustaendigeStelle().getOrganisationseinheitenId()).isEqualTo("123");
+	@DisplayName("with three matching zustaendige stelles")
+	@Nested
+	class TestWithThreeMatchingZustaendigeStelles {
+
+		@BeforeAll
+		static void setup() {
+			xtaIdentifiers = List.of("afmsh:ozg-cloud-utopia-test", "gae:ozg-cloud-itcase-test", "afmsh:ozg-cloud-bad-segeberg-kreis");
+		}
+
+		@DisplayName("should create three vorgangs")
+		@Test
+		void shouldCreateThreeVorgangs() {
+			semantikAdapter.processFormData(formData);
+
+			verify(vorgangRemoteService, times(3)).createVorgang(formDataCaptor.capture(), oeIdCaptor.capture());
+			assertThat(oeIdCaptor.getAllValues()).contains(Optional.of("123"), Optional.of("321"), Optional.of("444"));
 		}
+	}
+
+	@DisplayName("should return first vorgangId")
+	@Test
+	void shouldReturnFirstVorgangId() {
+		var result = semantikAdapter.processFormData(formData);
 
+		assertThat(result).isEqualTo(VORGANG_ID);
 	}
 
 	private FormData prepareTestData() {
diff --git a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragZustaendigeStelleMapperTest.java b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragZustaendigeStelleMapperTest.java
index ffc88cabe17fb7e087abab038e13dfff3b8b14d1..782209dff8ebd6174a29942c0812b90f8b5753ca 100644
--- a/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragZustaendigeStelleMapperTest.java
+++ b/semantik-adapter/src/test/java/de/ozgcloud/eingang/semantik/formbased/mantelantrag/MantelantragZustaendigeStelleMapperTest.java
@@ -1,6 +1,7 @@
 package de.ozgcloud.eingang.semantik.formbased.mantelantrag;
 
 import static de.ozgcloud.eingang.semantik.formbased.mantelantrag.MantelantragZustaendigeStelleMapper.*;
+import static java.util.Collections.*;
 import static org.assertj.core.api.Assertions.*;
 import static org.mockito.Mockito.*;
 
@@ -18,13 +19,10 @@ import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 import org.junit.jupiter.params.provider.ValueSource;
-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.FormDataTestFactory;
 import de.ozgcloud.eingang.common.formdata.FormHeaderTestFactory;
@@ -107,53 +105,104 @@ class MantelantragZustaendigeStelleMapperTest {
 		}
 	}
 
-	@DisplayName("adapt form data")
+	@DisplayName("parse form data")
 	@Nested
-	class TestAdaptFormData {
+	class TestParseFormData {
+
+		private FormData formData;
 
 		@Mock
+		private ZustaendigeStelle zustaendigeStelle;
+
+		@BeforeEach
+		void mock() {
+			formData = FormDataTestFactory.create();
+		}
+
+		@DisplayName("should override zustaendige stelles")
+		@Test
+		void shouldOverrideZustaendigeStelles() {
+			doReturn(List.of(zustaendigeStelle)).when(mapper).getZustaendigeStelles(formData);
+
+			var result = mapper.parseFormData(formData);
+
+			assertThat(result.getZustaendigeStelles()).containsExactly(zustaendigeStelle);
+		}
+
+		@DisplayName("should keep other formdata fields")
+		@Test
+		void shouldKeepOtherFormdataFields() {
+			doReturn(formData.getZustaendigeStelles()).when(mapper).getZustaendigeStelles(formData);
+
+			var result = mapper.parseFormData(formData);
+
+			assertThat(result).usingRecursiveComparison().isEqualTo(formData);
+		}
+	}
+
+	@DisplayName("get zustaendige stelles")
+	@Nested
+	class TestGetZustaendigeStelles {
+
 		private FormData formData;
 
 		@Mock
-		private FormData formData2;
+		private Map<String, Object> fieldMap;
+
+		@Mock
+		private ZustaendigeStelle stelle1;
+
+		@Mock
+		private ZustaendigeStelle stelle2;
+
+		@Mock
+		private ZustaendigeStelle stelle3;
 
-		@DisplayName("should return adapted value")
+		@BeforeEach
+		void mock() {
+			formData = FormDataTestFactory.createBuilder()
+					.formData(fieldMap)
+					.build();
+		}
+
+		@DisplayName("should return")
 		@Test
-		void shouldReturnAdaptedValue() {
-			doReturn(formData2).when(mapper).adaptFormDataWithPossibleException(formData);
+		void shouldReturn() {
+			doReturn(emptyList()).when(mapper).getMatchingSlots(fieldMap);
 
-			var resultFormData = mapper.parseFormData(formData);
+			var result = mapper.getZustaendigeStelles(formData);
 
-			assertThat(resultFormData).isEqualTo(formData2);
+			assertThat(result).isEmpty();
 		}
 
-		@DisplayName("should return original value with exception")
+		@DisplayName("should log error for no matching identifiers")
 		@Test
-		void shouldReturnOriginalValueWithException() {
-			doThrow(new TechnicalException("some error")).when(mapper).adaptFormDataWithPossibleException(formData);
+		void shouldLogErrorForNoMatchingIdentifiers() {
+			doReturn(emptyList()).when(mapper).getMatchingSlots(fieldMap);
 
-			var resultFormData = mapper.parseFormData(formData);
+			mapper.getZustaendigeStelles(formData);
 
-			assertThat(resultFormData).isEqualTo(formData);
+			verify(mapper).logErrorForNoMatchingIdentifiers();
 		}
 
-		@DisplayName("should log warning with exception")
+		@DisplayName("should return with three zustaendige stelle")
 		@Test
-		void shouldLogWarningWithException() {
-			var exception = new TechnicalException("some error");
-			doThrow(exception).when(mapper).adaptFormDataWithPossibleException(formData);
+		void shouldReturnWithThreeZustaendigeStelle() {
+			doReturn(List.of(0, 1, 2)).when(mapper).getMatchingSlots(fieldMap);
+			doReturn(stelle1).when(mapper).getZustaendigeStelle(fieldMap, 0);
+			doReturn(stelle2).when(mapper).getZustaendigeStelle(fieldMap, 1);
+			doReturn(stelle3).when(mapper).getZustaendigeStelle(fieldMap, 2);
 
-			mapper.parseFormData(formData);
+			var result = mapper.getZustaendigeStelles(formData);
 
-			verify(mapper).logWarningForFailure(exception);
+			assertThat(result).containsExactly(stelle1, stelle2, stelle3);
 		}
 	}
 
-	@DisplayName("adapt form data with possible exception")
+	@DisplayName("get zustaendige stelle")
 	@Nested
-	class TestAdaptFormDataWithPossibleException {
+	class TestGetZustaendigeStelle {
 
-		static final String TARGET_OPTIONAL_FIELD_VALUE = "optionalFieldValue";
 		static final Map<String, Function<ZustaendigeStelle, String>> FIELD_NAME_TO_EXPECTED_VALUE_EXTRACTOR = Map.of(
 				BEZEICHNUNG_FIELD, ZustaendigeStelle::getBezeichnung,
 				EMAIL_FIELD, ZustaendigeStelle::getEmail,
@@ -162,17 +211,8 @@ class MantelantragZustaendigeStelleMapperTest {
 				HAUSANSCHRIFT_ORT_FIELD, ZustaendigeStelle::getHausanschriftOrt,
 				TELEFON_FIELD, ZustaendigeStelle::getTelefon
 		);
-		private FormData formData;
 		private Map<String, Object> fieldMap;
 
-		private static Stream<Arguments> fieldNameAndSlotIndex() {
-			return Stream.of(0, 1, 2)
-					.flatMap(slotIndex -> FIELD_NAME_TO_EXPECTED_VALUE_EXTRACTOR
-							.keySet().stream()
-							.map(fieldName -> Arguments.of(slotIndex, fieldName))
-					);
-		}
-
 		@BeforeEach
 		void mock() {
 			fieldMap = new HashMap<>(Map.of(
@@ -180,21 +220,6 @@ class MantelantragZustaendigeStelleMapperTest {
 					getOrganisationseinheitIDFieldName(2), "",
 					getOrganisationseinheitIDFieldName(10), "1111111"
 			));
-			formData = FormDataTestFactory.createBuilder()
-					.formData(fieldMap)
-					.build();
-		}
-
-		@DisplayName("should keep form data except zustaendigestelle")
-		@Test
-		void shouldKeepFormDataExceptZustaendigestelle() {
-			doReturn(10).when(mapper).findSlotIndex(fieldMap);
-
-			var resultFormData = mapper.parseFormData(formData);
-
-			assertThat(resultFormData.getId()).isEqualTo(formData.getId());
-			assertThat(resultFormData.getHeader()).isEqualTo(formData.getHeader());
-			assertThat(resultFormData.getAntragsteller()).isEqualTo(formData.getAntragsteller());
 		}
 
 		@DisplayName("should map organisationseinheitId")
@@ -203,7 +228,7 @@ class MantelantragZustaendigeStelleMapperTest {
 		void shouldMapOrganisationseinheitId(int slotIndex) {
 			mockWithOEID(slotIndex, TARGET_OEID);
 
-			var zustaendigeStelle = getAdaptedZustaendigeStelle();
+			var zustaendigeStelle = getZustaendigeStelle(slotIndex);
 
 			assertThat(zustaendigeStelle.getOrganisationseinheitenId()).isEqualTo(TARGET_OEID);
 		}
@@ -212,62 +237,60 @@ class MantelantragZustaendigeStelleMapperTest {
 			return mapper.getNameForSlotIndex(ORGANISATIONSEINHEIT_ID_FIELD, slotIndex);
 		}
 
-		@DisplayName("should throw if organistaionseinheitId is missing")
+		@DisplayName("should log warning if organistaionseinheitId is missing")
 		@ParameterizedTest
 		@ValueSource(ints = { 0, 1, 2 })
-		void shouldThrowIfOrganistationseinheitIdIsMissing(int slotIndex) {
-			doReturn(slotIndex).when(mapper).findSlotIndex(fieldMap);
+		void shouldLogWarningIfOrganistaionseinheitIdIsMissing(int slotIndex) {
+			getZustaendigeStelle(slotIndex);
 
-			assertThatThrownBy(this::getAdaptedZustaendigeStelle)
-					.isInstanceOf(TechnicalException.class);
-		}
-
-		@DisplayName("should throw if organistationseinheitId is empty")
-		@ParameterizedTest
-		@ValueSource(ints = { 0, 1, 2 })
-		void shouldThrowIfOrganistationseinheitIdIsEmpty(int slotIndex) {
-			mockWithOEID(slotIndex, "");
-
-			assertThatThrownBy(this::getAdaptedZustaendigeStelle)
-					.isInstanceOf(TechnicalException.class);
+			verify(mapper).logWarningForEmptyOrganisationseinheitId(slotIndex);
 		}
 
 		@DisplayName("should map optional field")
 		@ParameterizedTest
-		@MethodSource("fieldNameAndSlotIndex")
+		@MethodSource("generateFieldNameAndSlotIndex")
 		void shouldMapOptionalField(int slotIndex, String fieldName) {
 			mockWithSomeOEID(slotIndex);
-			fieldMap.put(mapper.getNameForSlotIndex(fieldName, slotIndex), TARGET_OPTIONAL_FIELD_VALUE);
+			var optionalFieldValue = "value of '%s'".formatted(fieldName);
+			fieldMap.put(mapper.getNameForSlotIndex(fieldName, slotIndex), optionalFieldValue);
 
-			var zustaendigeStelle = getAdaptedZustaendigeStelle();
+			var zustaendigeStelle = getZustaendigeStelle(slotIndex);
 
-			assertThat(getExpectedByFieldName(zustaendigeStelle, fieldName)).isEqualTo(TARGET_OPTIONAL_FIELD_VALUE);
+			assertThat(getExpectedValueByFieldName(zustaendigeStelle, fieldName)).isEqualTo(optionalFieldValue);
 		}
 
 		@DisplayName("should map missing optional fields to empty")
 		@ParameterizedTest
-		@MethodSource("fieldNameAndSlotIndex")
+		@MethodSource("generateFieldNameAndSlotIndex")
 		void shouldMapMissingOptionalFieldsToEmpty(int slotIndex, String fieldName) {
 			mockWithSomeOEID(slotIndex);
 
-			var zustaendigeStelle = getAdaptedZustaendigeStelle();
+			var zustaendigeStelle = getZustaendigeStelle(slotIndex);
 
-			assertThat(getExpectedByFieldName(zustaendigeStelle, fieldName)).isEmpty();
+			assertThat(getExpectedValueByFieldName(zustaendigeStelle, fieldName)).isEmpty();
 		}
 
 		@DisplayName("should map empty optional fields to empty")
 		@ParameterizedTest
-		@MethodSource("fieldNameAndSlotIndex")
+		@MethodSource("generateFieldNameAndSlotIndex")
 		void shouldMapEmptyOptionalFieldsToEmpty(int slotIndex, String fieldName) {
 			mockWithSomeOEID(slotIndex);
 			fieldMap.put(mapper.getNameForSlotIndex(fieldName, slotIndex), "");
 
-			var zustaendigeStelle = getAdaptedZustaendigeStelle();
+			var zustaendigeStelle = getZustaendigeStelle(slotIndex);
 
-			assertThat(getExpectedByFieldName(zustaendigeStelle, fieldName)).isEmpty();
+			assertThat(getExpectedValueByFieldName(zustaendigeStelle, fieldName)).isEmpty();
 		}
 
-		private String getExpectedByFieldName(ZustaendigeStelle zustaendigeStelle, String fieldName) {
+		private static Stream<Arguments> generateFieldNameAndSlotIndex() {
+			return Stream.of(0, 1, 2)
+					.flatMap(slotIndex -> FIELD_NAME_TO_EXPECTED_VALUE_EXTRACTOR
+							.keySet().stream()
+							.map(fieldName -> Arguments.of(slotIndex, fieldName))
+					);
+		}
+
+		private String getExpectedValueByFieldName(ZustaendigeStelle zustaendigeStelle, String fieldName) {
 			var valueExtractor = FIELD_NAME_TO_EXPECTED_VALUE_EXTRACTOR.get(fieldName);
 			return valueExtractor.apply(zustaendigeStelle);
 		}
@@ -278,25 +301,20 @@ class MantelantragZustaendigeStelleMapperTest {
 
 		private void mockWithOEID(int slotIndex, String targetOeid) {
 			fieldMap.put(getOrganisationseinheitIDFieldName(slotIndex), targetOeid);
-			doReturn(slotIndex).when(mapper).findSlotIndex(fieldMap);
 		}
 
-		private ZustaendigeStelle getAdaptedZustaendigeStelle() {
-			var formDataResult = mapper.adaptFormDataWithPossibleException(formData);
-			return formDataResult.getZustaendigeStelle();
+		private ZustaendigeStelle getZustaendigeStelle(int slotIndex) {
+			return mapper.getZustaendigeStelle(fieldMap, slotIndex);
 		}
 
 	}
 
-	@DisplayName("find slot index")
+	@DisplayName("get matching slots")
 	@Nested
-	class TestFindSlotIndex {
+	class TestGetMatchingSlots {
 
 		private Map<String, Object> fieldMap;
 
-		@Captor
-		private ArgumentCaptor<String> warningCaptor;
-
 		@BeforeEach
 		void mock() {
 			fieldMap = new HashMap<>(Map.of(
@@ -305,15 +323,23 @@ class MantelantragZustaendigeStelleMapperTest {
 			));
 		}
 
-		@DisplayName("should return matching slot")
+		@DisplayName("should return empty")
+		@Test
+		void shouldReturnEmpty() {
+			var resultSlotIndices = mapper.getMatchingSlots(fieldMap);
+
+			assertThat(resultSlotIndices).isEmpty();
+		}
+
+		@DisplayName("should return matching slots")
 		@ParameterizedTest
 		@ValueSource(ints = { 0, 1, 2 })
 		void shouldReturnMatchingSlot(int slotIndex) {
 			fieldMap.put(getZustaendigeStelleName(slotIndex), IDENTIFIER);
 
-			var resultSlotIndex = mapper.findSlotIndex(fieldMap);
+			var resultSlotIndices = mapper.getMatchingSlots(fieldMap);
 
-			assertThat(resultSlotIndex).isEqualTo(slotIndex);
+			assertThat(resultSlotIndices).containsExactly(slotIndex);
 		}
 
 		@DisplayName("should return matching slot with upper-/lowercase difference in identifiers")
@@ -322,33 +348,14 @@ class MantelantragZustaendigeStelleMapperTest {
 		void shouldReturnMatchingSlotWithUppercaseIdentifier(int slotIndex) {
 			fieldMap.put(getZustaendigeStelleName(slotIndex), IDENTIFIER2UPPERCASE);
 
-			var resultSlotIndex = mapper.findSlotIndex(fieldMap);
+			var resultSlotIndex = mapper.getMatchingSlots(fieldMap);
 
-			assertThat(resultSlotIndex).isEqualTo(slotIndex);
+			assertThat(resultSlotIndex).containsExactly(slotIndex);
 		}
 
 		private String getZustaendigeStelleName(int slotIndex) {
 			return mapper.getNameForSlotIndex(ZUSTELLUNG_NACHRICHTENBROKER_FIELD, slotIndex);
 		}
-
-		@DisplayName("should throw if no slot matches")
-		@Test
-		void shouldThrowIfNoSlotMatches() {
-			assertThatThrownBy(() -> mapper.findSlotIndex(fieldMap))
-					.isInstanceOf(TechnicalException.class);
-		}
-
-		@DisplayName("should log warning if multiple slots match")
-		@Test
-		void shouldLogWarningIfMultipleSlotsMatch() {
-			fieldMap.put(getZustaendigeStelleName(0), IDENTIFIER2);
-			fieldMap.put(getZustaendigeStelleName(2), IDENTIFIER);
-
-			mapper.findSlotIndex(fieldMap);
-
-			verify(mapper).logWarningForUnexpected(warningCaptor.capture());
-			assertThat(warningCaptor.getValue()).isEqualTo(mapper.getMultipleSlotsMessage(List.of(0, 2)));
-		}
 	}
 
 	@DisplayName("get name for slot index")
diff --git a/semantik-adapter/src/test/resources/mantelantrag/4620-EH6C_7d703670-15b6-42b2-8cd1-88a7e4c494b9_Antrag_Max_Mustermann_SGBXII.xml b/semantik-adapter/src/test/resources/mantelantrag/4620-EH6C_7d703670-15b6-42b2-8cd1-88a7e4c494b9_Antrag_Max_Mustermann_SGBXII.xml
index dfe5df9a75784d09bed9a8b2d7a6506822906f0f..e45f08045f677cb400a0cf815f69bc2ec9468f68 100644
--- a/semantik-adapter/src/test/resources/mantelantrag/4620-EH6C_7d703670-15b6-42b2-8cd1-88a7e4c494b9_Antrag_Max_Mustermann_SGBXII.xml
+++ b/semantik-adapter/src/test/resources/mantelantrag/4620-EH6C_7d703670-15b6-42b2-8cd1-88a7e4c494b9_Antrag_Max_Mustermann_SGBXII.xml
@@ -83,7 +83,7 @@
     <zustellung_nachrichtenbroker2>afmsh:ozg-cloud-bad-segeberg-kreis</zustellung_nachrichtenbroker2>
     <zustellung_email_ln2/>
     <zustellung_webservice2/>
-    <kontaktsystem_oeid3/>
+    <kontaktsystem_oeid3>444</kontaktsystem_oeid3>
     <OrganisationseinheitenBEZEICHNUNG3/>
     <zust_strasse3/>
     <zust_hausnummer3/>
@@ -93,7 +93,7 @@
     <zust_telefonnummer3/>
     <zust_faxnummer3/>
     <zust_emailadresse3/>
-    <zustellung_nachrichtenbroker3/>
+    <zustellung_nachrichtenbroker3>gae:ozg-cloud-itcase-test</zustellung_nachrichtenbroker3>>
     <zustellung_email_ln3/>
     <zustellung_webservice3/>
     <grund>Hilfe</grund>
diff --git a/src/main/helm/templates/deployment.yaml b/src/main/helm/templates/deployment.yaml
index c68b9d69be88de512c6cca216e756aad79d6f46f..b59bb1cc41fbfbba0098590a4986042bd510300e 100644
--- a/src/main/helm/templates/deployment.yaml
+++ b/src/main/helm/templates/deployment.yaml
@@ -79,7 +79,7 @@ spec:
         - name: ozgcloud_adapter_targetVorgangManagerName
           value: {{ (.Values.routing).targetVorgangManagerName}}
         - name: grpc_client_vorgang-manager-{{ (.Values.routing).targetVorgangManagerName}}_address
-          value: 'vorgang-manager.{{ coalesce (.Values.routing).targetNamespace .Release.Namespace }}:9090'
+          value: 'dns:///vorgang-manager.{{ coalesce (.Values.routing).targetNamespace .Release.Namespace }}:9090'
         - name: grpc_client_vorgang-manager-{{ (.Values.routing).targetVorgangManagerName}}_negotiationType
           value: {{ (.Values.routing).negotiationType | default "TLS" }}
         {{- end }}
diff --git a/src/test/helm/deployment_routing_strategy_env_test.yaml b/src/test/helm/deployment_routing_strategy_env_test.yaml
index 8ae56386a24a3f0f74e3bdb3395b2aed9f4d2be4..e70cff6f10669ad7574fb80dcbf96f3c11aee715 100644
--- a/src/test/helm/deployment_routing_strategy_env_test.yaml
+++ b/src/test/helm/deployment_routing_strategy_env_test.yaml
@@ -50,6 +50,12 @@ tests:
           content:
             name: grpc_client_vorgang-manager-vorgang-manager_negotiationType
             value: TLS
+      - contains:
+          path: spec.template.spec.containers[0].env
+          content:
+            name: grpc_client_vorgang-manager-vorgang-manager_address
+            value: dns:///vorgang-manager.sh-helm-test:9090
+
   - it: validate routing infos
     set:
       routing:
diff --git a/src/test/helm/ingress_create_or_not.yaml b/src/test/helm/ingress_create_or_not_test.yaml
similarity index 100%
rename from src/test/helm/ingress_create_or_not.yaml
rename to src/test/helm/ingress_create_or_not_test.yaml
diff --git a/src/test/helm/ingress_nginx_tests.yaml b/src/test/helm/ingress_nginx_test.yaml
similarity index 100%
rename from src/test/helm/ingress_nginx_tests.yaml
rename to src/test/helm/ingress_nginx_test.yaml
diff --git a/xta-adapter/pom.xml b/xta-adapter/pom.xml
index e96fb6c3dd46267839a27a0e6c9b19dea237b91d..8c519d2ecfa0697c6d3d6018a97aa4a697dc06a7 100644
--- a/xta-adapter/pom.xml
+++ b/xta-adapter/pom.xml
@@ -4,7 +4,7 @@
 	<parent>
 		<groupId>de.ozgcloud.eingang</groupId>
 		<artifactId>eingang-manager</artifactId>
-		<version>2.13.0-SNAPSHOT</version>
+		<version>2.15.0-SNAPSHOT</version>
 	</parent>
 	<artifactId>xta-adapter</artifactId>
 	<name>Eingangs Adapter - XTA</name>
@@ -168,6 +168,7 @@
 			</plugin>
 		</plugins>
 	</build>
+	
 	<profiles>
 		<profile>
 			<id>ci-build</id>
@@ -181,7 +182,7 @@
 								<id>build-image</id>
 								<phase>install</phase>
 								<goals>
-									<goal>build-image</goal>
+									<goal>build-image-no-fork</goal>
 								</goals>
 							</execution>
 						</executions>
diff --git a/xta-adapter/src/main/helm/templates/xta_adapter_cronjob.yaml b/xta-adapter/src/main/helm/templates/xta_adapter_cronjob.yaml
index 3835e3ec440eebbd71cdb1bb5c21bf366add83c6..761959137f507e67d20c246ec86bc7393c52a75d 100644
--- a/xta-adapter/src/main/helm/templates/xta_adapter_cronjob.yaml
+++ b/xta-adapter/src/main/helm/templates/xta_adapter_cronjob.yaml
@@ -81,7 +81,7 @@ spec:
                 - name: ozgcloud_adapter_targetVorgangManagerName
                   value: {{ (.Values.routing).targetVorgangManagerName}}
                 - name: grpc_client_vorgang-manager-{{ (.Values.routing).targetVorgangManagerName }}_address
-                  value: 'vorgang-manager.{{ coalesce (.Values.routing).targetNamespace .Release.Namespace }}:9090'
+                  value: 'dns:///vorgang-manager.{{ coalesce (.Values.routing).targetNamespace .Release.Namespace }}:9090'
                 - name: grpc_client_vorgang-manager-{{ (.Values.routing).targetVorgangManagerName }}_negotiationType
                   value: {{ (.Values.routing).negotiationType | default "PLAINTEXT" }}
                 {{- end }}
diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapper.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapper.java
index 8041810ed8fbc3222fd10c06a4e64a6a760e9bf4..891512d2f4b878594ee813dbe3cdf5d9c4bfdb4c 100644
--- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapper.java
+++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapper.java
@@ -26,10 +26,8 @@ package de.ozgcloud.eingang.xta;
 import java.util.Collection;
 import java.util.List;
 import java.util.Objects;
-import java.util.function.Predicate;
 import java.util.stream.Stream;
 
-import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
 import org.springframework.stereotype.Component;
 
 import de.ozgcloud.eingang.common.formdata.IncomingFile;
@@ -44,14 +42,11 @@ class XtaIncomingFilesMapper {
 
 	private final ZipFileExtractor zipFileExtractor;
 
-	public static final String ZIP_CONTENT_TYPE = "application/zip";
-	static final Predicate<IncomingFile> IS_ZIP_FILE = contentType -> ZIP_CONTENT_TYPE.equals(contentType.getContentType());
-
 	public List<IncomingFile> toIncomingFiles(Collection<XtaFile> messageFiles) {
 		if (Objects.nonNull(messageFiles)) {
 			return messageFiles.stream()
 					.map(this::toIncomingFile)
-					.flatMap(this::extractZip)
+					.flatMap(this::tryToExtractZip)
 					.toList();
 		}
 		return List.of();
@@ -66,16 +61,11 @@ class XtaIncomingFilesMapper {
 				.build();
 	}
 
-	Stream<IncomingFile> extractZip(IncomingFile incomingFile) {
-		if (IS_ZIP_FILE.test(incomingFile)) {
-			try {
-				List<IncomingFile> extractedZips = zipFileExtractor.extractIncomingFilesSafely(incomingFile);
-				return extractedZips.stream();
-			} catch (RuntimeException e) {
-				LOG.error("Cannot read source ZIP. Not extracting file", e);
-				return Stream.of(incomingFile);
-			}
-		} else {
+	Stream<IncomingFile> tryToExtractZip(IncomingFile incomingFile) {
+		try {
+			List<IncomingFile> extractedZips = zipFileExtractor.extractIncomingFilesSafely(incomingFile);
+			return extractedZips.stream();
+		} catch (RuntimeException e) {
 			return Stream.of(incomingFile);
 		}
 	}
diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessage.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessage.java
index bb048d1c60c284da67062008acfdb6d5b1972281..2f51bd853ba2b95d58481319c083bc20f089c94f 100644
--- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessage.java
+++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessage.java
@@ -9,6 +9,8 @@ import lombok.Singular;
 @Builder(toBuilder = true)
 @Getter
 public class XtaMessage {
+	private String primaryFormDataMessage;
+
 	private XtaMessageMetaData metaData;
 	@Singular
 	private Collection<XtaFile> messageFiles;
diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java
index 09d353faf28d73111a2696cfc89e47978f9d07b4..7fb082ce762666db56da08c5734d9517738ef1a0 100644
--- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java
+++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMapper.java
@@ -1,15 +1,18 @@
 package de.ozgcloud.eingang.xta;
 
+import java.util.Optional;
+
 import org.mapstruct.Context;
 import org.mapstruct.Mapper;
 import org.mapstruct.Mapping;
 
 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;
 
-@Mapper(imports = {FilesMapperHelper.class, XtaMapperHelper.class})
+@Mapper(imports = { FilesMapperHelper.class, XtaMapperHelper.class })
 interface XtaMessageMapper {
 	int VORGANG_NUMMER_SUFFIX_LENGTH = 4;
 
@@ -22,6 +25,7 @@ interface XtaMessageMapper {
 	@Mapping(target = "numberOfRepresentations", dependsOn = "representations", expression = "java(representationsAttachmentsPair.representations().size())")
 	@Mapping(target = "representation", ignore = true)
 	@Mapping(target = "attachment", ignore = true)
+	@Mapping(target = "control.metaData", source = "metaData")
 	FormData toFormData(RepresentationsAttachmentsPair representationsAttachmentsPair, XtaMessageMetaData metaData,
 			@Context VorgangNummerSupplier vorgangNummerSupplier);
 
@@ -39,4 +43,8 @@ interface XtaMessageMapper {
 	default String fromId(XtaMessageId id) {
 		return id.toString();
 	}
+
+	default Optional<FormMetaData> mapMetaData(XtaMessageMetaData value) {
+		return Optional.ofNullable(value);
+	}
 }
diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaData.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaData.java
index 66d4ed8d011521b3895e738a3eaf7d91b35af8fa..84fc3290bd1420e24750706a3a073cca4801ea2a 100644
--- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaData.java
+++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaData.java
@@ -2,19 +2,58 @@ package de.ozgcloud.eingang.xta;
 
 import java.time.ZonedDateTime;
 
+import de.ozgcloud.eingang.common.formdata.FormMetaData;
+import de.ozgcloud.eingang.common.formdata.IncomingFile;
 import lombok.Builder;
 import lombok.Getter;
+import lombok.ToString;
 
 @Builder
 @Getter
-class XtaMessageMetaData {
+@ToString
+class XtaMessageMetaData implements FormMetaData {
+	static final String SERVICE = "service";
+	static final String MESSAGE_TYPE_ENTRY_NAME = "messageType";
+	static final String MESSAGE_TYPE_LIST_VERSION = "messageTypeListVersion";
+	static final String MESSAGE_ID_ENTRY_NAME = "messageId";
+	static final String XTA_IDENTIFIER_ENTRY_NAME = "xtaIdentifier";
+
 	// MsgIdentification.MessageId
 	private XtaMessageId messageId;
+
 	// DeliveryAttributes.origin
 	private ZonedDateTime origin;
 	// DeliveryAttributes.delivery
 	private ZonedDateTime delivery;
+
 	// Qualifier.MessageType.code
 	private String messageType;
+	// Qualifier.MessageType.listVersion
+	private String messageTypeListVersion;
+	// Qualifier.Service
+	private String service;
+
+	private String xtaIdentifier;
+
+	private IncomingFile metaDataFile;
+
+	@Override
+	public String getEntry(String name) {
+		switch (name) {
+		case MESSAGE_TYPE_ENTRY_NAME:
+			return getMessageType();
+		case MESSAGE_TYPE_LIST_VERSION:
+			return getMessageTypeListVersion();
+		case MESSAGE_ID_ENTRY_NAME:
+			return getMessageId().toString();
+		case XTA_IDENTIFIER_ENTRY_NAME:
+			return getXtaIdentifier();
+		case SERVICE:
+			return getService();
+
+		default:
+			return null;
+		}
+	}
 
 }
diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapper.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapper.java
index 2cb772154e77246a41508a0116dd6db7f9cf9cae..f5566e157a78701db29b3ca828e1e9e8fdcb5cef 100644
--- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapper.java
+++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapper.java
@@ -13,10 +13,14 @@ import eu.osci.ws._2014._10.transport.MessageMetaData;
 @Mapper
 interface XtaMessageMetaDataMapper {
 
+	@Mapping(target = "messageTypeListVersion", ignore = true)
+	@Mapping(target = "metaDataFile", ignore = true)
+	@Mapping(target = "service", ignore = true)
 	@Mapping(target = "origin", source = "deliveryAttributes.origin")
 	@Mapping(target = "delivery", source = "deliveryAttributes.delivery")
 	@Mapping(target = "messageId", source = "msgIdentification.messageID.value")
 	@Mapping(target = "messageType", source = "qualifier.messageType.code")
+	@Mapping(target = "xtaIdentifier", source = "destinations.reader.identifier.value")
 	XtaMessageMetaData fromSoap(MessageMetaData metaData);
 
 	default XtaMessageId fromString(String id) {
diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaRemoteService.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaRemoteService.java
index c1d3ecfb782a7e0f42f2feab9cadb78b621ff15c..a837c55d3c1670242f12ea891542be116052e09f 100644
--- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaRemoteService.java
+++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaRemoteService.java
@@ -94,7 +94,6 @@ class XtaRemoteService {
 	}
 
 	MsgStatusListTypeAndHeaderResponse getGenericStatusList(Object request) {
-
 		var template = webServiceTemplateBuilder.setMarshaller(osciMarshaller).setUnmarshaller(osciMarshaller).build();
 
 		return template.sendAndReceive(buildMarshalCallBack(request, buildActionCallback()), buildHeaderExtractor());
@@ -183,10 +182,12 @@ class XtaRemoteService {
 
 	public XtaMessage getMessage(XtaMessageId messageId) {
 		var contentContainer = loadContentContainer(messageId.toString());
+		XtaFile formDataFile = getMessage(contentContainer);
 
 		return XtaMessage.builder()
 				.metaData(null)
-				.messageFiles(Collections.singleton(getMessage(contentContainer)))
+				.primaryFormDataMessage(formDataFile.name())
+				.messageFiles(Collections.singleton(formDataFile))
 				.attachments(getAttachments(contentContainer).toList())
 				.build();
 	}
diff --git a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaService.java b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaService.java
index d5a8d537c84074c7a8bd5849fd744b320eeb3820..500e78da873a6acfc55c01a880f4ec953a875d4a 100644
--- a/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaService.java
+++ b/xta-adapter/src/main/java/de/ozgcloud/eingang/xta/XtaService.java
@@ -4,6 +4,7 @@ import static java.util.Collections.*;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Optional;
 import java.util.Spliterators;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
@@ -15,6 +16,7 @@ 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;
@@ -44,7 +46,10 @@ class XtaService {
 	private XtaCurrentIdentifierService service;
 
 	public Stream<FormData> getMessages() {
-		return createXtaMessageStream().filter(this::isSupportedMessageType).map(this::getFormData);
+		return createXtaMessageStream()
+				.filter(this::isSupportedMessageType)
+				.map(this::getFormDataIfNoRuntimeException)
+				.flatMap(Optional::stream);
 	}
 
 	Stream<XtaMessageMetaData> createXtaMessageStream() {
@@ -66,13 +71,38 @@ class XtaService {
 		return false;
 	}
 
-	public FormData getFormData(@NonNull XtaMessageMetaData metaData) {
+	Optional<FormData> getFormDataIfNoRuntimeException(@NonNull XtaMessageMetaData metaData) {
+		try {
+			return Optional.of(getFormData(metaData));
+		} catch (RuntimeException exception) {
+			LOG.error("Failed to process xta message (id: %s)".formatted(metaData.getMessageId()), exception);
+			return Optional.empty();
+		}
+	}
+
+	FormData getFormData(@NonNull XtaMessageMetaData metaData) {
 		var msg = remoteService.getMessage(metaData.getMessageId());
 		var incomingFiles = xtaIncomingFilesMapper.toIncomingFiles(msg.getMessageFiles());
 		var representationsAttachmentsPair = getRepresentationsAttachmentsPair(metaData, incomingFiles);
 
 		var formData = mapper.toFormData(representationsAttachmentsPair, metaData, vorgangNummerSupplier);
-		return addAttachments(msg, formData);
+		formData = addAttachments(msg, formData);
+
+		return addRepresentations(formData, msg);
+	}
+
+	FormData addRepresentations(FormData formData, XtaMessage msg) {
+		return formData.toBuilder().control(
+				formData.getControl().toBuilder()
+						.representations(Optional.of(buildRepresentations(formData.getControl().getRepresentations(), msg)))
+						.build())
+				.build();
+	}
+
+	private Representations buildRepresentations(Optional<Representations> base, XtaMessage msg) {
+		return base.map(Representations::toBuilder).orElseGet(Representations::builder)
+				.primaryFormDataRepresentation(msg.getPrimaryFormDataMessage())
+				.build();
 	}
 
 	FormData addAttachments(XtaMessage msg, FormData inFormData) {
diff --git a/xta-adapter/src/test/helm/xta_adapter_cronjob_env_test.yaml b/xta-adapter/src/test/helm/xta_adapter_cronjob_env_test.yaml
index 77547800e84d3f8f60fe508c57df9e5f7d0a0de6..e247e20d6703fa518cf1eb74616e5447f4fd8a2e 100644
--- a/xta-adapter/src/test/helm/xta_adapter_cronjob_env_test.yaml
+++ b/xta-adapter/src/test/helm/xta_adapter_cronjob_env_test.yaml
@@ -107,7 +107,7 @@ tests:
           path: spec.jobTemplate.spec.template.spec.containers[0].env
           content:
             name: grpc_client_vorgang-manager-vorgang-manager_address
-            value: 'vorgang-manager.helm-test:9090'
+            value: 'dns:///vorgang-manager.helm-test:9090'
       - contains:
           path: spec.jobTemplate.spec.template.spec.containers[0].env
           content:
@@ -152,7 +152,7 @@ tests:
           path: spec.jobTemplate.spec.template.spec.containers[0].env
           content:
             name: grpc_client_vorgang-manager-vorgang-manager_address
-            value: 'vorgang-manager.helm-test:9090'
+            value: 'dns:///vorgang-manager.helm-test:9090'
       - contains:
           path: spec.jobTemplate.spec.template.spec.containers[0].env
           content:
diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapperTest.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapperTest.java
index 1ae7d692986e14c57e983b2af836c8b637c33c92..8adbed4598d7224e121e0d723c6c29baf0456361 100644
--- a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapperTest.java
+++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaIncomingFilesMapperTest.java
@@ -27,10 +27,8 @@ import static org.assertj.core.api.Assertions.*;
 import static org.mockito.Mockito.*;
 
 import java.util.List;
-import java.util.UUID;
 import java.util.stream.Stream;
 
-import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.mockito.InjectMocks;
@@ -49,8 +47,6 @@ class XtaIncomingFilesMapperTest {
 	@Mock
 	private ZipFileExtractor extractor;
 
-	private static final String ZIP_CONTENT_TYPE = "application/zip";
-
 	@Nested
 	class TestToIncomingFiles {
 
@@ -59,12 +55,12 @@ class XtaIncomingFilesMapperTest {
 			var xtaFile = XtaFileTestFactory.create();
 			var incomingFile = IncomingFileTestFactory.create();
 			when(mapper.toIncomingFile(xtaFile)).thenReturn(incomingFile);
-			when(mapper.extractZip(incomingFile)).thenAnswer(x -> Stream.of(incomingFile));
+			when(mapper.tryToExtractZip(incomingFile)).thenAnswer(x -> Stream.of(incomingFile));
 
 			mapper.toIncomingFiles(List.of(xtaFile, xtaFile));
 
 			inOrder(mapper).verify(mapper, calls(2)).toIncomingFile(xtaFile);
-			inOrder(mapper).verify(mapper, calls(2)).extractZip(incomingFile);
+			inOrder(mapper).verify(mapper, calls(2)).tryToExtractZip(incomingFile);
 		}
 
 		@Test
@@ -107,7 +103,7 @@ class XtaIncomingFilesMapperTest {
 	}
 
 	@Nested
-	class TestExtractZip {
+	class TestTryToExtractZip {
 
 		@Mock
 		IncomingFile outFile1;
@@ -115,40 +111,29 @@ class XtaIncomingFilesMapperTest {
 		@Mock
 		IncomingFile outFile2;
 
+		private final IncomingFile zipFile = IncomingFileTestFactory.createBuilder()
+				.name("attachments.zip")
+				.build();
 
 		@Test
 		void shouldExtractZipFiles() {
 			var expectedExtractedFiles = List.of(outFile1, outFile2);
-			var zipFile = createTestIncomingFile();
 			when(extractor.extractIncomingFilesSafely(zipFile)).thenReturn(expectedExtractedFiles);
 
-			var extractedFiles = mapper.extractZip(zipFile).toList();
+			var extractedFiles = mapper.tryToExtractZip(zipFile).toList();
 
 			assertThat(extractedFiles).isEqualTo(expectedExtractedFiles);
 		}
 
-		IncomingFile createTestIncomingFile() {
-			return IncomingFileTestFactory.createBuilder()
-					.name("attachments.zip")
-					.contentType(ZIP_CONTENT_TYPE)
-					.build();
-		}
-
 		@Test
 		void shouldIgnoreNonZipFiles() {
+			when(extractor.extractIncomingFilesSafely(zipFile)).thenThrow(new RuntimeException());
 			var incomingFile = IncomingFileTestFactory.create();
 
-			var extractedFiles = mapper.extractZip(incomingFile).toList();
+			var extractedFiles = mapper.tryToExtractZip(incomingFile).toList();
 
 			assertThat(extractedFiles).containsExactly(incomingFile);
 		}
 	}
 
-	@Test
-	void testIsZipFilePredicate() {
-		assertThat(XtaIncomingFilesMapper.IS_ZIP_FILE.test(IncomingFileTestFactory.create())).isFalse();
-		assertThat(XtaIncomingFilesMapper.IS_ZIP_FILE.test(IncomingFileTestFactory.createBuilder().contentType(ZIP_CONTENT_TYPE).build()))
-				.isTrue();
-	}
-
 }
diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMapperTest.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMapperTest.java
index 83d1dc8f4fee83ad384db085315e9fbcc37cd075..23a2f984e0b91d38e35e63c3d2d73efd8cd69733 100644
--- a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMapperTest.java
+++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMapperTest.java
@@ -13,6 +13,7 @@ import org.mockito.Mock;
 import org.mockito.Spy;
 
 import de.ozgcloud.eingang.common.formdata.FormData;
+import de.ozgcloud.eingang.common.formdata.FormMetaDataTestFactory;
 import de.ozgcloud.eingang.common.vorgang.VorgangNummerSupplier;
 
 class XtaMessageMapperTest {
@@ -86,6 +87,14 @@ class XtaMessageMapperTest {
 			assertThat(formData.getHeader().getFormEngineName()).isEqualTo(FormHeaderTestFactory.XDOMEA_FORM_ENGINE_NAME);
 		}
 
+		@Test
+		void shouldSetDesinationId() {
+			var formData = doMapping();
+
+			assertThat(formData.getControl().getMetaData()).isPresent().get()
+					.extracting(metaData -> metaData.getEntry(XtaMessageMetaData.XTA_IDENTIFIER_ENTRY_NAME))
+					.isEqualTo(FormMetaDataTestFactory.XTA_IDENTIFIER);
+		}
 
 		private FormData doMapping() {
 			return mapper.toFormData(representationsAttachmentsPair, xtaMessageMetaData, vorgangNummerSupplier);
@@ -95,7 +104,6 @@ class XtaMessageMapperTest {
 	@Nested
 	class TestToFimFormData {
 
-
 		private XtaMessageMetaData xtaMessageMetaData;
 		private RepresentationsAttachmentsPair representationsAttachmentsPair;
 
@@ -108,7 +116,7 @@ class XtaMessageMapperTest {
 
 		@Test
 		void shouldSetFormEngineName() {
-			var formData =  mapper.toFormData(representationsAttachmentsPair, xtaMessageMetaData, vorgangNummerSupplier);
+			var formData = mapper.toFormData(representationsAttachmentsPair, xtaMessageMetaData, vorgangNummerSupplier);
 
 			assertThat(formData.getHeader().getFormEngineName()).isEqualTo(FormHeaderTestFactory.FIM_FORM_ENGINE_NAME);
 		}
diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapperTest.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapperTest.java
index 26f1ef8d1c76ea3a17eb9b6031c3df7d5d1e54d9..1233e71346ca304904f22fb36108bae6731bb3d1 100644
--- a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapperTest.java
+++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataMapperTest.java
@@ -2,8 +2,6 @@ package de.ozgcloud.eingang.xta;
 
 import static org.assertj.core.api.Assertions.*;
 
-import java.math.BigInteger;
-
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
@@ -21,7 +19,7 @@ class XtaMessageMetaDataMapperTest {
 
 		@Test
 		void shouldMap() {
-			var response = MsgStatusListTypeAndHeaderResponseTestFactory.createBuilder().build();
+			var response = MsgStatusListTypeAndHeaderResponseTestFactory.create();
 
 			var result = mapper.msgStatusListFromSoap(response);
 
@@ -31,7 +29,7 @@ class XtaMessageMetaDataMapperTest {
 		@DisplayName("should set moreMessagesAvailable to false")
 		@Test
 		void shouldSetMoreMessagesAvailableToFalse() {
-			var response = MsgStatusListTypeAndHeaderResponseTestFactory.createBuilder().build();
+			var response = MsgStatusListTypeAndHeaderResponseTestFactory.create();
 
 			var result = mapper.msgStatusListFromSoap(response);
 
diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataTestFactory.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataTestFactory.java
index fbe07498eb8d3435d1c739a268ace2273bc133ac..5ee03139664cf766ba09ac8adc3e95d59e2fc246 100644
--- a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataTestFactory.java
+++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageMetaDataTestFactory.java
@@ -4,11 +4,15 @@ import static de.ozgcloud.eingang.xta.XtaMessageTestFactory.*;
 
 import java.time.ZonedDateTime;
 
+import de.ozgcloud.eingang.common.formdata.FormMetaDataTestFactory;
+
 class XtaMessageMetaDataTestFactory {
 
 	static final String MESSAGE_TYPE = "Geschaeftsgang.Geschaeftsgang.0201";
 	static final String FIM_MESSAGE_TYPE = "fim.S17000652.17000652001004";
 	static final ZonedDateTime ORIGIN = ZonedDateTime.parse("2022-10-29T15:45:52.4942149+02:00");
+	static final String SERVICE = "urn:fim:Versammlungsanzeige:1.4";
+	static final String MESSAGE_TYPE_LIST_VERSION = "1.0";
 
 	static XtaMessageMetaData create() {
 		return createBuilder().build();
@@ -18,7 +22,10 @@ class XtaMessageMetaDataTestFactory {
 		return XtaMessageMetaData.builder()
 				.messageId(MESSAGE_ID)
 				.messageType(MESSAGE_TYPE)
-				.origin(ORIGIN);
+				.messageTypeListVersion(MESSAGE_TYPE_LIST_VERSION)
+				.origin(ORIGIN)
+				.xtaIdentifier(FormMetaDataTestFactory.XTA_IDENTIFIER)
+				.service(SERVICE);
 	}
 
 	static XtaMessageMetaData createFim() {
@@ -26,9 +33,7 @@ class XtaMessageMetaDataTestFactory {
 	}
 
 	static XtaMessageMetaData.XtaMessageMetaDataBuilder createFimBuilder() {
-		return XtaMessageMetaData.builder()
-				.messageId(MESSAGE_ID)
-				.messageType(FIM_MESSAGE_TYPE)
-				.origin(ORIGIN);
+		return createBuilder()
+				.messageType(FIM_MESSAGE_TYPE);
 	}
 }
diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageTestFactory.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageTestFactory.java
index 6c8597cc38fd795a311ad8d3a70e64a5c24c6347..1a1397db1e1bae3588ef81e7162f8c80308b2283 100644
--- a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageTestFactory.java
+++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaMessageTestFactory.java
@@ -5,6 +5,7 @@ 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() {
 		return createBuilder().build();
@@ -14,6 +15,7 @@ class XtaMessageTestFactory {
 		return XtaMessage.builder()
 				.metaData(XtaMessageMetaDataTestFactory.create())
 				.messageFile(XtaFileTestFactory.create())
+				.primaryFormDataMessage(XtaFileTestFactory.NAME)
 				.attachment(attachment);
 	}
 }
diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaRemoteServiceITCase.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaRemoteServiceFunctionalCase.java
similarity index 100%
rename from xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaRemoteServiceITCase.java
rename to xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaRemoteServiceFunctionalCase.java
diff --git a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java
index 374d71632023fb10b42f1698b4b7c44d1e462445..effc877a5d5045273819eef3e441eb6893da1f02 100644
--- a/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java
+++ b/xta-adapter/src/test/java/de/ozgcloud/eingang/xta/XtaServiceTest.java
@@ -6,6 +6,7 @@ import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 
 import java.util.List;
+import java.util.Optional;
 import java.util.stream.Stream;
 
 import org.junit.jupiter.api.BeforeEach;
@@ -20,6 +21,8 @@ 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;
@@ -49,52 +52,93 @@ class XtaServiceTest {
 	@Mock
 	private XtaCurrentIdentifierService currentIdentifierService;
 
+	@Mock
+	private FormData formData;
+
+	@Mock
+	private FormData formData2;
+
 	@Nested
 	class TestGetMessagesAsFormData {
 
 		private final XtaMessageMetaData messageMetaData = XtaMessageMetaDataTestFactory.create();
 		private final XtaMessage message = XtaMessageTestFactory.create();
 
-		@BeforeEach
-		void setup() {
-			doReturn(Stream.of(messageMetaData)).when(service).createXtaMessageStream();
-		}
+		@DisplayName("with one message")
+		@Nested
+		class TestWithOneMessage {
+			@BeforeEach
+			void setup() {
+				doReturn(Stream.of(messageMetaData)).when(service).createXtaMessageStream();
+			}
 
-		@Test
-		void shouldCallCreateStream() {
-			service.getMessages();
+			@Test
+			void shouldCallCreateStream() {
+				service.getMessages();
 
-			verify(service).createXtaMessageStream();
-		}
+				verify(service).createXtaMessageStream();
+			}
 
-		@Test
-		void shouldCallFilterByMessageType() {
-			setupMocks();
+			@Test
+			void shouldCallFilterByMessageType() {
+				setupMocks();
 
-			service.getMessages().toList();
+				service.getMessages().toList();
 
-			verify(service).isSupportedMessageType(messageMetaData);
-		}
+				verify(service).isSupportedMessageType(messageMetaData);
+			}
 
-		@Test
-		void shouldCallGetFormData() {
-			setupMocks();
-			doReturn(true).when(service).isSupportedMessageType(messageMetaData);
+			@Test
+			void shouldCallGetFormDataIfNoRuntimeException() {
+				setupMocks();
+				doReturn(true).when(service).isSupportedMessageType(messageMetaData);
 
-			service.getMessages().toList();
+				service.getMessages().toList();
 
-			verify(service).getFormData(messageMetaData);
+				verify(service).getFormData(messageMetaData);
+			}
+
+			@Test
+			void shouldNotCallGetFormDataIfNoRuntimeException() {
+				doReturn(false).when(service).isSupportedMessageType(messageMetaData);
+
+				service.getMessages().toList();
+
+				verify(service, never()).getFormDataIfNoRuntimeException(any());
+			}
 		}
 
-		@Test
-		void shouldNotCallGetFormData() {
-			doReturn(false).when(service).isSupportedMessageType(messageMetaData);
+		@DisplayName("with multiple messages")
+		@Nested
+		class TestWithMultipleMessages {
+			private final XtaMessageMetaData messageMetaData2 = XtaMessageMetaDataTestFactory.createBuilder()
+					.messageId(XtaMessageId.from("messageId2"))
+					.build();
+			private final XtaMessageMetaData messageMetaData3 = XtaMessageMetaDataTestFactory.createBuilder()
+					.messageId(XtaMessageId.from("messageId3"))
+					.build();
+
+			@BeforeEach
+			void setup() {
+				doReturn(Stream.of(messageMetaData, messageMetaData2, messageMetaData3)).when(service).createXtaMessageStream();
+			}
+
+			@DisplayName("should return stream of messages")
+			@Test
+			void shouldReturnStreamOfMessages() {
+				doReturn(true).when(service).isSupportedMessageType(messageMetaData);
+				doReturn(false).when(service).isSupportedMessageType(messageMetaData3);
+				doReturn(true).when(service).isSupportedMessageType(messageMetaData2);
+				doReturn(Optional.of(formData)).when(service).getFormDataIfNoRuntimeException(messageMetaData);
+				doReturn(Optional.of(formData2)).when(service).getFormDataIfNoRuntimeException(messageMetaData2);
 
-			service.getMessages().toList();
+				var result = service.getMessages().toList();
 
-			verify(service, never()).getFormData(any());
+				assertThat(result).containsExactly(formData, formData2);
+			}
 		}
 
+
 		private void setupMocks() {
 			var testFormData = FormDataTestFactory.create();
 			when(mapper.toFormData(any(), any(), eq(vorgangNummerSupplier))).thenReturn(testFormData);
@@ -129,6 +173,53 @@ class XtaServiceTest {
 		}
 	}
 
+	@DisplayName("get form data if no runtime exception")
+	@Nested
+	class TestGetFormDataIfNoRuntimeException {
+
+		@Mock
+		XtaMessageMetaData messageMetaData;
+
+		@Mock
+		FormData formData;
+
+		@DisplayName("should call get formdata")
+		@Test
+		void shouldCallGetFormdata() {
+			service.getFormDataIfNoRuntimeException(messageMetaData);
+
+			verify(service).getFormData(messageMetaData);
+		}
+
+		@DisplayName("with exception")
+		@Nested
+		class TestWithException {
+			@DisplayName("should return empty")
+			@Test
+			void shouldReturnEmpty() {
+				doThrow(new RuntimeException("test-error")).when(service).getFormData(any());
+
+				var result = service.getFormDataIfNoRuntimeException(messageMetaData);
+
+				assertThat(result).isEmpty();
+			}
+		}
+
+		@DisplayName("without exception")
+		@Nested
+		class TestWithoutException {
+			@DisplayName("should return")
+			@Test
+			void shouldReturn() {
+				doReturn(formData).when(service).getFormData(any());
+
+				var result = service.getFormDataIfNoRuntimeException(messageMetaData);
+
+				assertThat(result).contains(formData);
+			}
+		}
+	}
+
 	@Nested
 	class TestGetFormData {
 
@@ -192,7 +283,7 @@ class XtaServiceTest {
 
 		@Test
 		void shouldReturnMappedResult() {
-			doReturn(mappedFormData).when(service).addAttachments(any(), any());
+			doReturn(mappedFormData).when(service).addRepresentations(any(), any());
 
 			var result = service.getFormData(messageMetaData);
 
@@ -353,4 +444,28 @@ class XtaServiceTest {
 		}
 	}
 
+	@Nested
+	class TestAddRepresentations {
+		@Test
+		void shouldAddPrimaryRepresentation() {
+			var result = service.addRepresentations(FormDataTestFactory.create(), XtaMessageTestFactory.create());
+
+			assertThat(result.getControl().getRepresentations()).isPresent().get()
+					.extracting(Representations::getPrimaryFormDataRepresentation).isEqualTo(XtaMessageTestFactory.PRIMARY_FORM_DATA_MESSAGE);
+		}
+
+		@Test
+		void shouldRespectExistingRepresentation() {
+			var formData = FormDataTestFactory.createBuilder().control(FormDataControlTestFactory.createBuilder()
+					.representations(Optional.of(
+							Representations.builder().primaryFormDataPdfRepresentation("PDF_FILE").build()))
+					.build()).build();
+
+			var result = service.addRepresentations(formData, XtaMessageTestFactory.create());
+
+			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");
+		}
+	}
 }