diff --git a/.gitignore b/.gitignore
index dfef11fec1a6a560e16005d6dab3446ff596505d..7f63988e16bb81c61bdb52555d2c946b19cfacde 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,4 @@ goofy-client/apps/coverage/
 
 .attach**
 .factorypath
+.vscode/
diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangQuery.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangQuery.java
index dcaa5ac1fa3eac0320e31fb26c44182a7983a124..228c17aa8bba2e3c113ad68804a717d348f9ced1 100644
--- a/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangQuery.java
+++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangQuery.java
@@ -1,21 +1,23 @@
 package de.ozgcloud.apilib.vorgang;
 
+import java.util.Collection;
 import java.util.Optional;
 
 import lombok.Builder;
 import lombok.Getter;
+import lombok.Singular;
 
 @Builder
 @Getter
 public class OzgCloudVorgangQuery {
 	@Builder.Default
-	public final Optional<String> organisationsEinheitId = Optional.empty();
+	private final Optional<String> organisationsEinheitId = Optional.empty();
 	@Builder.Default
-	public final Optional<FormIdentification> form = Optional.empty();
+	private final Optional<FormIdentification> form = Optional.empty();
 	@Builder.Default
-	public final Optional<String> status = Optional.empty();
+	private final Optional<String> status = Optional.empty();
 	@Builder.Default
-	public final Optional<String> aktenzeichen = Optional.empty();
+	private final Optional<String> aktenzeichen = Optional.empty();
 
 	@Builder.Default
 	public final Optional<Query> query = Optional.empty();
@@ -23,13 +25,15 @@ public class OzgCloudVorgangQuery {
 	@Builder
 	@Getter
 	public static class Query {
-		public final LogicalOperator logicalOperator;
-		public final Expression expression;
-		public final OzgCloudVorgangQuery nestedQuery;
+		private final LogicalOperator logicalOperator;
+		@Singular
+		private final Collection<Expression> expressions;
+		private final Query nestedQuery;
 	}
 
+	@Builder
 	public static record FormIdentification(String formId, String formEngineName) {
-	};
+	}
 
 	public enum LogicalOperator {
 		AND, OR
@@ -38,11 +42,11 @@ public class OzgCloudVorgangQuery {
 	@Builder
 	@Getter
 	public static class Expression {
-		public final String path;
-		public final ComparsionOperator operator;
-		public final Integer operandIntValue;
-		public final Boolean operandBoolValue;
-		public final String operandStringValue;
+		private final String path;
+		private final ComparsionOperator operator;
+		private final Integer operandIntValue;
+		private final Boolean operandBoolValue;
+		private final String operandStringValue;
 
 		public enum ComparsionOperator {
 			GREATER_THEN, // >
diff --git a/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/grpc/OzgCloudVorgangQueryMapper.java b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/grpc/OzgCloudVorgangQueryMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..156b33ad16c283c394e08cd87063e4036277ca82
--- /dev/null
+++ b/api-lib-core/src/main/java/de/ozgcloud/apilib/vorgang/grpc/OzgCloudVorgangQueryMapper.java
@@ -0,0 +1,91 @@
+package de.ozgcloud.apilib.vorgang.grpc;
+
+import org.mapstruct.CollectionMappingStrategy;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.NullValueCheckStrategy;
+
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangQuery;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangQuery.FormIdentification;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangQuery.Query;
+import de.ozgcloud.vorgang.common.GrpcQueryOperator;
+import de.ozgcloud.vorgang.vorgang.GrpcLogicalOperator;
+import de.ozgcloud.vorgang.vorgang.GrpcQuery;
+import de.ozgcloud.vorgang.vorgang.GrpcVorgangQueryExpression;
+import de.ozgcloud.vorgang.vorgang.GrpcVorgangQueryExpression.Builder;
+
+@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
+interface OzgCloudVorgangQueryMapper {
+
+	default GrpcQuery toGrpc(OzgCloudVorgangQuery query) {
+		var queryBuilder = GrpcQuery.newBuilder();
+		query.getAktenzeichen().map(this::toAktenzeichenExpression).ifPresent(queryBuilder::addExpressions);
+		query.getForm().map(this::toFormExpression).ifPresent(queryBuilder::addExpressions);
+		query.getStatus().map(this::toStatusExpression).ifPresent(queryBuilder::addExpressions);
+		query.getOrganisationsEinheitId().map(this::toOrganisationsEinheitIdExpression).ifPresent(queryBuilder::addExpressions);
+
+		if (queryBuilder.getExpressionsList().isEmpty()) {
+			return query.getQuery().map(this::nestedQueryToGrpc).orElseGet(queryBuilder::build);
+		}
+
+		query.getQuery().map(this::nestedQueryToGrpc).ifPresent(queryBuilder::setNestedQuery);
+		return queryBuilder.setLogicalOperator(GrpcLogicalOperator.AND).build();
+	}
+
+	private GrpcVorgangQueryExpression toAktenzeichenExpression(String aktenzeichen) {
+		return getEqualExpressionBuilder()
+				.setPath("aktenzeichen")
+				.setOperandStringValue(aktenzeichen)
+				.build();
+	}
+
+	private GrpcVorgangQueryExpression toOrganisationsEinheitIdExpression(String organisationsEinheitId) {
+		return getEqualExpressionBuilder()
+				.setPath("eingangs.zustaendigeStelle.organisationseinheitenId")
+				.setOperandStringValue(organisationsEinheitId)
+				.build();
+	}
+
+	private GrpcVorgangQueryExpression toStatusExpression(String status) {
+		return getEqualExpressionBuilder()
+				.setPath("status")
+				.setOperandStringValue(status)
+				.build();
+	}
+
+	private GrpcVorgangQueryExpression toFormExpression(FormIdentification formIdentification) {
+		return getEqualExpressionBuilder()
+				.setPath("formEngineName")
+				.setOperandStringValue(formIdentification.formEngineName())
+				.build();
+	}
+
+	default Builder getEqualExpressionBuilder() {
+		return GrpcVorgangQueryExpression.newBuilder()
+				.setOperator(GrpcQueryOperator.EQUAL);
+	}
+
+	@Mapping(target = "expressionsList.mergeFrom", ignore = true)
+	@Mapping(target = "expressionsList.clearField", ignore = true)
+	@Mapping(target = "expressionsList.clearOneof", ignore = true)
+	@Mapping(target = "expressionsList.mergeUnknownFields", ignore = true)
+	@Mapping(target = "expressionsList.unknownFields", ignore = true)
+	@Mapping(target = "expressionsList.allFields", ignore = true)
+	@Mapping(target = "expressionsList.operandStringValueBytes", ignore = true)
+	@Mapping(target = "expressionsList.operatorValue", ignore = true)
+	@Mapping(target = "expressionsList.pathBytes", ignore = true)
+	@Mapping(target = "mergeFrom", ignore = true)
+	@Mapping(target = "clearField", ignore = true)
+	@Mapping(target = "clearOneof", ignore = true)
+	@Mapping(target = "mergeNestedQuery", ignore = true)
+	@Mapping(target = "mergeUnknownFields", ignore = true)
+	@Mapping(target = "removeExpressions", ignore = true)
+	@Mapping(target = "logicalOperatorValue", ignore = true)
+	@Mapping(target = "unknownFields", ignore = true)
+	@Mapping(target = "allFields", ignore = true)
+	@Mapping(target = "expressionsBuilderList", ignore = true)
+	@Mapping(target = "expressionsOrBuilderList", ignore = true)
+
+	@Mapping(target = "expressionsList", source = "expressions")
+	GrpcQuery nestedQueryToGrpc(Query query1);
+}
diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/ExpressionTestFactory.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/ExpressionTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..559af9309cc036548486570468cccddb0a2b75e7
--- /dev/null
+++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/ExpressionTestFactory.java
@@ -0,0 +1,26 @@
+package de.ozgcloud.apilib.vorgang;
+
+import com.thedeanda.lorem.LoremIpsum;
+
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangQuery.Expression;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangQuery.Expression.ComparsionOperator;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangQuery.Expression.ExpressionBuilder;
+
+public class ExpressionTestFactory {
+
+	public static final int OPERAND_INT_VALUE = (int) (Math.random() * 100);
+	public static final String PATH = LoremIpsum.getInstance().getWords(1);
+	public static final ComparsionOperator OPERATOR = ComparsionOperator.EQUAL;
+
+	public static Expression create() {
+		return createBuilder().build();
+	}
+
+	public static ExpressionBuilder createBuilder() {
+		return Expression.builder()
+				.operator(OPERATOR)
+				.path(PATH)
+				.operandIntValue(OPERAND_INT_VALUE);
+	}
+
+}
diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/FormIdentificationTestFactory.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/FormIdentificationTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..f5142a3ade1dfdcc173dcf0ce5a3bc9b1cbe0241
--- /dev/null
+++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/FormIdentificationTestFactory.java
@@ -0,0 +1,26 @@
+package de.ozgcloud.apilib.vorgang;
+
+import java.util.UUID;
+
+import com.thedeanda.lorem.LoremIpsum;
+
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangQuery.FormIdentification;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangQuery.FormIdentification.FormIdentificationBuilder;
+
+public class FormIdentificationTestFactory {
+
+	public static final String FORM_ENGINE_NAME = LoremIpsum.getInstance().getWords(1);
+	public static final String FORM_ID = UUID.randomUUID().toString();
+
+	public static FormIdentification create() {
+		return createBuilder()
+				.build();
+	}
+
+	public static FormIdentificationBuilder createBuilder() {
+		return FormIdentification.builder()
+				.formId(FORM_ID)
+				.formEngineName(FORM_ENGINE_NAME);
+	}
+
+}
diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangQueryTestFactory.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangQueryTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..e9b036e0f7aa28841fb994fc8593cd3ce2ed2ec1
--- /dev/null
+++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/OzgCloudVorgangQueryTestFactory.java
@@ -0,0 +1,33 @@
+package de.ozgcloud.apilib.vorgang;
+
+import java.util.Optional;
+import java.util.UUID;
+
+import com.thedeanda.lorem.LoremIpsum;
+
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangQuery.FormIdentification;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangQuery.OzgCloudVorgangQueryBuilder;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangQuery.Query;
+
+public class OzgCloudVorgangQueryTestFactory {
+
+	public static final Query QUERY = QueryTestFactory.create();
+	public static final String STATUS = LoremIpsum.getInstance().getWords(1);
+	public static final FormIdentification FORM = FormIdentificationTestFactory.create();
+	public static final String AKTENZEICHEN = UUID.randomUUID().toString();
+	public static final String ORGANISATIONS_EINHEIT_ID = UUID.randomUUID().toString();
+
+	public static OzgCloudVorgangQuery create() {
+		return createBuilder()
+				.build();
+	}
+
+	public static OzgCloudVorgangQueryBuilder createBuilder() {
+		return OzgCloudVorgangQuery.builder()
+				.aktenzeichen(Optional.of(AKTENZEICHEN))
+				.form(Optional.of(FORM))
+				.organisationsEinheitId(Optional.of(ORGANISATIONS_EINHEIT_ID))
+				.status(Optional.of(STATUS))
+				.query(Optional.of(QUERY));
+	}
+}
diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/QueryTestFactory.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/QueryTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..113d68eb4c58e72613aba4456e213c8a595d0fdd
--- /dev/null
+++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/QueryTestFactory.java
@@ -0,0 +1,23 @@
+package de.ozgcloud.apilib.vorgang;
+
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangQuery.Expression;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangQuery.LogicalOperator;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangQuery.Query;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangQuery.Query.QueryBuilder;
+
+public class QueryTestFactory {
+
+	public static final LogicalOperator LOGICAL_OPERATOR = LogicalOperator.OR;
+	public static final Expression EXPRESSION = ExpressionTestFactory.create();
+
+	public static Query create() {
+		return createBuilder().build();
+	}
+
+	public static QueryBuilder createBuilder() {
+		return Query.builder()
+				.expression(EXPRESSION)
+				.logicalOperator(LOGICAL_OPERATOR);
+	}
+
+}
diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/grpc/GrpcQueryTestFactory.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/grpc/GrpcQueryTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..18c3d1ee41f6539ed9c9c4c4cd415a2910c4bb15
--- /dev/null
+++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/grpc/GrpcQueryTestFactory.java
@@ -0,0 +1,23 @@
+package de.ozgcloud.apilib.vorgang.grpc;
+
+import de.ozgcloud.apilib.vorgang.QueryTestFactory;
+import de.ozgcloud.vorgang.vorgang.GrpcLogicalOperator;
+import de.ozgcloud.vorgang.vorgang.GrpcQuery;
+import de.ozgcloud.vorgang.vorgang.GrpcQuery.Builder;
+import de.ozgcloud.vorgang.vorgang.GrpcVorgangQueryExpression;
+
+class GrpcQueryTestFactory {
+
+	private static final GrpcLogicalOperator LOGICAL_OPERATOR = GrpcLogicalOperator.valueOf(QueryTestFactory.LOGICAL_OPERATOR.toString());
+	public static final GrpcVorgangQueryExpression EXPRESSION = GrpcVorgangQueryExpressionTestFactory.create();
+
+	public static GrpcQuery create() {
+		return createBuilder().build();
+	}
+
+	public static Builder createBuilder() {
+		return GrpcQuery.newBuilder()
+				.setLogicalOperator(LOGICAL_OPERATOR)
+				.addExpressions(EXPRESSION);
+	}
+}
diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/grpc/GrpcVorgangQueryExpressionTestFactory.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/grpc/GrpcVorgangQueryExpressionTestFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..e7e544b2b7b0605993b090a0705fa1f7b5fa8c81
--- /dev/null
+++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/grpc/GrpcVorgangQueryExpressionTestFactory.java
@@ -0,0 +1,26 @@
+package de.ozgcloud.apilib.vorgang.grpc;
+
+import de.ozgcloud.apilib.vorgang.ExpressionTestFactory;
+import de.ozgcloud.vorgang.common.GrpcQueryOperator;
+import de.ozgcloud.vorgang.vorgang.GrpcVorgangQueryExpression;
+import de.ozgcloud.vorgang.vorgang.GrpcVorgangQueryExpression.Builder;
+
+public class GrpcVorgangQueryExpressionTestFactory {
+
+	public static final int OPERAND_INT_VALUE = ExpressionTestFactory.OPERAND_INT_VALUE;
+	public static final String PATH = ExpressionTestFactory.PATH;
+	public static final GrpcQueryOperator OPERATOR = GrpcQueryOperator.valueOf(ExpressionTestFactory.OPERATOR.toString());
+
+	public static GrpcVorgangQueryExpression create() {
+		return createBuilder()
+				.build();
+	}
+
+	public static Builder createBuilder() {
+		return GrpcVorgangQueryExpression.newBuilder()
+				.setOperator(OPERATOR)
+				.setPath(PATH)
+				.setOperandIntValue(OPERAND_INT_VALUE);
+	}
+
+}
diff --git a/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/grpc/OzgCloudVorgangQueryMapperTest.java b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/grpc/OzgCloudVorgangQueryMapperTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..124cbc3279a1c0c7ab3e64074ba9f9d34a1a751b
--- /dev/null
+++ b/api-lib-core/src/test/java/de/ozgcloud/apilib/vorgang/grpc/OzgCloudVorgangQueryMapperTest.java
@@ -0,0 +1,151 @@
+package de.ozgcloud.apilib.vorgang.grpc;
+
+import static org.assertj.core.api.Assertions.*;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.mapstruct.factory.Mappers;
+
+import de.ozgcloud.apilib.vorgang.FormIdentificationTestFactory;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangQuery;
+import de.ozgcloud.apilib.vorgang.OzgCloudVorgangQueryTestFactory;
+import de.ozgcloud.apilib.vorgang.QueryTestFactory;
+import de.ozgcloud.vorgang.common.GrpcQueryOperator;
+import de.ozgcloud.vorgang.vorgang.GrpcLogicalOperator;
+import de.ozgcloud.vorgang.vorgang.GrpcQuery;
+import de.ozgcloud.vorgang.vorgang.GrpcVorgangQueryExpression;
+
+class OzgCloudVorgangQueryMapperTest {
+
+	private final OzgCloudVorgangQueryMapper mapper = Mappers.getMapper(OzgCloudVorgangQueryMapper.class);
+
+	@Nested
+	class ToGrpc {
+
+		private final GrpcVorgangQueryExpression aktenzeichenExpression = GrpcVorgangQueryExpressionTestFactory.createBuilder()
+				.setPath("aktenzeichen")
+				.setOperator(GrpcQueryOperator.EQUAL)
+				.setOperandStringValue(OzgCloudVorgangQueryTestFactory.AKTENZEICHEN)
+				.build();
+
+		private final GrpcVorgangQueryExpression formExpression = GrpcVorgangQueryExpressionTestFactory.createBuilder()
+				.setPath("formEngineName")
+				.setOperator(GrpcQueryOperator.EQUAL)
+				.setOperandStringValue(FormIdentificationTestFactory.FORM_ENGINE_NAME)
+				.build();
+
+		private final GrpcVorgangQueryExpression statusExpression = GrpcVorgangQueryExpressionTestFactory.createBuilder()
+				.setPath("status")
+				.setOperator(GrpcQueryOperator.EQUAL)
+				.setOperandStringValue(OzgCloudVorgangQueryTestFactory.STATUS)
+				.build();
+
+		private final GrpcVorgangQueryExpression organisationsEinheitIdExpression = GrpcVorgangQueryExpressionTestFactory.createBuilder()
+				.setPath("eingangs.zustaendigeStelle.organisationseinheitenId")
+				.setOperator(GrpcQueryOperator.EQUAL)
+				.setOperandStringValue(OzgCloudVorgangQueryTestFactory.ORGANISATIONS_EINHEIT_ID)
+				.build();
+
+		@Nested
+		class OnNoNestedQuery {
+
+			private final OzgCloudVorgangQuery query = OzgCloudVorgangQueryTestFactory.createBuilder()
+					.query(Optional.empty())
+					.build();
+
+			@Test
+			void shouldMapToGrpcQuery() {
+				var grpcQuery = mapper.toGrpc(query);
+
+				assertThat(grpcQuery).usingRecursiveComparison().isEqualTo(GrpcQueryTestFactory.createBuilder().clearExpressions()
+						.addAllExpressions(List.of(aktenzeichenExpression, formExpression, statusExpression, organisationsEinheitIdExpression))
+						.setLogicalOperator(GrpcLogicalOperator.AND)
+						.build());
+			}
+		}
+
+		@Nested
+		class OnNestedQueryAndOptionals {
+
+			private final OzgCloudVorgangQuery query = OzgCloudVorgangQueryTestFactory.create();
+
+			@Test
+			void shouldMapToGrpcQuery() {
+				var grpcQuery = mapper.toGrpc(query);
+
+				assertThat(grpcQuery).usingRecursiveComparison().isEqualTo(GrpcQueryTestFactory.createBuilder().clearExpressions()
+						.addAllExpressions(List.of(aktenzeichenExpression, formExpression, statusExpression, organisationsEinheitIdExpression))
+						.setLogicalOperator(GrpcLogicalOperator.AND)
+						.setNestedQuery(GrpcQueryTestFactory.create())
+						.build());
+			}
+
+			@Test
+			void shouldMapToDoubleNestedGrpcQuery() {
+				var grpcQuery = mapper.toGrpc(OzgCloudVorgangQueryTestFactory.createBuilder()
+						.query(Optional.of(QueryTestFactory.createBuilder()
+								.nestedQuery(QueryTestFactory.create())
+								.build()))
+						.build());
+
+				assertThat(grpcQuery).usingRecursiveComparison().isEqualTo(GrpcQueryTestFactory.createBuilder().clearExpressions()
+						.addAllExpressions(List.of(aktenzeichenExpression, formExpression, statusExpression, organisationsEinheitIdExpression))
+						.setLogicalOperator(GrpcLogicalOperator.AND)
+						.setNestedQuery(GrpcQueryTestFactory.createBuilder()
+								.setNestedQuery(GrpcQueryTestFactory.create())
+								.build())
+						.build());
+			}
+
+		}
+
+		@Nested
+		class OnOnlyNestedQuery {
+			private final OzgCloudVorgangQuery.OzgCloudVorgangQueryBuilder queryBuilder = OzgCloudVorgangQueryTestFactory.createBuilder()
+					.aktenzeichen(Optional.empty())
+					.form(Optional.empty())
+					.organisationsEinheitId(Optional.empty())
+					.status(Optional.empty());
+
+			@Test
+			void shouldMapToGrpcQuery() {
+				var grpcQuery = mapper.toGrpc(queryBuilder.build());
+
+				assertThat(grpcQuery).usingRecursiveComparison().isEqualTo(GrpcQueryTestFactory.create());
+			}
+
+			@Test
+			void shouldMapToNestedGrpcQuery() {
+				var grpcQuery = mapper.toGrpc(queryBuilder.query(Optional.of(QueryTestFactory.createBuilder()
+						.nestedQuery(QueryTestFactory.create()).build()))
+						.build());
+
+				assertThat(grpcQuery).usingRecursiveComparison().isEqualTo(GrpcQueryTestFactory.createBuilder()
+						.setNestedQuery(GrpcQueryTestFactory.create())
+						.build());
+			}
+		}
+
+		@Nested
+		class OnEmptyQuery {
+
+			private final OzgCloudVorgangQuery query = OzgCloudVorgangQueryTestFactory.createBuilder()
+					.aktenzeichen(Optional.empty())
+					.form(Optional.empty())
+					.organisationsEinheitId(Optional.empty())
+					.status(Optional.empty())
+					.query(Optional.empty())
+					.build();
+
+			@Test
+			void shouldMapToEmptyGrpcQuery() {
+				var grpcQuery = mapper.toGrpc(query);
+
+				assertThat(grpcQuery).usingRecursiveComparison().isEqualTo(GrpcQuery.newBuilder().build());
+			}
+		}
+	}
+}