diff --git a/forwarder/src/main/java/de/ozgcloud/eingang/forwarder/EingangStubReceiverStreamObserver.java b/forwarder/src/main/java/de/ozgcloud/eingang/forwarder/EingangStubReceiverStreamObserver.java
index 5c9f3d4ad29bf0fd09c57784300b28afb1bea20f..d5f1aa22a54acee33d98a9212725616fbae03111 100644
--- a/forwarder/src/main/java/de/ozgcloud/eingang/forwarder/EingangStubReceiverStreamObserver.java
+++ b/forwarder/src/main/java/de/ozgcloud/eingang/forwarder/EingangStubReceiverStreamObserver.java
@@ -103,14 +103,14 @@ public class EingangStubReceiverStreamObserver implements StreamObserver<GrpcRou
 		}
 	}
 
-	private void handleRouteForwarding(GrpcRouteForwarding routeForwarding) {
+	void handleRouteForwarding(GrpcRouteForwarding routeForwarding) {
 		if (Objects.nonNull(formData)) {
 			throw new IllegalStateException("Received second RouteForwarding. Send only one per request.");
 		}
 		formData = routeForwardingMapper.toFormData(routeForwarding);
 	}
 
-	private void handleAttachment(GrpcAttachment attachment) {
+	void handleAttachment(GrpcAttachment attachment) {
 		if (attachment.hasFile()) {
 			setCurrentMetadata(incomingFileMapper.fromGrpcAttachmentFile(attachment.getFile()));
 			groupName = Optional.of(attachment.getFile().getGroupName());
@@ -119,7 +119,7 @@ public class EingangStubReceiverStreamObserver implements StreamObserver<GrpcRou
 		}
 	}
 
-	private void handleRepresentation(GrpcRepresentation representation) {
+	void handleRepresentation(GrpcRepresentation representation) {
 		if (representation.hasFile()) {
 			setCurrentMetadata(incomingFileMapper.fromGrpcRepresentationFile(representation.getFile()));
 		} else {
@@ -128,21 +128,21 @@ public class EingangStubReceiverStreamObserver implements StreamObserver<GrpcRou
 
 	}
 
-	private void setCurrentMetadata(IncomingFile metaData) {
+	void setCurrentMetadata(IncomingFile metaData) {
 		if (Objects.nonNull(currentFile)) {
-			throw new TechnicalException("Received additional file before previos file reached the end.");
+			throw new IllegalStateException("Received additional file before previos file reached the end.");
 		}
 		currentFile = metaData;
 	}
 
-	private void handleFileContent(GrpcFileContent fileContent) {
+	void handleFileContent(GrpcFileContent fileContent) {
 		if (Objects.isNull(receivingFileContent)) {
 			initContentReceiving();
 		}
 		storeFileContent(fileContent);
 	}
 
-	private void initContentReceiving() {
+	void initContentReceiving() {
 		try {
 			pipedInput = new PipedInputStream(CHUNK_SIZE);
 			pipedOutput = new PipedOutputStream(pipedInput);
@@ -152,9 +152,9 @@ public class EingangStubReceiverStreamObserver implements StreamObserver<GrpcRou
 		}
 	}
 
-	private void storeFileContent(GrpcFileContent content) {
+	void storeFileContent(GrpcFileContent content) {
 		if (Objects.isNull(currentFile)) {
-			throw new TechnicalException("File content received before metadata.");
+			throw new IllegalStateException("File content received before metadata.");
 		}
 		try {
 			pipedOutput.write(content.getContent().toByteArray());
@@ -166,14 +166,16 @@ public class EingangStubReceiverStreamObserver implements StreamObserver<GrpcRou
 		}
 	}
 
-	private void handleEndOfFile() {
+	void handleEndOfFile() {
 		closeOutputPipe();
 		var completedIncomingFile = currentFile.toBuilder().file(getSavedFileContent()).build();
-		groupName.map(group -> attachments.get(group)).orElse(representations).add(completedIncomingFile);
+		groupName.map(group -> attachments.computeIfAbsent(group, s -> new ArrayList<IncomingFile>()))
+				.orElse(representations)
+				.add(completedIncomingFile);
 		resetFileReceiving();
 	}
 
-	private File getSavedFileContent() {
+	File getSavedFileContent() {
 		try {
 			return receivingFileContent.get(TIMEOUT_MINUTES, TimeUnit.MINUTES);
 		} catch (ExecutionException | TimeoutException e) {
@@ -186,7 +188,7 @@ public class EingangStubReceiverStreamObserver implements StreamObserver<GrpcRou
 		}
 	}
 
-	private void resetFileReceiving() {
+	void resetFileReceiving() {
 		currentFile = null;
 		groupName = Optional.empty();
 		pipedOutput = null;
@@ -201,11 +203,11 @@ public class EingangStubReceiverStreamObserver implements StreamObserver<GrpcRou
 		closeInputPipe();
 	}
 
-	private void closeOutputPipe() {
+	void closeOutputPipe() {
 		IOUtils.closeQuietly(pipedOutput, e -> LOG.error("Cannot close output stream.", e));
 	}
 
-	private void closeInputPipe() {
+	void closeInputPipe() {
 		IOUtils.closeQuietly(pipedInput, e -> LOG.error("Cannot close input stream.", e));
 	}
 
@@ -215,13 +217,15 @@ public class EingangStubReceiverStreamObserver implements StreamObserver<GrpcRou
 		responseConsumer.accept(GrpcRouteForwardingResponse.getDefaultInstance());
 	}
 
-	private FormData assembleFormData() {
+	FormData assembleFormData() {
 		if (Objects.isNull(formData)) {
 			throw new IllegalStateException("Never received RouteForwarding containing EingangStub and RouteCriteria.");
 		}
 		return formData.toBuilder()
 				.representations(representations)
 				.attachments(attachments.entrySet().stream().map(incomingFileGroupMapper::fromMapEntry).toList())
+				.numberOfAttachments(attachments.size())
+				.numberOfRepresentations(representations.size())
 				.build();
 	}
 
diff --git a/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/EingangStubReceiverStreamObserverTest.java b/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/EingangStubReceiverStreamObserverTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f4bacd0b2c16dc6db7749bfe7a49e6b20473aebf
--- /dev/null
+++ b/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/EingangStubReceiverStreamObserverTest.java
@@ -0,0 +1,1024 @@
+/*
+ * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
+ * Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei
+ * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.ozgcloud.eingang.forwarder;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeoutException;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+import org.springframework.test.util.ReflectionTestUtils;
+
+import de.ozgcloud.common.errorhandling.TechnicalException;
+import de.ozgcloud.eingang.common.formdata.FormData;
+import de.ozgcloud.eingang.common.formdata.FormDataTestFactory;
+import de.ozgcloud.eingang.common.formdata.IncomingFile;
+import de.ozgcloud.eingang.common.formdata.IncomingFileGroupTestFactory;
+import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory;
+import de.ozgcloud.eingang.forwarding.GrpcAttachment;
+import de.ozgcloud.eingang.forwarding.GrpcFileContent;
+import de.ozgcloud.eingang.forwarding.GrpcRepresentation;
+import de.ozgcloud.eingang.forwarding.GrpcRouteForwarding;
+import de.ozgcloud.eingang.forwarding.GrpcRouteForwardingResponse;
+import lombok.SneakyThrows;
+
+class EingangStubReceiverStreamObserverTest {
+
+	private EingangStubReceiverStreamObserver observer;
+
+	@Mock
+	private RouteForwardingMapper routeForwardingMapper;
+	@Mock
+	private IncomingFileMapper incomingFileMapper;
+	@Mock
+	private IncomingFileGroupMapper incomingFileGroupMapper;
+	@Mock
+	private Function<InputStream, CompletableFuture<File>> fileSaver;
+	@Mock
+	private Consumer<FormData> formDataConsumer;
+	@Mock
+	private Consumer<GrpcRouteForwardingResponse> responseConsumer;
+
+	@BeforeEach
+	void setUp() {
+		observer = spy(EingangStubReceiverStreamObserver.builder()
+				.fileSaver(fileSaver)
+				.routeForwardingMapper(routeForwardingMapper)
+				.incomingFileMapper(incomingFileMapper)
+				.incomingFileGroupMapper(incomingFileGroupMapper)
+				.formDataConsumer(formDataConsumer)
+				.responseConsumer(responseConsumer)
+				.build());
+	}
+
+	@Nested
+	class TestOnNext {
+
+		@Nested
+		class TestOnRouteForwarding {
+
+			@BeforeEach
+			void mock() {
+				doNothing().when(observer).handleRouteForwarding(any());
+			}
+
+			@Test
+			void shouldCallHandleRouteForwarding() {
+				observer.onNext(GrpcRouteForwardingRequestTestFactory.createWithRouteForwarding());
+
+				verify(observer).handleRouteForwarding(GrpcRouteForwardingRequestTestFactory.ROUTE_FORWARDING);
+			}
+
+			@Test
+			void shouldNotCallHandleAttachment() {
+				observer.onNext(GrpcRouteForwardingRequestTestFactory.createWithRouteForwarding());
+
+				verify(observer, never()).handleAttachment(any());
+			}
+
+			@Test
+			void shouldNotCallHandleRepresentation() {
+				observer.onNext(GrpcRouteForwardingRequestTestFactory.createWithRouteForwarding());
+
+				verify(observer, never()).handleRepresentation(any());
+			}
+		}
+
+		@Nested
+		class TestOnAttachment {
+			@Test
+			void shouldCallHandleAttachment() {
+				observer.onNext(GrpcRouteForwardingRequestTestFactory.createWithAttachment());
+
+				verify(observer).handleAttachment(GrpcRouteForwardingRequestTestFactory.ATTACHMENT);
+			}
+
+			@Test
+			void shouldNotCallHandleRouteForwarding() {
+				observer.onNext(GrpcRouteForwardingRequestTestFactory.createWithAttachment());
+
+				verify(observer, never()).handleRouteForwarding(any());
+			}
+
+			@Test
+			void shouldNotCallHandleRepresentation() {
+				observer.onNext(GrpcRouteForwardingRequestTestFactory.createWithAttachment());
+
+				verify(observer, never()).handleRepresentation(any());
+			}
+		}
+
+		@Nested
+		class TestOnRepresentation {
+			@Test
+			void shouldCallHandleRepresentation() {
+				observer.onNext(GrpcRouteForwardingRequestTestFactory.createWithRepresentation());
+
+				verify(observer).handleRepresentation(GrpcRouteForwardingRequestTestFactory.REPRESENTATION);
+			}
+
+			@Test
+			void shouldNotCallHandleRouteForwarding() {
+				observer.onNext(GrpcRouteForwardingRequestTestFactory.createWithRepresentation());
+
+				verify(observer, never()).handleRouteForwarding(any());
+			}
+
+			@Test
+			void shouldNotCallHandleAttachment() {
+				observer.onNext(GrpcRouteForwardingRequestTestFactory.createWithRepresentation());
+
+				verify(observer, never()).handleAttachment(any());
+			}
+		}
+	}
+
+	@Nested
+	class TestHandleRouteForwarding {
+
+		private final GrpcRouteForwarding routeForwarding = GrpcRouteForwardingTestFactory.create();
+
+		@Test
+		void shouldThrowIllegalStateExceptionIfFormDataIsSet() {
+			setFormData(FormDataTestFactory.create());
+
+			assertThrows(IllegalStateException.class, () -> observer.handleRouteForwarding(routeForwarding));
+
+		}
+
+		@Test
+		void shouldMapRouteForwarding() {
+			observer.handleRouteForwarding(routeForwarding);
+
+			verify(routeForwardingMapper).toFormData(routeForwarding);
+		}
+
+		@Test
+		void shouldSetFormData() {
+			var formData = FormDataTestFactory.create();
+			when(routeForwardingMapper.toFormData(any())).thenReturn(formData);
+
+			observer.handleRouteForwarding(routeForwarding);
+
+			assertThat(getFormData()).isEqualTo(formData);
+		}
+	}
+
+	@Nested
+	class TestHandleAttachment {
+
+		@Nested
+		class TestWithFile {
+
+			private final GrpcAttachment attachmentWithFile = GrpcAttachmentTestFactory.createWithFile();
+			private final IncomingFile incomingFile = IncomingFileTestFactory.create();
+
+			@BeforeEach
+			void mock() {
+				doNothing().when(observer).setCurrentMetadata(any());
+				when(incomingFileMapper.fromGrpcAttachmentFile(any())).thenReturn(incomingFile);
+			}
+
+			@Test
+			void shouldCallIncomingFileMapper() {
+				observer.handleAttachment(attachmentWithFile);
+
+				verify(incomingFileMapper).fromGrpcAttachmentFile(GrpcAttachmentTestFactory.FILE);
+			}
+
+			@Test
+			void shouldCallSetCurrentMetadata() {
+				observer.handleAttachment(attachmentWithFile);
+
+				verify(observer).setCurrentMetadata(incomingFile);
+			}
+
+			@Test
+			void shouldSetGroupName() {
+				observer.handleAttachment(attachmentWithFile);
+
+				assertThat(getGroupName()).contains(GrpcAttachmentFileTestFactory.GROUP_NAME);
+			}
+
+			@Test
+			void shouldNotCallHandleFileContent() {
+				observer.handleAttachment(attachmentWithFile);
+
+				verify(observer, never()).handleFileContent(any());
+			}
+		}
+
+		@Nested
+		class TestWithContent {
+
+			private final GrpcAttachment attachmentWithContent = GrpcAttachmentTestFactory.createWithContent();
+
+			@BeforeEach
+			void mock() {
+				doNothing().when(observer).handleFileContent(any());
+			}
+
+			@Test
+			void shouldCallHandleFileContent() {
+				observer.handleAttachment(attachmentWithContent);
+
+				verify(observer).handleFileContent(GrpcAttachmentTestFactory.CONTENT);
+			}
+
+			@Test
+			void shouldNotCallIncomingFileMapper() {
+				observer.handleAttachment(attachmentWithContent);
+
+				verify(incomingFileMapper, never()).fromGrpcAttachmentFile(any());
+			}
+
+			@Test
+			void shouldNotSetGroupName() {
+				observer.handleAttachment(attachmentWithContent);
+
+				assertThat(getGroupName()).isEmpty();
+			}
+		}
+	}
+
+	@Nested
+	class TestHandleRepresentation {
+
+		@Nested
+		class TestWithFile {
+
+			private final GrpcRepresentation representationWithFile = GrpcRepresentationTestFactory.createWithFile();
+			private final IncomingFile incomingFile = IncomingFileTestFactory.create();
+
+			@BeforeEach
+			void mock() {
+				doNothing().when(observer).setCurrentMetadata(any());
+				when(incomingFileMapper.fromGrpcRepresentationFile(any())).thenReturn(incomingFile);
+			}
+
+			@Test
+			void shouldCallIncomingFileMapper() {
+				observer.handleRepresentation(representationWithFile);
+
+				verify(incomingFileMapper).fromGrpcRepresentationFile(GrpcRepresentationTestFactory.FILE);
+			}
+
+			@Test
+			void shouldCallSetCurrentMetadata() {
+				observer.handleRepresentation(representationWithFile);
+
+				verify(observer).setCurrentMetadata(incomingFile);
+			}
+
+			@Test
+			void shouldNotCallHandleFileContent() {
+				observer.handleRepresentation(representationWithFile);
+
+				verify(observer, never()).handleFileContent(any());
+			}
+		}
+
+		@Nested
+		class TestWithContent {
+
+			private final GrpcRepresentation representationWithContent = GrpcRepresentationTestFactory.createWithContent();
+
+			@BeforeEach
+			void mock() {
+				doNothing().when(observer).handleFileContent(any());
+			}
+
+			@Test
+			void shouldCallHandleFileContent() {
+				observer.handleRepresentation(representationWithContent);
+
+				verify(observer).handleFileContent(GrpcRepresentationTestFactory.CONTENT);
+			}
+
+			@Test
+			void shouldNotCallIncomingFileMapper() {
+				observer.handleRepresentation(representationWithContent);
+
+				verify(incomingFileMapper, never()).fromGrpcRepresentationFile(any());
+			}
+		}
+	}
+
+	@Nested
+	class TestSetCurrentMetadata {
+
+		private final IncomingFile incomingFile = IncomingFileTestFactory.create();
+
+		@Test
+		void shouldThrowIllegalStateExceptionIfCurrentFileIsSet() {
+			setCurrentFile(incomingFile);
+
+			assertThrows(IllegalStateException.class, () -> observer.setCurrentMetadata(incomingFile));
+		}
+
+		@Test
+		void shouldSetCurrentFile() {
+			observer.setCurrentMetadata(incomingFile);
+
+			assertThat(getCurrentFile()).isSameAs(incomingFile);
+		}
+	}
+
+	@Nested
+	class TestHandleFileContent {
+
+		private final GrpcFileContent fileContent = GrpcFileContentTestFactory.create();
+
+		@Nested
+		class TestOnReceivingFileContentIsNull {
+			@BeforeEach
+			void mock() {
+				doNothing().when(observer).initContentReceiving();
+				doNothing().when(observer).storeFileContent(any());
+			}
+
+			@Test
+			void shouldCallInitContentReceiving() {
+				observer.handleFileContent(fileContent);
+
+				verify(observer).initContentReceiving();
+			}
+
+			@Test
+			void shouldCallStoreFileContent() {
+				observer.handleFileContent(fileContent);
+
+				verify(observer).storeFileContent(fileContent);
+			}
+		}
+
+		@Nested
+		class TestOnReceivingFileContentIsNotNull {
+			@Mock
+			private CompletableFuture<File> receivingFileContent;
+
+			@BeforeEach
+			void mock() {
+				doNothing().when(observer).storeFileContent(any());
+				setFileContent(receivingFileContent);
+			}
+
+			@Test
+			void shouldNotCallInitContentReceiving() {
+				observer.handleFileContent(fileContent);
+
+				verify(observer, never()).initContentReceiving();
+			}
+
+			@Test
+			void shouldCallStoreFileContent() {
+				observer.handleFileContent(fileContent);
+
+				verify(observer).storeFileContent(fileContent);
+			}
+		}
+	}
+
+	@Nested
+	class TestInitContentReceiving {
+
+		private final byte[] content = new byte[] { 1, 2, 3 };
+
+		@Test
+		void shouldCreateInputStream() {
+			observer.initContentReceiving();
+
+			assertThat(getPipedInput()).isNotNull();
+		}
+
+		@Test
+		void shouldCreateOutputStream() {
+			observer.initContentReceiving();
+
+			assertThat(getPipedOutput()).isNotNull();
+		}
+
+		@Test
+		void shouldCreateConnectedStreams() {
+			observer.initContentReceiving();
+
+			verifyStreamSetUp();
+		}
+
+		@SneakyThrows
+		private void verifyStreamSetUp() {
+			var pipedInput = getPipedInput();
+			var pipedOutput = getPipedOutput();
+			pipedOutput.write(content);
+			pipedOutput.close();
+			var readBytes = pipedInput.readAllBytes();
+			assertThat(readBytes).isEqualTo(content);
+		}
+
+		@Test
+		void shouldCallFileSaver() {
+			observer.initContentReceiving();
+
+			verify(fileSaver).apply(getPipedInput());
+		}
+
+		@Test
+		void shouldSetReceivingFileContent() {
+			var fileFuture = CompletableFuture.completedFuture(mock(File.class));
+			when(fileSaver.apply(any())).thenReturn(fileFuture);
+
+			observer.initContentReceiving();
+
+			assertThat(getFileContent()).isSameAs(fileFuture);
+		}
+	}
+
+	@Nested
+	class TestStoreFileContent {
+		@Mock
+		private PipedOutputStream pipedOutput;
+
+		@BeforeEach
+		void setUp() {
+			setPipedOutput(pipedOutput);
+		}
+
+		@Nested
+		class TestOnCurrentFileIsNull {
+
+			@Test
+			void shouldThrowTechnicalException() {
+				var fileContent = GrpcFileContentTestFactory.create();
+
+				assertThrows(IllegalStateException.class, () -> observer.storeFileContent(fileContent));
+			}
+		}
+
+		@Nested
+		class TestOnCurrentFileIsNotNull {
+
+			private final IncomingFile incomingFile = IncomingFileTestFactory.create();
+
+			@BeforeEach
+			void mock() {
+				setCurrentFile(incomingFile);
+			}
+
+			@Test
+			@SneakyThrows
+			void shouldWriteContentToOutputStream() {
+				observer.storeFileContent(GrpcFileContentTestFactory.create());
+
+				verify(pipedOutput).write(GrpcFileContentTestFactory.CONTENT);
+			}
+
+			@Test
+			void shouldCallHandleEndOfFile() {
+				doNothing().when(observer).handleEndOfFile();
+				var fileContent = GrpcFileContentTestFactory.createBuilder().setIsEndOfFile(true).build();
+
+				observer.storeFileContent(fileContent);
+
+				verify(observer).handleEndOfFile();
+			}
+
+			@Test
+			void shouldNotCallHandleEndOfFile() {
+				var fileContent = GrpcFileContentTestFactory.createBuilder().setIsEndOfFile(false).build();
+
+				observer.storeFileContent(fileContent);
+
+				verify(observer, never()).handleEndOfFile();
+			}
+
+			@Test
+			@SneakyThrows
+			void shouldThrowTechnicalExceptionOnIOException() {
+				doThrow(new IOException()).when(pipedOutput).write(any());
+				var fileContent = GrpcFileContentTestFactory.create();
+
+				assertThrows(TechnicalException.class, () -> {
+					observer.storeFileContent(fileContent);
+				});
+			}
+		}
+	}
+
+	@Nested
+	class TestHandleEndOfFile {
+
+		@Mock
+		private File savedFileContent;
+
+		private final IncomingFile incomingFile = IncomingFileTestFactory.createBuilder().file(null).build();
+
+		@BeforeEach
+		void setUp() {
+			doNothing().when(observer).closeOutputPipe();
+			doReturn(savedFileContent).when(observer).getSavedFileContent();
+			setCurrentFile(incomingFile);
+		}
+
+		@Test
+		void shouldCallCloseOutputPipe() {
+			observer.handleEndOfFile();
+
+			verify(observer).closeOutputPipe();
+		}
+
+		@Nested
+		class TestOnGroupNameEmpty {
+
+			@BeforeEach
+			void setUp() {
+				setGroupName(Optional.empty());
+			}
+
+			@Test
+			void shouldAddFileToRepresentations() {
+				var expectedIncomingFile = IncomingFileTestFactory.createBuilder().file(savedFileContent).build();
+
+				observer.handleEndOfFile();
+
+				assertThat(getRepresentations()).usingRecursiveFieldByFieldElementComparator().containsExactly(expectedIncomingFile);
+			}
+		}
+
+		@Nested
+		class TestOnGroupNameSet {
+
+			@BeforeEach
+			void setUp() {
+				setGroupName(Optional.of(GrpcAttachmentFileTestFactory.GROUP_NAME));
+			}
+
+			@Test
+			void shouldAddFileToAttachments() {
+				var expectedIncomingFile = IncomingFileTestFactory.createBuilder().file(savedFileContent).build();
+
+				observer.handleEndOfFile();
+
+				var attachmentGroup = getAttachments().get(GrpcAttachmentFileTestFactory.GROUP_NAME);
+				assertThat(attachmentGroup).usingRecursiveFieldByFieldElementComparator().containsExactly(expectedIncomingFile);
+			}
+		}
+
+		@Test
+		void shouldCallResetFileReceiving() {
+			observer.handleEndOfFile();
+
+			verify(observer).resetFileReceiving();
+		}
+	}
+
+	@Nested
+	class TestGetSavedFileContent {
+		@BeforeEach
+		void setUp() {
+			doNothing().when(observer).closeInputPipe();
+		}
+
+		@Nested
+		class TestOnNoExceptions {
+			@Mock
+			private File fileContent;
+
+			@BeforeEach
+			void setUp() {
+				setFileContent(CompletableFuture.completedFuture(fileContent));
+			}
+
+			@Test
+			void shouldReturnFile() {
+				var savedFileContent = observer.getSavedFileContent();
+
+				assertThat(savedFileContent).isSameAs(fileContent);
+			}
+
+			@Test
+			void shouldCallCloseInputPipe() {
+				observer.getSavedFileContent();
+
+				verify(observer).closeInputPipe();
+			}
+		}
+
+		@Nested
+		class TestOnExecutionException {
+
+			@BeforeEach
+			void setUp() {
+				setFileContent(CompletableFuture.failedFuture(new Exception()));
+			}
+
+			@Test
+			void shouldThrowTechnicalException() {
+				assertThrows(TechnicalException.class, () -> observer.getSavedFileContent());
+			}
+
+			@Test
+			void shouldCallCloseInputPipe() {
+				try {
+					observer.getSavedFileContent();
+				} catch (TechnicalException e) {
+					// expected
+				}
+
+				verify(observer).closeInputPipe();
+			}
+		}
+
+		@Nested
+		class TestOnTimeoutException {
+
+			@Mock
+			private CompletableFuture<File> fileFuture;
+
+			@BeforeEach
+			@SneakyThrows
+			void setUp() {
+				setFileContent(fileFuture);
+				when(fileFuture.get(anyLong(), any())).thenThrow(new TimeoutException());
+			}
+
+			@Test
+			void shouldThrowTechnicalException() {
+				assertThrows(TechnicalException.class, () -> observer.getSavedFileContent());
+			}
+
+			@Test
+			void shouldCallCloseInputPipe() {
+				try {
+					observer.getSavedFileContent();
+				} catch (TechnicalException e) {
+					// expected
+				}
+
+				verify(observer).closeInputPipe();
+			}
+		}
+
+		@Nested
+		class TestOnInterruptedException {
+
+			@Mock
+			private CompletableFuture<File> fileFuture;
+
+			@BeforeEach
+			@SneakyThrows
+			void setUp() {
+				setFileContent(fileFuture);
+				when(fileFuture.get(anyLong(), any())).thenThrow(new InterruptedException());
+			}
+
+			@Test
+			void shouldThrowTechnicalException() {
+				assertThrows(TechnicalException.class, () -> observer.getSavedFileContent());
+			}
+
+			@Test
+			void shouldInterruptCurrentThread() {
+				try {
+					observer.getSavedFileContent();
+				} catch (TechnicalException e) {
+					// expected
+				}
+
+				assertThat(Thread.currentThread().isInterrupted()).isTrue();
+			}
+
+			@Test
+			void shouldCallCloseInputPipe() {
+				try {
+					observer.getSavedFileContent();
+				} catch (TechnicalException e) {
+					// expected
+				}
+
+				verify(observer).closeInputPipe();
+			}
+		}
+	}
+
+	@Nested
+	class TestResetFielReceiving {
+
+		@BeforeEach
+		void setUp() {
+			setCurrentFile(IncomingFileTestFactory.create());
+			setGroupName(Optional.of(GrpcAttachmentFileTestFactory.GROUP_NAME));
+			setPipedOutput(mock(PipedOutputStream.class));
+			setPipedOutput(mock(PipedOutputStream.class));
+			setFileContent(CompletableFuture.completedFuture(mock(File.class)));
+		}
+
+		@Test
+		void shouldResetCurrentFile() {
+			observer.resetFileReceiving();
+
+			assertThat(getCurrentFile()).isNull();
+		}
+
+		@Test
+		void shouldResetGroupName() {
+			observer.resetFileReceiving();
+
+			assertThat(getGroupName()).isEmpty();
+		}
+
+		@Test
+		void shouldResetPipedOutput() {
+			observer.resetFileReceiving();
+
+			assertThat(getPipedOutput()).isNull();
+		}
+
+		@Test
+		void shouldResetPipedInput() {
+			observer.resetFileReceiving();
+
+			assertThat(getPipedInput()).isNull();
+		}
+
+		@Test
+		void shouldResetReceivingFileContent() {
+			observer.resetFileReceiving();
+
+			assertThat(getFileContent()).isNull();
+		}
+	}
+
+	@Nested
+	class TestOnError {
+
+		@BeforeEach
+		void mock() {
+			doNothing().when(observer).closeOutputPipe();
+			doNothing().when(observer).closeInputPipe();
+		}
+
+		@Test
+		void shouldCallCloseOutputPipe() {
+			observer.onError(new Exception());
+
+			verify(observer).closeOutputPipe();
+		}
+
+		@Test
+		void shouldCallCloseInputPipe() {
+			observer.onError(new Exception());
+
+			verify(observer).closeInputPipe();
+		}
+	}
+
+	@Nested
+	class TestCloseOutputPipe {
+
+		@Mock
+		private PipedOutputStream pipedOutput;
+
+		@BeforeEach
+		void setUp() {
+			setPipedOutput(pipedOutput);
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldClosePipedOutput() {
+			observer.closeOutputPipe();
+
+			verify(pipedOutput).close();
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldNotThrowException() {
+			doThrow(IOException.class).when(pipedOutput).close();
+
+			assertDoesNotThrow(() -> observer.closeOutputPipe());
+		}
+	}
+
+	@Nested
+	class TestCloseInputPipe {
+
+		@Mock
+		private PipedInputStream pipedInput;
+
+		@BeforeEach
+		void setUp() {
+			setPipedInput(pipedInput);
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldClosePipedInput() {
+			observer.closeInputPipe();
+
+			verify(pipedInput).close();
+		}
+
+		@Test
+		@SneakyThrows
+		void shouldNotThrowException() {
+			doThrow(IOException.class).when(pipedInput).close();
+
+			assertDoesNotThrow(() -> observer.closeInputPipe());
+		}
+	}
+
+	@Nested
+	class TestOnCompleted {
+
+		private final FormData formData = FormDataTestFactory.create();
+
+		@BeforeEach
+		void mock() {
+			doReturn(formData).when(observer).assembleFormData();
+		}
+
+		@Test
+		void shouldCallAssembleFormData() {
+			observer.onCompleted();
+
+			verify(observer).assembleFormData();
+		}
+
+		@Test
+		void shouldCallFormDataConsumer() {
+			observer.onCompleted();
+
+			verify(formDataConsumer).accept(formData);
+		}
+
+		@Test
+		void shouldCallResponseConsumer() {
+			observer.onCompleted();
+
+			verify(responseConsumer).accept(GrpcRouteForwardingResponse.getDefaultInstance());
+		}
+	}
+
+	@Nested
+	class TestAssembleFormData {
+
+		@Nested
+		class TestOnFormDataNotSet {
+
+			@Test
+			void shouldThrowIllegalStateException() {
+				assertThrows(IllegalStateException.class, () -> observer.assembleFormData());
+			}
+		}
+
+		@Nested
+		class TestOnFormDataSet {
+
+			private final FormData formData = FormDataTestFactory.createBuilder()
+					.clearAttachments()
+					.clearRepresentations()
+					.numberOfAttachments(0)
+					.numberOfRepresentations(0)
+					.control(null)
+					.build();
+
+			private final List<IncomingFile> representations = FormDataTestFactory.REPRESENTATIONS;
+			private final Map.Entry<String, List<IncomingFile>> attachmentEntry = Map.entry(
+					IncomingFileGroupTestFactory.NAME, IncomingFileGroupTestFactory.INCOMING_FILES);
+
+			@BeforeEach
+			void setUp() {
+				setFormData(formData);
+				setRepresentations(representations);
+				setAttachments(Map.ofEntries(attachmentEntry));
+			}
+
+			@Test
+			void shouldCallIncomingFileGroupMapper() {
+				observer.assembleFormData();
+
+				verify(incomingFileGroupMapper).fromMapEntry(attachmentEntry);
+			}
+
+			@Test
+			void shouldReturnFormData() {
+				var expectedFormData = FormDataTestFactory.createBuilder()
+						.control(null)
+						.build();
+				when(incomingFileGroupMapper.fromMapEntry(attachmentEntry)).thenReturn(IncomingFileGroupTestFactory.create());
+
+				var assembledFormData = observer.assembleFormData();
+
+				assertThat(assembledFormData).usingRecursiveComparison().isEqualTo(expectedFormData);
+			}
+		}
+	}
+
+	private FormData getFormData() {
+		return (FormData) ReflectionTestUtils.getField(observer, "formData");
+	}
+
+	private void setFormData(FormData formData) {
+		ReflectionTestUtils.setField(observer, "formData", formData);
+	}
+
+	@SuppressWarnings("unchecked")
+	private Optional<String> getGroupName() {
+		return (Optional<String>) ReflectionTestUtils.getField(observer, "groupName");
+	}
+
+	private void setGroupName(Optional<String> groupName) {
+		ReflectionTestUtils.setField(observer, "groupName", groupName);
+	}
+
+	private IncomingFile getCurrentFile() {
+		return (IncomingFile) ReflectionTestUtils.getField(observer, "currentFile");
+	}
+
+	private void setCurrentFile(IncomingFile incomingFile) {
+		ReflectionTestUtils.setField(observer, "currentFile", incomingFile);
+	}
+
+	private void setFileContent(CompletableFuture<File> fileFuture) {
+		ReflectionTestUtils.setField(observer, "receivingFileContent", fileFuture);
+	}
+
+	@SuppressWarnings("unchecked")
+	private CompletableFuture<File> getFileContent() {
+		return (CompletableFuture<File>) ReflectionTestUtils.getField(observer, "receivingFileContent");
+	}
+
+	private PipedInputStream getPipedInput() {
+		return (PipedInputStream) ReflectionTestUtils.getField(observer, "pipedInput");
+	}
+
+	private void setPipedInput(PipedInputStream pipedInput) {
+		ReflectionTestUtils.setField(observer, "pipedInput", pipedInput);
+	}
+
+	private PipedOutputStream getPipedOutput() {
+		return (PipedOutputStream) ReflectionTestUtils.getField(observer, "pipedOutput");
+	}
+
+	private void setPipedOutput(PipedOutputStream pipedOutput) {
+		ReflectionTestUtils.setField(observer, "pipedOutput", pipedOutput);
+	}
+
+	@SuppressWarnings("unchecked")
+	private List<IncomingFile> getRepresentations() {
+		return (List<IncomingFile>) ReflectionTestUtils.getField(observer, "representations");
+	}
+
+	private void setRepresentations(List<IncomingFile> representations) {
+		ReflectionTestUtils.setField(observer, "representations", representations);
+	}
+
+	@SuppressWarnings("unchecked")
+	private Map<String, List<IncomingFile>> getAttachments() {
+		return (Map<String, List<IncomingFile>>) ReflectionTestUtils.getField(observer, "attachments");
+	}
+
+	private void setAttachments(Map<String, List<IncomingFile>> attachments) {
+		ReflectionTestUtils.setField(observer, "attachments", attachments);
+	}
+
+}
diff --git a/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/GrpcAttachmentFileTestFactory.java b/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/GrpcAttachmentFileTestFactory.java
index 12382dcfeb61d76e40707785b00ab67c5c683308..ec48f44e48beb0c2d0cd072050bd7494a1effac3 100644
--- a/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/GrpcAttachmentFileTestFactory.java
+++ b/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/GrpcAttachmentFileTestFactory.java
@@ -23,15 +23,14 @@
  */
 package de.ozgcloud.eingang.forwarder;
 
-import com.thedeanda.lorem.LoremIpsum;
-
+import de.ozgcloud.eingang.common.formdata.IncomingFileGroupTestFactory;
 import de.ozgcloud.eingang.common.formdata.IncomingFileTestFactory;
 import de.ozgcloud.eingang.forwarding.GrpcAttachmentFile;
 import de.ozgcloud.eingang.forwarding.GrpcAttachmentFile.Builder;
 
 public class GrpcAttachmentFileTestFactory {
 
-	public static final String GROUP_NAME = LoremIpsum.getInstance().getWords(1);
+	public static final String GROUP_NAME = IncomingFileGroupTestFactory.NAME;
 
 	public static GrpcAttachmentFile create() {
 		return createBuilder().build();
diff --git a/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/GrpcAttachmentTestFactory.java b/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/GrpcAttachmentTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..e5593e13f415f71ceee9fd21e5fb548383f7d8eb
--- /dev/null
+++ b/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/GrpcAttachmentTestFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
+ * Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei
+ * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.ozgcloud.eingang.forwarder;
+
+import de.ozgcloud.eingang.forwarding.GrpcAttachment;
+import de.ozgcloud.eingang.forwarding.GrpcAttachmentFile;
+import de.ozgcloud.eingang.forwarding.GrpcFileContent;
+
+public class GrpcAttachmentTestFactory {
+
+	public static final GrpcAttachmentFile FILE = GrpcAttachmentFileTestFactory.create();
+	public static final GrpcFileContent CONTENT = GrpcFileContentTestFactory.create();
+
+	public static GrpcAttachment createWithFile() {
+		return GrpcAttachment.newBuilder()
+				.setFile(FILE)
+				.build();
+	}
+
+	public static GrpcAttachment createWithContent() {
+		return GrpcAttachment.newBuilder()
+				.setContent(CONTENT)
+				.build();
+	}
+
+}
diff --git a/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/GrpcFileContentTestFactory.java b/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/GrpcFileContentTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..d4040f97517ce4c6a379d38eaeb173bc96bf90d0
--- /dev/null
+++ b/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/GrpcFileContentTestFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
+ * Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei
+ * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.ozgcloud.eingang.forwarder;
+
+import com.google.protobuf.ByteString;
+import com.thedeanda.lorem.LoremIpsum;
+
+import de.ozgcloud.eingang.forwarding.GrpcFileContent;
+import de.ozgcloud.eingang.forwarding.GrpcFileContent.Builder;
+
+public class GrpcFileContentTestFactory {
+
+	public static final boolean IS_END_OF_FILE = false;
+	public static final byte[] CONTENT = LoremIpsum.getInstance().getWords(10).getBytes();
+
+	public static GrpcFileContent create() {
+		return createBuilder().build();
+	}
+
+	public static Builder createBuilder() {
+		return GrpcFileContent.newBuilder()
+				.setContent(ByteString.copyFrom(CONTENT))
+				.setIsEndOfFile(IS_END_OF_FILE);
+	}
+
+}
diff --git a/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/GrpcRepresentationTestFactory.java b/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/GrpcRepresentationTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..e437c900d0a49cf0f714d4d7718a9f699d681af8
--- /dev/null
+++ b/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/GrpcRepresentationTestFactory.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
+ * Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei
+ * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.ozgcloud.eingang.forwarder;
+
+import de.ozgcloud.eingang.forwarding.GrpcFileContent;
+import de.ozgcloud.eingang.forwarding.GrpcRepresentation;
+import de.ozgcloud.eingang.forwarding.GrpcRepresentationFile;
+
+public class GrpcRepresentationTestFactory {
+
+	public static final GrpcRepresentationFile FILE = GrpcRepresentationFileTestFactory.create();
+	public static final GrpcFileContent CONTENT = GrpcFileContentTestFactory.create();
+
+	public static GrpcRepresentation createWithFile() {
+		return GrpcRepresentation.newBuilder()
+				.setFile(FILE)
+				.build();
+	}
+
+	public static GrpcRepresentation createWithContent() {
+		return GrpcRepresentation.newBuilder()
+				.setContent(CONTENT)
+				.build();
+	}
+}
diff --git a/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/GrpcRouteForwardingRequestTestFactory.java b/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/GrpcRouteForwardingRequestTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..a05ac9a84aa68f8deae2657d2e4e64fd37879291
--- /dev/null
+++ b/forwarder/src/test/java/de/ozgcloud/eingang/forwarder/GrpcRouteForwardingRequestTestFactory.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2025 Das Land Schleswig-Holstein vertreten durch den
+ * Ministerpräsidenten des Landes Schleswig-Holstein
+ * Staatskanzlei
+ * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
+ *
+ * Lizenziert unter der EUPL, Version 1.2 oder - sobald
+ * diese von der Europäischen Kommission genehmigt wurden -
+ * Folgeversionen der EUPL ("Lizenz");
+ * Sie dürfen dieses Werk ausschließlich gemäß
+ * dieser Lizenz nutzen.
+ * Eine Kopie der Lizenz finden Sie hier:
+ *
+ * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * Sofern nicht durch anwendbare Rechtsvorschriften
+ * gefordert oder in schriftlicher Form vereinbart, wird
+ * die unter der Lizenz verbreitete Software "so wie sie
+ * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
+ * ausdrücklich oder stillschweigend - verbreitet.
+ * Die sprachspezifischen Genehmigungen und Beschränkungen
+ * unter der Lizenz sind dem Lizenztext zu entnehmen.
+ */
+package de.ozgcloud.eingang.forwarder;
+
+import de.ozgcloud.eingang.forwarding.GrpcAttachment;
+import de.ozgcloud.eingang.forwarding.GrpcRepresentation;
+import de.ozgcloud.eingang.forwarding.GrpcRouteForwarding;
+import de.ozgcloud.eingang.forwarding.GrpcRouteForwardingRequest;
+
+public class GrpcRouteForwardingRequestTestFactory {
+
+	public static final GrpcRepresentation REPRESENTATION = GrpcRepresentationTestFactory.createWithFile();
+	public static final GrpcAttachment ATTACHMENT = GrpcAttachmentTestFactory.createWithFile();
+	public static final GrpcRouteForwarding ROUTE_FORWARDING = GrpcRouteForwardingTestFactory.create();
+
+	public static GrpcRouteForwardingRequest createWithRouteForwarding() {
+		return GrpcRouteForwardingRequest.newBuilder()
+				.setRouteForwarding(ROUTE_FORWARDING)
+				.build();
+	}
+
+	public static GrpcRouteForwardingRequest createWithAttachment() {
+		return GrpcRouteForwardingRequest.newBuilder()
+				.setAttachment(ATTACHMENT)
+				.build();
+	}
+
+	public static GrpcRouteForwardingRequest createWithRepresentation() {
+		return GrpcRouteForwardingRequest.newBuilder()
+				.setRepresentation(REPRESENTATION)
+				.build();
+	}
+}