diff --git a/client-java/controller/pom.xml b/client-java/controller/pom.xml
index e599727ab4..93965fff82 100644
--- a/client-java/controller/pom.xml
+++ b/client-java/controller/pom.xml
@@ -140,6 +140,13 @@
provided
+
+
+ org.antlr
+ antlr4-runtime
+
+
+
com.h2database
h2
@@ -204,10 +211,15 @@
lettuce-core
test
-
software.amazon.awssdk
- netty-nio-client
+ dynamodb
+ test
+
+
+
+ org.slf4j
+ slf4j-simple
test
@@ -227,7 +239,6 @@
grpc-stub
test
-
@@ -265,6 +276,23 @@
maven-compiler-plugin
+
+
+ org.antlr
+ antlr4-maven-plugin
+
+ false
+ true
+
+
+
+
+ antlr4
+
+
+
+
+
+
+ org.antlr
+ shaded.org.antlr
+
+
diff --git a/client-java/controller/src/main/antlr4/org/evomaster/client/java/controller/dynamodb/DynamoDbConditionExpression.g4 b/client-java/controller/src/main/antlr4/org/evomaster/client/java/controller/dynamodb/DynamoDbConditionExpression.g4
new file mode 100644
index 0000000000..81b72a6d5c
--- /dev/null
+++ b/client-java/controller/src/main/antlr4/org/evomaster/client/java/controller/dynamodb/DynamoDbConditionExpression.g4
@@ -0,0 +1,123 @@
+grammar DynamoDbConditionExpression;
+
+expression
+ : orExpr EOF
+ ;
+
+orExpr
+ : andExpr (OR andExpr)*
+ ;
+
+andExpr
+ : notExpr (AND notExpr)*
+ ;
+
+notExpr
+ : NOT notExpr #negatedExpr
+ | primary #primaryExpr
+ ;
+
+primary
+ : LPAREN orExpr RPAREN #parenthesizedPrimary
+ | predicate #predicatePrimary
+ ;
+
+predicate
+ : ATTRIBUTE_EXISTS LPAREN path RPAREN #attributeExistsPredicate
+ | ATTRIBUTE_NOT_EXISTS LPAREN path RPAREN #attributeNotExistsPredicate
+ | ATTRIBUTE_TYPE LPAREN path COMMA value RPAREN #attributeTypePredicate
+ | BEGINS_WITH LPAREN path COMMA value RPAREN #beginsWithPredicate
+ | CONTAINS LPAREN path COMMA value RPAREN #containsPredicate
+ | SIZE LPAREN path RPAREN comparator value #sizePredicate
+ | path BETWEEN value AND value #betweenPredicate
+ | path IN LPAREN value (COMMA value)* RPAREN #inPredicate
+ | path comparator value #comparisonPredicate
+ ;
+
+comparator
+ : EQ
+ | NE
+ | LT
+ | LTE
+ | GT
+ | GTE
+ ;
+
+path
+ : IDENTIFIER
+ ;
+
+value
+ : PLACEHOLDER #placeholderValue
+ | STRING_LITERAL #stringValue
+ | NUMBER_LITERAL #numberValue
+ | BOOLEAN_LITERAL #booleanValue
+ | NULL_LITERAL #nullValue
+ | IDENTIFIER #identifierValue
+ ;
+
+LPAREN : '(';
+RPAREN : ')';
+COMMA : ',';
+EQ : '=';
+NE : '<>';
+LTE : '<=';
+GTE : '>=';
+LT : '<';
+GT : '>';
+
+AND : A N D;
+OR : O R;
+NOT : N O T;
+BETWEEN : B E T W E E N;
+IN : I N;
+ATTRIBUTE_EXISTS : A T T R I B U T E '_' E X I S T S;
+ATTRIBUTE_NOT_EXISTS : A T T R I B U T E '_' N O T '_' E X I S T S;
+ATTRIBUTE_TYPE : A T T R I B U T E '_' T Y P E;
+BEGINS_WITH : B E G I N S '_' W I T H;
+CONTAINS : C O N T A I N S;
+SIZE : S I Z E;
+
+BOOLEAN_LITERAL : T R U E | F A L S E;
+NULL_LITERAL : N U L L;
+
+PLACEHOLDER : ':' IDENT_START IDENT_PART*;
+NUMBER_LITERAL : '-'? DIGIT+ ('.' DIGIT+)? EXPONENT?;
+STRING_LITERAL : '\'' ~['\r\n]* '\'';
+
+IDENTIFIER : IDENT_START IDENT_PART* INDEX* ('.' IDENT_START IDENT_PART* INDEX*)*;
+
+WS : [ \t\r\n]+ -> skip;
+
+fragment INDEX : '[' DIGIT+ ']';
+fragment EXPONENT : [eE] [+\-]? DIGIT+;
+fragment IDENT_START : [a-zA-Z_#];
+fragment IDENT_PART : [a-zA-Z0-9_];
+fragment DIGIT : [0-9];
+
+fragment A : [aA];
+fragment B : [bB];
+fragment C : [cC];
+fragment D : [dD];
+fragment E : [eE];
+fragment F : [fF];
+fragment G : [gG];
+fragment H : [hH];
+fragment I : [iI];
+fragment J : [jJ];
+fragment K : [kK];
+fragment L : [lL];
+fragment M : [mM];
+fragment N : [nN];
+fragment O : [oO];
+fragment P : [pP];
+fragment Q : [qQ];
+fragment R : [rR];
+fragment S : [sS];
+fragment T : [tT];
+fragment U : [uU];
+fragment V : [vV];
+fragment W : [wW];
+fragment X : [xX];
+fragment Y : [yY];
+fragment Z : [zZ];
diff --git a/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/DynamoDbAttributeValueHelper.java b/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/DynamoDbAttributeValueHelper.java
new file mode 100644
index 0000000000..1ac2a78c64
--- /dev/null
+++ b/client-java/controller/src/main/java/org/evomaster/client/java/controller/dynamodb/DynamoDbAttributeValueHelper.java
@@ -0,0 +1,231 @@
+package org.evomaster.client.java.controller.dynamodb;
+
+import java.nio.ByteBuffer;
+import java.util.*;
+
+/**
+ * Utilities to deal with DynamoDB SDK request/response values without
+ * introducing direct compile-time dependencies to AWS SDK classes.
+ */
+public final class DynamoDbAttributeValueHelper {
+
+ /**
+ * Reflection-bound AWS AttributeValue accessors. Keep these literals unchanged:
+ * they must match SDK method names exactly.
+ */
+ private static final String METHOD_NUL = "nul";
+ private static final String METHOD_S = "s";
+ private static final String METHOD_N = "n";
+ private static final String METHOD_BOOL = "bool";
+ private static final String METHOD_HAS_M = "hasM";
+ private static final String METHOD_M = "m";
+ private static final String METHOD_HAS_L = "hasL";
+ private static final String METHOD_L = "l";
+ private static final String METHOD_HAS_SS = "hasSs";
+ private static final String METHOD_SS = "ss";
+ private static final String METHOD_HAS_NS = "hasNs";
+ private static final String METHOD_NS = "ns";
+ private static final String METHOD_HAS_BS = "hasBs";
+ private static final String METHOD_BS = "bs";
+ private static final String METHOD_B = "b";
+
+ private static final String DECIMAL_SEPARATOR = ".";
+ private static final String SCIENTIFIC_NOTATION_E_LOWER = "e";
+ private static final String SCIENTIFIC_NOTATION_E_UPPER = "E";
+
+ /**
+ * Utility class, no instances.
+ */
+ private DynamoDbAttributeValueHelper() {
+ }
+
+ /**
+ * Converts a map of DynamoDB attribute values into plain Java values.
+ *
+ * @param source input object expected to be a map
+ * @return normalized map or empty map when input is not a map
+ */
+ public static Map toPlainMap(Object source) {
+ if (!(source instanceof Map, ?>)) {
+ return Collections.emptyMap();
+ }
+
+ Map result = new LinkedHashMap<>();
+ ((Map, ?>) source).forEach((key, value) -> {
+ if (key != null) {
+ result.put(String.valueOf(key), toPlainValue(value));
+ }
+ });
+ return result;
+ }
+
+ /**
+ * Converts one DynamoDB attribute value object into a plain Java value.
+ *
+ * @param value attribute value object
+ * @return normalized Java value
+ */
+ @SuppressWarnings("unchecked")
+ public static Object toPlainValue(Object value) {
+ if (value == null) {
+ return null;
+ }
+
+ if (value instanceof Map, ?>) {
+ return toPlainMap(value);
+ }
+
+ if (value instanceof Collection>) {
+ return toPlainList((Collection