From e130932bb1b491c4b951979ab041ba277652b20c Mon Sep 17 00:00:00 2001
From: rschoene <rene.schoene@tu-dresden.de>
Date: Fri, 2 Sep 2022 14:52:57 +0200
Subject: [PATCH] move TestUtils to separate package

- also extracted inner classes
---
 .../ragconnect/tests/AbstractMqttTest.java    |   3 +-
 .../ragconnect/tests/AttributeTest.java       |   5 +-
 .../tests/ContextFreeSimpleTest.java          |  11 +-
 .../ragconnect/tests/DefaultOnlyReadTest.java |  38 +-
 .../tests/DefaultOnlyWriteTest.java           |  34 +-
 .../org/jastadd/ragconnect/tests/Errors.java  |   5 +-
 .../jastadd/ragconnect/tests/ExampleTest.java |   7 +-
 .../ragconnect/tests/ForwardingTest.java      |   4 +-
 .../tests/IncrementalDependencyTest.java      |  10 +-
 .../ragconnect/tests/IndexedSendTest.java     |   6 +-
 .../jastadd/ragconnect/tests/JavaTest.java    |   7 +-
 .../jastadd/ragconnect/tests/MappingTest.java |  18 +-
 .../ragconnect/tests/MqttHandlerTest.java     |   1 +
 .../ragconnect/tests/Read1Write2Test.java     |  16 +-
 .../ragconnect/tests/Read2Write1Test.java     |  10 +-
 .../ragconnect/tests/RegressionTests.java     |   1 +
 .../jastadd/ragconnect/tests/TestUtils.java   | 642 ------------------
 .../ragconnect/tests/TutorialTest.java        |   2 +-
 .../org/jastadd/ragconnect/tests/ViaTest.java |  14 +-
 .../jastadd/ragconnect/tests/Warnings.java    |   5 +-
 .../tests/list/AbstractListTest.java          |   8 +-
 .../tests/list/ListIncrementalTest.java       |   4 +-
 .../ragconnect/tests/list/ListManualTest.java |   4 +-
 .../tests/relation/RelationTest.java          |   7 +-
 .../singleList/AbstractSingleListTest.java    |   8 +-
 .../AbstractSingleListVariantTest.java        |  10 +-
 .../SingleListVariantIncrementalTest.java     |   2 +-
 .../SingleListVariantManualTest.java          |   2 +-
 .../AbstractTokenValueSendTest.java           |  18 +-
 .../TokenValueSendIncrementalTest.java        |   2 +-
 .../tokenValue/TokenValueSendManualTest.java  |   2 +-
 .../tests/tree/AbstractTreeTest.java          |   2 +-
 .../tests/tree/TreeIncrementalTest.java       |   6 +-
 .../ragconnect/tests/tree/TreeManualTest.java |   7 +-
 .../AbstractTreeAllowedTokensTest.java        |  11 +-
 .../TreeAllowedTokensIncrementalTest.java     |   6 +-
 .../TreeAllowedTokensManualTest.java          |   7 +-
 .../tests/utils/ChangeObserver.java           |  49 ++
 .../tests/utils/DefaultMappings.java          | 246 +++++++
 .../ragconnect/tests/utils/IntList.java       |  31 +
 .../ragconnect/tests/utils/TestChecker.java   | 222 ++++++
 .../ragconnect/tests/utils/TestUtils.java     | 181 +++++
 42 files changed, 891 insertions(+), 783 deletions(-)
 delete mode 100644 ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java
 create mode 100644 ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/ChangeObserver.java
 create mode 100644 ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/DefaultMappings.java
 create mode 100644 ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/IntList.java
 create mode 100644 ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/TestChecker.java
 create mode 100644 ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/TestUtils.java

diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/AbstractMqttTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/AbstractMqttTest.java
index b8f31b8..9720f2f 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/AbstractMqttTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/AbstractMqttTest.java
@@ -2,9 +2,8 @@ package org.jastadd.ragconnect.tests;
 
 import defaultOnlyRead.ast.MqttHandler;
 import io.github.artsok.RepeatedIfExceptionsTest;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.*;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/AttributeTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/AttributeTest.java
index afc5cab..7073e6d 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/AttributeTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/AttributeTest.java
@@ -2,6 +2,7 @@ package org.jastadd.ragconnect.tests;
 
 import attributeInc.ast.*;
 import de.tudresden.inf.st.jastadd.dumpAst.ast.Dumper;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Tag;
 
@@ -12,11 +13,11 @@ import java.util.concurrent.Callable;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
-import org.jastadd.ragconnect.tests.TestUtils.TestChecker;
+import org.jastadd.ragconnect.tests.utils.TestChecker;
 
 import static java.util.function.Predicate.isEqual;
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.jastadd.ragconnect.tests.TestUtils.*;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.*;
 import static org.junit.jupiter.api.Assertions.*;
 
 /**
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ContextFreeSimpleTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ContextFreeSimpleTest.java
index 82588b7..a74b4d9 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ContextFreeSimpleTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ContextFreeSimpleTest.java
@@ -4,13 +4,16 @@ import contextFreeSimpleInc.ast.A;
 import contextFreeSimpleInc.ast.MqttHandler;
 import contextFreeSimpleInc.ast.Root;
 import contextFreeSimpleInc.ast.SerializationException;
+import org.jastadd.ragconnect.tests.utils.DefaultMappings;
+import org.jastadd.ragconnect.tests.utils.TestChecker;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Tag;
 
 import java.io.IOException;
 import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
 import static org.junit.jupiter.api.Assertions.*;
 
 /**
@@ -41,7 +44,7 @@ public class ContextFreeSimpleTest extends AbstractMqttTest {
 
   private ReceiverData data;
   private MqttHandler handler;
-  private TestUtils.TestChecker checker;
+  private TestChecker checker;
 
   @Override
   protected void createModel() {
@@ -70,7 +73,7 @@ public class ContextFreeSimpleTest extends AbstractMqttTest {
 
     handler.newConnection(TOPIC_WILDCARD, (topic, bytes) -> data.valuesSent += 1);
 
-    checker = new TestUtils.TestChecker();
+    checker = new TestChecker();
     checker.alwaysWait()
             .setCheckForString(TOPIC_UNNAMED, (name, expected) -> this.check(name, expected, model.getA(), unnamedA))
             .setCheckForString(TOPIC_SINGLE, (name, expected) -> this.check(name, expected, model.getSingleA(), singleA))
@@ -143,7 +146,7 @@ public class ContextFreeSimpleTest extends AbstractMqttTest {
   private void send(String topic, String value) throws IOException {
     A a = new A().setValue(value);
     try {
-      publisher.publish(topic, TestUtils.DefaultMappings.TreeToBytes(a::serialize));
+      publisher.publish(topic, DefaultMappings.TreeToBytes(a::serialize));
     } catch (SerializationException e) {
       throw new IOException(e);
     }
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyReadTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyReadTest.java
index 356f2b1..f72a80a 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyReadTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyReadTest.java
@@ -3,14 +3,16 @@ package org.jastadd.ragconnect.tests;
 import defaultOnlyRead.ast.A;
 import defaultOnlyRead.ast.BoxedTypes;
 import defaultOnlyRead.ast.NativeTypes;
+import org.jastadd.ragconnect.tests.utils.DefaultMappings;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Test;
 
 import java.io.IOException;
 import java.nio.file.Paths;
 import java.util.concurrent.TimeUnit;
 
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
-import static org.jastadd.ragconnect.tests.TestUtils.testJaddContainReferenceToJackson;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.testJaddContainReferenceToJackson;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -119,22 +121,22 @@ public class DefaultOnlyReadTest extends AbstractMqttTest {
     final char expectedCharValue = 'c';
     final String expectedStringValue = "6.3";
 
-    publisher.publish(TOPIC_NATIVE_BOOLEAN, TestUtils.DefaultMappings.BoolToBytes(expectedBooleanValue));
-    publisher.publish(TOPIC_NATIVE_INT, TestUtils.DefaultMappings.IntToBytes(expectedIntValue));
-    publisher.publish(TOPIC_NATIVE_SHORT, TestUtils.DefaultMappings.ShortToBytes(expectedShortValue));
-    publisher.publish(TOPIC_NATIVE_LONG, TestUtils.DefaultMappings.LongToBytes(expectedLongValue));
-    publisher.publish(TOPIC_NATIVE_FLOAT, TestUtils.DefaultMappings.FloatToBytes(expectedFloatValue));
-    publisher.publish(TOPIC_NATIVE_DOUBLE, TestUtils.DefaultMappings.DoubleToBytes(expectedDoubleValue));
-    publisher.publish(TOPIC_NATIVE_CHAR, TestUtils.DefaultMappings.CharToBytes(expectedCharValue));
-    publisher.publish(TOPIC_NATIVE_STRING, TestUtils.DefaultMappings.StringToBytes(expectedStringValue));
-
-    publisher.publish(TOPIC_BOXED_BOOLEAN, TestUtils.DefaultMappings.BoolToBytes(expectedBooleanValue));
-    publisher.publish(TOPIC_BOXED_INTEGER, TestUtils.DefaultMappings.IntToBytes(expectedIntValue));
-    publisher.publish(TOPIC_BOXED_SHORT, TestUtils.DefaultMappings.ShortToBytes(expectedShortValue));
-    publisher.publish(TOPIC_BOXED_LONG, TestUtils.DefaultMappings.LongToBytes(expectedLongValue));
-    publisher.publish(TOPIC_BOXED_FLOAT, TestUtils.DefaultMappings.FloatToBytes(expectedFloatValue));
-    publisher.publish(TOPIC_BOXED_DOUBLE, TestUtils.DefaultMappings.DoubleToBytes(expectedDoubleValue));
-    publisher.publish(TOPIC_BOXED_CHARACTER, TestUtils.DefaultMappings.CharToBytes(expectedCharValue));
+    publisher.publish(TOPIC_NATIVE_BOOLEAN, DefaultMappings.BoolToBytes(expectedBooleanValue));
+    publisher.publish(TOPIC_NATIVE_INT, DefaultMappings.IntToBytes(expectedIntValue));
+    publisher.publish(TOPIC_NATIVE_SHORT, DefaultMappings.ShortToBytes(expectedShortValue));
+    publisher.publish(TOPIC_NATIVE_LONG, DefaultMappings.LongToBytes(expectedLongValue));
+    publisher.publish(TOPIC_NATIVE_FLOAT, DefaultMappings.FloatToBytes(expectedFloatValue));
+    publisher.publish(TOPIC_NATIVE_DOUBLE, DefaultMappings.DoubleToBytes(expectedDoubleValue));
+    publisher.publish(TOPIC_NATIVE_CHAR, DefaultMappings.CharToBytes(expectedCharValue));
+    publisher.publish(TOPIC_NATIVE_STRING, DefaultMappings.StringToBytes(expectedStringValue));
+
+    publisher.publish(TOPIC_BOXED_BOOLEAN, DefaultMappings.BoolToBytes(expectedBooleanValue));
+    publisher.publish(TOPIC_BOXED_INTEGER, DefaultMappings.IntToBytes(expectedIntValue));
+    publisher.publish(TOPIC_BOXED_SHORT, DefaultMappings.ShortToBytes(expectedShortValue));
+    publisher.publish(TOPIC_BOXED_LONG, DefaultMappings.LongToBytes(expectedLongValue));
+    publisher.publish(TOPIC_BOXED_FLOAT, DefaultMappings.FloatToBytes(expectedFloatValue));
+    publisher.publish(TOPIC_BOXED_DOUBLE, DefaultMappings.DoubleToBytes(expectedDoubleValue));
+    publisher.publish(TOPIC_BOXED_CHARACTER, DefaultMappings.CharToBytes(expectedCharValue));
 
     TestUtils.waitForMqtt();
 
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyWriteTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyWriteTest.java
index d30912c..b56f5dd 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyWriteTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/DefaultOnlyWriteTest.java
@@ -4,13 +4,15 @@ import defaultOnlyWrite.ast.A;
 import defaultOnlyWrite.ast.BoxedTypesSyn;
 import defaultOnlyWrite.ast.MqttHandler;
 import defaultOnlyWrite.ast.NativeTypesSyn;
+import org.jastadd.ragconnect.tests.utils.DefaultMappings;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Test;
 
 import java.io.IOException;
 import java.nio.file.Paths;
 import java.util.concurrent.TimeUnit;
 
-import static org.jastadd.ragconnect.tests.TestUtils.*;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.*;
 import static org.junit.jupiter.api.Assertions.*;
 
 /**
@@ -177,63 +179,63 @@ public class DefaultOnlyWriteTest extends AbstractMqttTest {
 
     receiver.newConnection(transformed ? TOPIC_NATIVE_BOOLEAN_TRANSFORMED : TOPIC_NATIVE_BOOLEAN, bytes -> {
       result.numberOfNativeBoolValues += 1;
-      result.lastNativeBoolValue = TestUtils.DefaultMappings.BytesToBool(bytes);
+      result.lastNativeBoolValue = DefaultMappings.BytesToBool(bytes);
     });
     receiver.newConnection(transformed ? TOPIC_NATIVE_INT_TRANSFORMED : TOPIC_NATIVE_INT, bytes -> {
       result.numberOfNativeIntValues += 1;
-      result.lastNativeIntValue = TestUtils.DefaultMappings.BytesToInt(bytes);
+      result.lastNativeIntValue = DefaultMappings.BytesToInt(bytes);
     });
     receiver.newConnection(transformed ? TOPIC_NATIVE_SHORT_TRANSFORMED : TOPIC_NATIVE_SHORT, bytes -> {
       result.numberOfNativeShortValues += 1;
-      result.lastNativeShortValue = TestUtils.DefaultMappings.BytesToShort(bytes);
+      result.lastNativeShortValue = DefaultMappings.BytesToShort(bytes);
     });
     receiver.newConnection(transformed ? TOPIC_NATIVE_LONG_TRANSFORMED : TOPIC_NATIVE_LONG, bytes -> {
       result.numberOfNativeLongValues += 1;
-      result.lastNativeLongValue = TestUtils.DefaultMappings.BytesToLong(bytes);
+      result.lastNativeLongValue = DefaultMappings.BytesToLong(bytes);
     });
     receiver.newConnection(transformed ? TOPIC_NATIVE_FLOAT_TRANSFORMED : TOPIC_NATIVE_FLOAT, bytes -> {
       result.numberOfNativeFloatValues += 1;
-      result.lastNativeFloatValue = TestUtils.DefaultMappings.BytesToFloat(bytes);
+      result.lastNativeFloatValue = DefaultMappings.BytesToFloat(bytes);
     });
     receiver.newConnection(transformed ? TOPIC_NATIVE_DOUBLE_TRANSFORMED : TOPIC_NATIVE_DOUBLE, bytes -> {
       result.numberOfNativeDoubleValues += 1;
-      result.lastNativeDoubleValue = TestUtils.DefaultMappings.BytesToDouble(bytes);
+      result.lastNativeDoubleValue = DefaultMappings.BytesToDouble(bytes);
     });
     receiver.newConnection(transformed ? TOPIC_NATIVE_CHAR_TRANSFORMED : TOPIC_NATIVE_CHAR, bytes -> {
       result.numberOfNativeCharValues += 1;
-      result.lastNativeCharValue = TestUtils.DefaultMappings.BytesToChar(bytes);
+      result.lastNativeCharValue = DefaultMappings.BytesToChar(bytes);
     });
     receiver.newConnection(transformed ? TOPIC_NATIVE_STRING_TRANSFORMED : TOPIC_NATIVE_STRING, bytes -> {
       result.numberOfNativeStringValues += 1;
-      result.lastNativeStringValue = TestUtils.DefaultMappings.BytesToString(bytes);
+      result.lastNativeStringValue = DefaultMappings.BytesToString(bytes);
     });
     receiver.newConnection(transformed ? TOPIC_BOXED_BOOLEAN_TRANSFORMED : TOPIC_BOXED_BOOLEAN, bytes -> {
       result.numberOfBoxedBoolValues += 1;
-      result.lastBoxedBoolValue = TestUtils.DefaultMappings.BytesToBool(bytes);
+      result.lastBoxedBoolValue = DefaultMappings.BytesToBool(bytes);
     });
     receiver.newConnection(transformed ? TOPIC_BOXED_INTEGER_TRANSFORMED : TOPIC_BOXED_INTEGER, bytes -> {
       result.numberOfBoxedIntValues += 1;
-      result.lastBoxedIntValue = TestUtils.DefaultMappings.BytesToInt(bytes);
+      result.lastBoxedIntValue = DefaultMappings.BytesToInt(bytes);
     });
     receiver.newConnection(transformed ? TOPIC_BOXED_SHORT_TRANSFORMED : TOPIC_BOXED_SHORT, bytes -> {
       result.numberOfBoxedShortValues += 1;
-      result.lastBoxedShortValue = TestUtils.DefaultMappings.BytesToShort(bytes);
+      result.lastBoxedShortValue = DefaultMappings.BytesToShort(bytes);
     });
     receiver.newConnection(transformed ? TOPIC_BOXED_LONG_TRANSFORMED : TOPIC_BOXED_LONG, bytes -> {
       result.numberOfBoxedLongValues += 1;
-      result.lastBoxedLongValue = TestUtils.DefaultMappings.BytesToLong(bytes);
+      result.lastBoxedLongValue = DefaultMappings.BytesToLong(bytes);
     });
     receiver.newConnection(transformed ? TOPIC_BOXED_FLOAT_TRANSFORMED : TOPIC_BOXED_FLOAT, bytes -> {
       result.numberOfBoxedFloatValues += 1;
-      result.lastBoxedFloatValue = TestUtils.DefaultMappings.BytesToFloat(bytes);
+      result.lastBoxedFloatValue = DefaultMappings.BytesToFloat(bytes);
     });
     receiver.newConnection(transformed ? TOPIC_BOXED_DOUBLE_TRANSFORMED : TOPIC_BOXED_DOUBLE, bytes -> {
       result.numberOfBoxedDoubleValues += 1;
-      result.lastBoxedDoubleValue = TestUtils.DefaultMappings.BytesToDouble(bytes);
+      result.lastBoxedDoubleValue = DefaultMappings.BytesToDouble(bytes);
     });
     receiver.newConnection(transformed ? TOPIC_BOXED_CHARACTER_TRANSFORMED : TOPIC_BOXED_CHARACTER, bytes -> {
       result.numberOfBoxedCharValues += 1;
-      result.lastBoxedCharValue = TestUtils.DefaultMappings.BytesToChar(bytes);
+      result.lastBoxedCharValue = DefaultMappings.BytesToChar(bytes);
     });
     return result;
   }
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Errors.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Errors.java
index 9d4c730..c4be09c 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Errors.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Errors.java
@@ -1,9 +1,8 @@
 package org.jastadd.ragconnect.tests;
 
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import java.io.File;
 import java.io.IOException;
@@ -14,7 +13,7 @@ import java.util.List;
 import java.util.stream.Collectors;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.jastadd.ragconnect.tests.TestUtils.readFile;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.readFile;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 /**
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ExampleTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ExampleTest.java
index 143c76b..cc9faca 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ExampleTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ExampleTest.java
@@ -3,7 +3,8 @@ package org.jastadd.ragconnect.tests;
 import com.google.protobuf.InvalidProtocolBufferException;
 import config.Config.RobotConfig;
 import example.ast.*;
-import org.jastadd.ragconnect.tests.TestUtils.TestChecker;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
+import org.jastadd.ragconnect.tests.utils.TestChecker;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import robot.RobotStateOuterClass.RobotState;
@@ -11,8 +12,8 @@ import robot.RobotStateOuterClass.RobotState;
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
-import static org.jastadd.ragconnect.tests.TestUtils.waitForMqtt;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.waitForMqtt;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ForwardingTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ForwardingTest.java
index 314ad3f..3efa2e6 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ForwardingTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ForwardingTest.java
@@ -1,6 +1,8 @@
 package org.jastadd.ragconnect.tests;
 
 import forwardingInc.ast.*;
+import org.jastadd.ragconnect.tests.utils.TestChecker;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Tag;
 
 import java.io.IOException;
@@ -11,7 +13,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.groups.Tuple.tuple;
-import static org.jastadd.ragconnect.tests.TestUtils.*;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.*;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 /**
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/IncrementalDependencyTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/IncrementalDependencyTest.java
index 46e944c..2d441ad 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/IncrementalDependencyTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/IncrementalDependencyTest.java
@@ -3,12 +3,14 @@ package org.jastadd.ragconnect.tests;
 import incremental.ast.A;
 import incremental.ast.B;
 import incremental.ast.MqttHandler;
+import org.jastadd.ragconnect.tests.utils.DefaultMappings;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Tag;
 
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
 import static org.junit.jupiter.api.Assertions.*;
 
 /**
@@ -61,15 +63,15 @@ public class IncrementalDependencyTest extends AbstractMqttTest {
 
     handler.newConnection(TOPIC_OUT_A, bytes -> {
       dataA.numberOfStringValues += 1;
-      dataA.lastStringValue = TestUtils.DefaultMappings.BytesToString(bytes);
+      dataA.lastStringValue = DefaultMappings.BytesToString(bytes);
     });
     handler.newConnection(TOPIC_OUT_B1, bytes -> {
       dataB1.numberOfStringValues += 1;
-      dataB1.lastStringValue = TestUtils.DefaultMappings.BytesToString(bytes);
+      dataB1.lastStringValue = DefaultMappings.BytesToString(bytes);
     });
     handler.newConnection(TOPIC_OUT_B2, bytes -> {
       dataB2.numberOfStringValues += 1;
-      dataB2.lastStringValue = TestUtils.DefaultMappings.BytesToString(bytes);
+      dataB2.lastStringValue = DefaultMappings.BytesToString(bytes);
     });
 
     assertTrue(model.connectInput(mqttUri(TOPIC_IN)));
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/IndexedSendTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/IndexedSendTest.java
index dc1bdda..7ea7ed8 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/IndexedSendTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/IndexedSendTest.java
@@ -4,6 +4,8 @@ import indexedSendInc.ast.*;
 import io.github.artsok.RepeatedIfExceptionsTest;
 import org.assertj.core.api.Assertions;
 import org.assertj.core.groups.Tuple;
+import org.jastadd.ragconnect.tests.utils.TestChecker;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Tag;
 
 import java.io.IOException;
@@ -13,7 +15,7 @@ import java.util.function.Predicate;
 import java.util.function.Supplier;
 
 import static org.assertj.core.groups.Tuple.tuple;
-import static org.jastadd.ragconnect.tests.TestUtils.*;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.*;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -40,7 +42,7 @@ public class IndexedSendTest extends AbstractMqttTest {
 
   private MqttHandler handler;
   private ReceiverData data;
-  private TestUtils.TestChecker checker;
+  private TestChecker checker;
 
   private Root model;
   private SenderRoot senderRoot;
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/JavaTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/JavaTest.java
index 0c33e9c..81d2817 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/JavaTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/JavaTest.java
@@ -2,18 +2,15 @@ package org.jastadd.ragconnect.tests;
 
 import javaInc.ast.*;
 import org.assertj.core.groups.Tuple;
-import org.jastadd.ragconnect.tests.TestUtils.TestChecker;
+import org.jastadd.ragconnect.tests.utils.TestChecker;
 import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
 import java.util.List;
 
 import static org.assertj.core.api.Assertions.tuple;
-import static org.jastadd.ragconnect.tests.TestUtils.javaUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.javaUri;
 import static org.junit.jupiter.api.Assertions.*;
 
 /**
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/MappingTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/MappingTest.java
index f1cafb0..519b802 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/MappingTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/MappingTest.java
@@ -4,11 +4,13 @@ import mapping.ast.A;
 import mapping.ast.BoxedTypes;
 import mapping.ast.MqttHandler;
 import mapping.ast.NativeTypes;
+import org.jastadd.ragconnect.tests.utils.DefaultMappings;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -62,31 +64,31 @@ public class MappingTest extends AbstractMqttTest {
     data = new ReceiverData();
     handler.newConnection(TOPIC_WRITE_NATIVE_INT, bytes -> {
       data.numberOfNativeIntValues += 1;
-      data.lastNativeIntValue = TestUtils.DefaultMappings.BytesToInt(bytes);
+      data.lastNativeIntValue = DefaultMappings.BytesToInt(bytes);
     });
     handler.newConnection(TOPIC_WRITE_NATIVE_SHORT, bytes -> {
       data.numberOfNativeShortValues += 1;
-      data.lastNativeShortValue = TestUtils.DefaultMappings.BytesToShort(bytes);
+      data.lastNativeShortValue = DefaultMappings.BytesToShort(bytes);
     });
     handler.newConnection(TOPIC_WRITE_NATIVE_LONG, bytes -> {
       data.numberOfNativeLongValues += 1;
-      data.lastNativeLongValue = TestUtils.DefaultMappings.BytesToLong(bytes);
+      data.lastNativeLongValue = DefaultMappings.BytesToLong(bytes);
     });
     handler.newConnection(TOPIC_WRITE_NATIVE_FLOAT, bytes -> {
       data.numberOfNativeFloatValues += 1;
-      data.lastNativeFloatValue = TestUtils.DefaultMappings.BytesToFloat(bytes);
+      data.lastNativeFloatValue = DefaultMappings.BytesToFloat(bytes);
     });
     handler.newConnection(TOPIC_WRITE_NATIVE_DOUBLE, bytes -> {
       data.numberOfNativeDoubleValues += 1;
-      data.lastNativeDoubleValue = TestUtils.DefaultMappings.BytesToDouble(bytes);
+      data.lastNativeDoubleValue = DefaultMappings.BytesToDouble(bytes);
     });
     handler.newConnection(TOPIC_WRITE_NATIVE_CHAR, bytes -> {
       data.numberOfNativeCharValues += 1;
-      data.lastNativeCharValue = TestUtils.DefaultMappings.BytesToChar(bytes);
+      data.lastNativeCharValue = DefaultMappings.BytesToChar(bytes);
     });
     handler.newConnection(TOPIC_WRITE_NATIVE_BOOLEAN, bytes -> {
       data.numberOfNativeBooleanValues += 1;
-      data.lastNativeBooleanValue = TestUtils.DefaultMappings.BytesToBool(bytes);
+      data.lastNativeBooleanValue = DefaultMappings.BytesToBool(bytes);
     });
 
     assertTrue(natives.connectWriteIntValue(mqttUri(TOPIC_WRITE_NATIVE_INT), isWriteCurrentValue()));
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/MqttHandlerTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/MqttHandlerTest.java
index be61201..f8b127e 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/MqttHandlerTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/MqttHandlerTest.java
@@ -1,6 +1,7 @@
 package org.jastadd.ragconnect.tests;
 
 import example.ast.MqttHandler;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
 
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read1Write2Test.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read1Write2Test.java
index 4deccef..155109f 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read1Write2Test.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read1Write2Test.java
@@ -1,11 +1,13 @@
 package org.jastadd.ragconnect.tests;
 
+import org.jastadd.ragconnect.tests.utils.DefaultMappings;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import read1write2.ast.*;
 
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -75,29 +77,29 @@ public class Read1Write2Test extends AbstractMqttTest {
 
     handler.newConnection(TOPIC_SAME_WRITE_INT, bytes -> {
       dataSame.numberOfIntValues += 1;
-      dataSame.lastIntValue = TestUtils.DefaultMappings.BytesToInt(bytes);
+      dataSame.lastIntValue = DefaultMappings.BytesToInt(bytes);
     });
     handler.newConnection(TOPIC_SAME_WRITE_STRING, bytes -> {
       dataSame.numberOfStringValues += 1;
-      dataSame.lastStringValue = TestUtils.DefaultMappings.BytesToString(bytes);
+      dataSame.lastStringValue = DefaultMappings.BytesToString(bytes);
     });
 
     handler.newConnection(TOPIC_DIFFERENT_WRITE1_INT, bytes -> {
       dataOther1.numberOfIntValues += 1;
-      dataOther1.lastIntValue = TestUtils.DefaultMappings.BytesToInt(bytes);
+      dataOther1.lastIntValue = DefaultMappings.BytesToInt(bytes);
     });
     handler.newConnection(TOPIC_DIFFERENT_WRITE1_STRING, bytes -> {
       dataOther1.numberOfStringValues += 1;
-      dataOther1.lastStringValue = TestUtils.DefaultMappings.BytesToString(bytes);
+      dataOther1.lastStringValue = DefaultMappings.BytesToString(bytes);
     });
 
     handler.newConnection(TOPIC_DIFFERENT_WRITE2_INT, bytes -> {
       dataOther2.numberOfIntValues += 1;
-      dataOther2.lastIntValue = TestUtils.DefaultMappings.BytesToInt(bytes);
+      dataOther2.lastIntValue = DefaultMappings.BytesToInt(bytes);
     });
     handler.newConnection(TOPIC_DIFFERENT_WRITE2_STRING, bytes -> {
       dataOther2.numberOfStringValues += 1;
-      dataOther2.lastStringValue = TestUtils.DefaultMappings.BytesToString(bytes);
+      dataOther2.lastStringValue = DefaultMappings.BytesToString(bytes);
     });
 
     assertTrue(onSameNonterminal.connectInput(mqttUri(TOPIC_SAME_READ)));
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read2Write1Test.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read2Write1Test.java
index f931c13..0bd2219 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read2Write1Test.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Read2Write1Test.java
@@ -1,11 +1,13 @@
 package org.jastadd.ragconnect.tests;
 
+import org.jastadd.ragconnect.tests.utils.DefaultMappings;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import read2write1.ast.*;
 
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -76,17 +78,17 @@ public class Read2Write1Test extends AbstractMqttTest {
 
     handler.newConnection(TOPIC_SAME_WRITE_INT, bytes -> {
       dataSame.numberOfIntValues += 1;
-      dataSame.lastIntValue = TestUtils.DefaultMappings.BytesToInt(bytes);
+      dataSame.lastIntValue = DefaultMappings.BytesToInt(bytes);
     });
 
     handler.newConnection(TOPIC_DIFFERENT_WRITE1_INT, bytes -> {
       dataOther1.numberOfIntValues += 1;
-      dataOther1.lastIntValue = TestUtils.DefaultMappings.BytesToInt(bytes);
+      dataOther1.lastIntValue = DefaultMappings.BytesToInt(bytes);
     });
 
     handler.newConnection(TOPIC_DIFFERENT_WRITE2_INT, bytes -> {
       dataOther2.numberOfIntValues += 1;
-      dataOther2.lastIntValue = TestUtils.DefaultMappings.BytesToInt(bytes);
+      dataOther2.lastIntValue = DefaultMappings.BytesToInt(bytes);
     });
 
     assertTrue(onSameNonterminal.connectInput1(mqttUri(TOPIC_SAME_READ1)));
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/RegressionTests.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/RegressionTests.java
index 5f74942..92a2c4b 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/RegressionTests.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/RegressionTests.java
@@ -1,5 +1,6 @@
 package org.jastadd.ragconnect.tests;
 
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Test;
 import via.ast.A;
 
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java
deleted file mode 100644
index c5b0fd9..0000000
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TestUtils.java
+++ /dev/null
@@ -1,642 +0,0 @@
-package org.jastadd.ragconnect.tests;
-
-import com.fasterxml.jackson.core.JsonEncoding;
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.core.JsonGenerator;
-import org.assertj.core.groups.Tuple;
-import org.awaitility.Awaitility;
-import org.awaitility.core.ConditionFactory;
-import org.jastadd.ragconnect.compiler.Compiler;
-import org.junit.jupiter.api.Assertions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.*;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-import java.util.function.BiConsumer;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
-
-/**
- * Utility methods for tests.
- *
- * @author rschoene - Initial contribution
- */
-public class TestUtils {
-
-  private static final Logger logger = LoggerFactory.getLogger(TestUtils.class);
-  public static final double DELTA = 0.001d;
-  public static final String INPUT_DIRECTORY_PREFIX = "./src/test/01-input/";
-  public static final String OUTPUT_DIRECTORY_PREFIX = "./src/test/02-after-ragconnect/";
-
-  public static boolean isCi() {
-    return System.getenv("GITLAB_CI") != null;
-  }
-
-  public static String getMqttHost() {
-    if (isCi()) {
-      // we are in the CI, so use "mqtt" as host
-      return "mqtt";
-    } {
-      // else assume a locally running mqtt broker
-      return "localhost";
-    }
-  }
-
-  public static String mqttUri(String path) {
-    return "mqtt://" + getMqttHost() + "/" + path;
-  }
-
-  public static String restUri(String path, int port) {
-    return "rest://localhost:" + port + "/" + path;
-  }
-
-  public static String javaUri(String path) {
-    return "java://localhost/" + path;
-  }
-
-  public static int getMqttDefaultPort() {
-    return 1883;
-  }
-
-  public static Path runCompiler(String grammarFile, Iterable<String> connectFiles, String rootNode, String outputDirectory, int expectedReturnValue, String... additionalArguments) {
-
-    assertThat(connectFiles).isNotEmpty();
-
-    Path outPath = Paths.get(OUTPUT_DIRECTORY_PREFIX)
-        .resolve(outputDirectory)
-        .resolve("Compiler.out");
-    ensureCreated(outPath.getParent());
-
-    try {
-      logger.debug("user.dir: {}", System.getProperty("user.dir"));
-      List<String> args = new ArrayList<>() {{
-        add("--o=" + OUTPUT_DIRECTORY_PREFIX + outputDirectory);
-        add("--rootNode=" + rootNode);
-        add("--verbose");
-        add(INPUT_DIRECTORY_PREFIX + grammarFile);
-      }};
-      connectFiles.forEach(connectFile -> args.add(INPUT_DIRECTORY_PREFIX + connectFile));
-      args.addAll(Arrays.asList(additionalArguments));
-
-      int returnValue = exec(Compiler.class, args.toArray(new String[0]), outPath.toFile());
-      Assertions.assertEquals(expectedReturnValue, returnValue, "RagConnect did not return with value " + expectedReturnValue);
-    } catch (IOException | InterruptedException e) {
-      fail(e);
-    }
-    return outPath;
-  }
-
-  public static <T> String prettyPrint(Iterable<T> aList, Function<T, String> elementPrinter) {
-    StringJoiner sj = new StringJoiner(", ", "[", "]");
-    aList.forEach(element -> sj.add(elementPrinter.apply(element)));
-    return sj.toString();
-  }
-
-  public static void assertLinesMatch(String directory, String expectedName, String out) throws IOException {
-    Path expectedPath = Paths.get(TestUtils.INPUT_DIRECTORY_PREFIX)
-            .resolve(directory)
-            .resolve(expectedName + ".expected");
-    String expected = readFile(expectedPath, Charset.defaultCharset());
-    List<String> outList = Arrays.asList(out.split("\n"));
-    Collections.sort(outList);
-    List<String> expectedList = Arrays.stream(expected.split("\n"))
-            .sorted()
-            .filter(s -> !s.isEmpty() && !s.startsWith("//"))
-            .collect(Collectors.toList());
-
-    Assertions.assertLinesMatch(expectedList, outList);
-  }
-
-  private static void ensureCreated(Path directory) {
-    File directoryFile = directory.toFile();
-    if (directoryFile.exists() && directoryFile.isDirectory()) {
-      return;
-    }
-    assertTrue(directoryFile.mkdirs());
-  }
-
-  public static int exec(Class<?> klass, String[] args, File err) throws IOException,
-      InterruptedException {
-    String javaHome = System.getProperty("java.home");
-    String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
-    String classpath = System.getProperty("java.class.path");
-    String className = klass.getName();
-
-    String[] newArgs = new String[args.length + 4];
-    newArgs[0] = javaBin;
-    newArgs[1] = "-cp";
-    newArgs[2] = classpath;
-    newArgs[3] = className;
-    System.arraycopy(args, 0, newArgs, 4, args.length);
-
-    ProcessBuilder builder = new ProcessBuilder(newArgs);
-//    builder.redirectOutput(err);
-    builder.redirectError(err);
-
-    Process process = builder.start();
-    process.waitFor();
-    return process.exitValue();
-  }
-
-  public static void testJaddContainReferenceToJackson(Path path, boolean shouldContain) {
-    try {
-      String content = Files.readString(path);
-      boolean actualContain = content.contains("com.fasterxml.jackson.databind.ObjectMapper");
-      if (actualContain && !shouldContain) {
-        fail(path + " should not depend on jackson library, but does");
-      }
-      if (!actualContain && shouldContain) {
-        fail(path + " does not depend on jackson library");
-      }
-    } catch (IOException e) {
-      fail(e);
-    }
-  }
-
-  public static String readFile(Path path, Charset encoding)
-      throws IOException {
-    byte[] encoded = Files.readAllBytes(path);
-    return new String(encoded, encoding);
-  }
-
-  public static void waitForMqtt() throws InterruptedException {
-    TimeUnit.MILLISECONDS.sleep(1500);
-  }
-
-  public static ConditionFactory awaitMqtt() {
-    return Awaitility.await().atMost(1500, TimeUnit.MILLISECONDS);
-  }
-
-  static <T_Event, T_ASTNode> void logEvent(T_Event event, T_ASTNode node, String attribute, Object params, Object value) {
-    logger.info("event: {}, node: {}, attribute: {}, params: {}, value: {}",
-            event, node, attribute, params, value);
-  }
-
-  public static class TestChecker {
-    static class ActualAndExpected<T> {
-      Callable<T> actual;
-      T expected;
-      BiConsumer<String, T> customCheck;
-
-      ActualAndExpected(String key) {
-        expected = null;
-      }
-
-      void check(String name) {
-        if (customCheck != null) {
-          customCheck.accept(name, expected);
-          return;
-        }
-        if (actual == null) {
-          fail("No actual getter defined for " + name);
-        }
-        T actualValue = null;
-        try {
-          actualValue = this.actual.call();
-        } catch (Exception e) {
-          fail(e);
-        }
-        assertThat(actualValue).as(name).isEqualTo(expected);
-      }
-
-      void checkAwait(String name) {
-        if (customCheck != null) {
-          logger.warn("Custom check set for {}. Can't await for that.", name);
-          customCheck.accept(name, expected);
-          return;
-        }
-        if (actual == null) {
-          fail("No actual getter defined for " + name);
-        }
-        awaitMqtt().alias(name + " == " + expected).until(actual, Predicate.isEqual(expected));
-      }
-    }
-    static class ValuesToCompare<T> {
-      protected final Map<String, ActualAndExpected<T>> values = new HashMap<>();
-      protected final TestChecker parent;
-
-      ValuesToCompare(TestChecker parent) {
-        this.parent = parent;
-      }
-
-      public TestChecker setActual(String name, Callable<T> actual) {
-        _computeIfAbsent(name).actual = actual;
-        return parent;
-      }
-
-      public TestChecker setCheck(String name, BiConsumer<String, T> check) {
-        _computeIfAbsent(name).customCheck = check;
-        return parent;
-      }
-
-      public TestChecker put(String name, T expected) {
-        _computeIfAbsent(name).expected = expected;
-        return parent;
-      }
-
-      public TestChecker updateExpected(String name, Function<T, T> updater) {
-        ActualAndExpected<T> aae = _computeIfAbsent(name);
-        aae.expected = updater.apply(aae.expected);
-        return parent;
-      }
-
-      private ActualAndExpected<T> _computeIfAbsent(String name) {
-        return values.computeIfAbsent(name, ActualAndExpected::new);
-      }
-
-      ActualAndExpected<T> get(String name) {
-        return values.get(name);
-      }
-
-      void forEach(BiConsumer<? super String, ? super ActualAndExpected<T>> action) {
-        values.forEach(action);
-      }
-    }
-    static class IntegerValuesToCompare extends ValuesToCompare<Integer> {
-      IntegerValuesToCompare(TestChecker parent) {
-        super(parent);
-      }
-
-      public TestChecker incNumberOfValues() {
-        return addToNumberOfValues(1);
-      }
-
-      public TestChecker addToNumberOfValues(int increment) {
-        // if there is at least one call to this, we do not need to manually wait in the next check()
-        parent.needManualWait = false;
-        Integer currentExpected = values.computeIfAbsent(NUMBER_OF_VALUES, ActualAndExpected::new).expected;
-        return put(NUMBER_OF_VALUES, currentExpected + increment);
-      }
-
-      public TestChecker setActualNumberOfValues(Callable<Integer> actual) {
-        setActual(NUMBER_OF_VALUES, actual);
-        values.get(NUMBER_OF_VALUES).expected = 0;
-        return parent;
-      }
-    }
-    private final static String NUMBER_OF_VALUES = "numberOfValues";
-    public final ValuesToCompare<Object> objectValues = new ValuesToCompare<>(this);
-    public final ValuesToCompare<String> stringValues = new ValuesToCompare<>(this);
-    public final ValuesToCompare<Tuple> tupleValues = new ValuesToCompare<>(this);
-    public final IntegerValuesToCompare intValues = new IntegerValuesToCompare(this);
-    private boolean needManualWait = true;
-    private boolean useManualWait = true;
-
-    public TestChecker incNumberOfValues() {
-      return intValues.incNumberOfValues();
-    }
-
-    public TestChecker addToNumberOfValues(int increment) {
-      return intValues.addToNumberOfValues(increment);
-    }
-
-    public TestChecker setActualNumberOfValues(Callable<Integer> actual) {
-      return intValues.setActualNumberOfValues(actual);
-    }
-
-    public TestChecker alwaysWait() {
-      return setActualNumberOfValues(() -> 0);
-    }
-
-    public TestChecker put(String name, Object expected) {
-      return objectValues.put(name, expected);
-    }
-
-    public TestChecker setCheckForObject(String name, BiConsumer<String, Object> check) {
-      return objectValues.setCheck(name, check);
-    }
-
-    public TestChecker setActualString(String name, Callable<String> actual) {
-      return stringValues.setActual(name, actual);
-    }
-
-    public TestChecker setCheckForString(String name, BiConsumer<String, String> check) {
-      return stringValues.setCheck(name, check);
-    }
-
-    public TestChecker put(String name, String expected) {
-      return stringValues.put(name, expected);
-    }
-
-    public TestChecker setActualTuple(String name, Callable<Tuple> actual) {
-      return tupleValues.setActual(name, actual);
-    }
-
-    public TestChecker setCheckForTuple(String name, BiConsumer<String, Tuple> check) {
-      return tupleValues.setCheck(name, check);
-    }
-
-    public TestChecker put(String name, Tuple expected) {
-      return tupleValues.put(name, expected);
-    }
-
-    public TestChecker setActualInteger(String name, Callable<Integer> actual) {
-      return intValues.setActual(name, actual);
-    }
-
-    public TestChecker setCheckForInteger(String name, BiConsumer<String, Integer> check) {
-      return intValues.setCheck(name, check);
-    }
-
-    public TestChecker put(String name, Integer expected) {
-      return intValues.put(name, expected);
-    }
-
-    public TestChecker disableManualWait() {
-      useManualWait = false;
-      needManualWait = false;
-      return this;
-    }
-
-    public void check() {
-      if (needManualWait) {
-        try {
-          waitForMqtt();
-        } catch (InterruptedException e) {
-          fail(e);
-        }
-      }
-      intValues.get(NUMBER_OF_VALUES).checkAwait(NUMBER_OF_VALUES);
-
-      objectValues.forEach((name, aae) -> aae.check(name));
-      stringValues.forEach((name, aae) -> aae.check(name));
-      tupleValues.forEach((name, aae) -> aae.check(name));
-      intValues.forEach((name, aae) -> {
-        if (!name.equals(NUMBER_OF_VALUES)) {
-          aae.check(name);
-        }
-      });
-      needManualWait = useManualWait;
-    }
-  }
-
-  public static class IntList {
-    private final List<Integer> integers;
-    public IntList(Integer... values) {
-      integers = Arrays.stream(values).filter(Objects::nonNull).collect(Collectors.toList());
-    }
-
-    public List<Integer> toList() {
-      return integers;
-    }
-
-    public List<Integer> toAbsList() {
-      return integers.stream().map(Math::abs).collect(Collectors.toList());
-    }
-
-    public static IntList list(Integer... values) {
-      return new IntList(values);
-    }
-  }
-
-  @SuppressWarnings({"unused", "rawtypes"})
-  public static class DefaultMappings {
-    static class ReadNode extends defaultOnlyRead.ast.ASTNode {
-      public boolean DefaultBytesToBooleanMapping(byte[] input) throws Exception {
-        return _ragconnect__apply__DefaultBytesToBooleanMapping(input);
-      }
-      public int DefaultBytesToIntMapping(byte[] input) throws Exception {
-        return _ragconnect__apply__DefaultBytesToIntMapping(input);
-      }
-      public short DefaultBytesToShortMapping(byte[] input) throws Exception {
-        return _ragconnect__apply__DefaultBytesToShortMapping(input);
-      }
-      public long DefaultBytesToLongMapping(byte[] input) throws Exception {
-        return _ragconnect__apply__DefaultBytesToLongMapping(input);
-      }
-      public float DefaultBytesToFloatMapping(byte[] input) throws Exception {
-        return _ragconnect__apply__DefaultBytesToFloatMapping(input);
-      }
-      public double DefaultBytesToDoubleMapping(byte[] input) throws Exception {
-        return _ragconnect__apply__DefaultBytesToDoubleMapping(input);
-      }
-      public char DefaultBytesToCharMapping(byte[] input) throws Exception {
-        return _ragconnect__apply__DefaultBytesToCharMapping(input);
-      }
-      public String DefaultBytesToStringMapping(byte[] input) throws Exception {
-        return _ragconnect__apply__DefaultBytesToStringMapping(input);
-      }
-    }
-
-    static class WriteNode extends defaultOnlyWrite.ast.ASTNode {
-      public byte[] DefaultBooleanToBytesMapping(boolean input) throws Exception {
-        return _ragconnect__apply__DefaultBooleanToBytesMapping(input);
-      }
-      public byte[] DefaultIntToBytesMapping(int input) throws Exception {
-        return _ragconnect__apply__DefaultIntToBytesMapping(input);
-      }
-      public byte[] DefaultShortToBytesMapping(short input) throws Exception {
-        return _ragconnect__apply__DefaultShortToBytesMapping(input);
-      }
-      public byte[] DefaultLongToBytesMapping(long input) throws Exception {
-        return _ragconnect__apply__DefaultLongToBytesMapping(input);
-      }
-      public byte[] DefaultFloatToBytesMapping(float input) throws Exception {
-        return _ragconnect__apply__DefaultFloatToBytesMapping(input);
-      }
-      public byte[] DefaultDoubleToBytesMapping(double input) throws Exception {
-        return _ragconnect__apply__DefaultDoubleToBytesMapping(input);
-      }
-      public byte[] DefaultCharToBytesMapping(char input) throws Exception {
-        return _ragconnect__apply__DefaultCharToBytesMapping(input);
-      }
-      public byte[] DefaultStringToBytesMapping(String input) throws Exception {
-        return _ragconnect__apply__DefaultStringToBytesMapping(input);
-      }
-    }
-    @FunctionalInterface
-    interface SerializeFunction<E extends Throwable> {
-      void accept(JsonGenerator g, String fieldName) throws E;
-    }
-
-    static ReadNode readNode = new ReadNode();
-    static WriteNode writeNode = new WriteNode();
-
-    public static boolean BytesToBool(byte[] input) {
-      try {
-        return readNode.DefaultBytesToBooleanMapping(input);
-      } catch (Exception e) {
-        e.printStackTrace();
-        return false;
-      }
-    }
-    public static int BytesToInt(byte[] input) {
-      try {
-        return readNode.DefaultBytesToIntMapping(input);
-      } catch (Exception e) {
-        e.printStackTrace();
-        return 0;
-      }
-    }
-    public static short BytesToShort(byte[] input) {
-      try {
-        return readNode.DefaultBytesToShortMapping(input);
-      } catch (Exception e) {
-        e.printStackTrace();
-        return 0;
-      }
-    }
-    public static long BytesToLong(byte[] input) {
-      try {
-        return readNode.DefaultBytesToLongMapping(input);
-      } catch (Exception e) {
-        e.printStackTrace();
-        return 0;
-      }
-    }
-    public static float BytesToFloat(byte[] input) {
-      try {
-        return readNode.DefaultBytesToFloatMapping(input);
-      } catch (Exception e) {
-        e.printStackTrace();
-        return 0;
-      }
-    }
-    public static double BytesToDouble(byte[] input) {
-      try {
-        return readNode.DefaultBytesToDoubleMapping(input);
-      } catch (Exception e) {
-        e.printStackTrace();
-        return 0;
-      }
-    }
-    public static char BytesToChar(byte[] input) {
-      try {
-        return readNode.DefaultBytesToCharMapping(input);
-      } catch (Exception e) {
-        e.printStackTrace();
-        return 0;
-      }
-    }
-    public static String BytesToString(byte[] input) {
-      try {
-        return readNode.DefaultBytesToStringMapping(input);
-      } catch (Exception e) {
-        e.printStackTrace();
-        return null;
-      }
-    }
-    public static byte[] BoolToBytes(boolean input) {
-      try {
-        return writeNode.DefaultBooleanToBytesMapping(input);
-      } catch (Exception e) {
-        e.printStackTrace();
-        return null;
-      }
-    }
-    public static byte[] IntToBytes(int input) {
-      try {
-        return writeNode.DefaultIntToBytesMapping(input);
-      } catch (Exception e) {
-        e.printStackTrace();
-        return null;
-      }
-    }
-    public static byte[] ShortToBytes(short input) {
-      try {
-        return writeNode.DefaultShortToBytesMapping(input);
-      } catch (Exception e) {
-        e.printStackTrace();
-        return null;
-      }
-    }
-    public static byte[] LongToBytes(long input) {
-      try {
-        return writeNode.DefaultLongToBytesMapping(input);
-      } catch (Exception e) {
-        e.printStackTrace();
-        return null;
-      }
-    }
-    public static byte[] FloatToBytes(float input) {
-      try {
-        return writeNode.DefaultFloatToBytesMapping(input);
-      } catch (Exception e) {
-        e.printStackTrace();
-        return null;
-      }
-    }
-    public static byte[] DoubleToBytes(double input) {
-      try {
-        return writeNode.DefaultDoubleToBytesMapping(input);
-      } catch (Exception e) {
-        e.printStackTrace();
-        return null;
-      }
-    }
-    public static byte[] CharToBytes(char input) {
-      try {
-        return writeNode.DefaultCharToBytesMapping(input);
-      } catch (Exception e) {
-        e.printStackTrace();
-        return null;
-      }
-    }
-    public static byte[] StringToBytes(String input) {
-      try {
-        return writeNode.DefaultStringToBytesMapping(input);
-      } catch (Exception e) {
-        e.printStackTrace();
-        return null;
-      }
-    }
-    public static <E extends Throwable> byte[] TreeToBytes(SerializeFunction<E> serializeFunction) throws E, IOException {
-      ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-      JsonFactory factory = new JsonFactory();
-      JsonGenerator generator = factory.createGenerator(outputStream, JsonEncoding.UTF8);
-      serializeFunction.accept(generator, null);
-      generator.flush();
-      return outputStream.toString().getBytes();
-    }
-  }
-
-  public static class ChangeObserver {
-    Map<Supplier<String>, String> callableToPrevious = new HashMap<>();
-    private Callable<Boolean> hasChanged;
-
-    @SafeVarargs
-    public final void init(Supplier<String>... suppliers) {
-      callableToPrevious.clear();
-      Arrays.stream(suppliers).forEach(callable -> callableToPrevious.put(callable, callable.get()));
-      hasChanged = () -> callableToPrevious.entrySet().stream()
-              .anyMatch(entry -> !entry.getKey().get().equals(entry.getValue()));
-    }
-
-    public void start() {
-      updatePrevious();
-    }
-
-    private void updatePrevious() {
-      callableToPrevious.keySet().forEach(callable -> callableToPrevious.put(callable, callable.get()));
-    }
-
-    public void awaitChange() {
-      awaitMqtt().until(hasChanged);
-      updatePrevious();
-    }
-
-    public boolean hasChanged() {
-      try {
-        return hasChanged.call();
-      } catch (Exception e) {
-        fail(e);
-        return false;
-      }
-    }
-  }
-}
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TutorialTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TutorialTest.java
index 27edcee..490f8c5 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TutorialTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/TutorialTest.java
@@ -5,7 +5,7 @@ import tutorial.ast.B;
 
 import java.io.IOException;
 
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 /**
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ViaTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ViaTest.java
index 4c1be6b..9401cf6 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ViaTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/ViaTest.java
@@ -1,6 +1,8 @@
 package org.jastadd.ragconnect.tests;
 
-import org.jastadd.ragconnect.tests.TestUtils.TestChecker;
+import org.jastadd.ragconnect.tests.utils.DefaultMappings;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
+import org.jastadd.ragconnect.tests.utils.TestChecker;
 import org.junit.jupiter.api.Tag;
 import via.ast.A;
 import via.ast.MqttHandler;
@@ -13,8 +15,8 @@ import javax.ws.rs.core.MediaType;
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
-import static org.jastadd.ragconnect.tests.TestUtils.restUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.restUri;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
@@ -91,15 +93,15 @@ public class ViaTest extends AbstractMqttTest {
 
     handler.newConnection(TOPIC_MQTT_2_MQTT_SEND, bytes -> {
       dataMqtt2Mqtt.numberOfStringValues += 1;
-      dataMqtt2Mqtt.lastStringValue = TestUtils.DefaultMappings.BytesToString(bytes);
+      dataMqtt2Mqtt.lastStringValue = DefaultMappings.BytesToString(bytes);
     });
     handler.newConnection(TOPIC_REST_2_MQTT_SEND, bytes -> {
       dataRest2Mqtt.numberOfStringValues += 1;
-      dataRest2Mqtt.lastStringValue = TestUtils.DefaultMappings.BytesToString(bytes);
+      dataRest2Mqtt.lastStringValue = DefaultMappings.BytesToString(bytes);
     });
     handler.newConnection(TOPIC_BOTH_2_MQTT_SEND, bytes -> {
       dataBoth2Mqtt.numberOfStringValues += 1;
-      dataBoth2Mqtt.lastStringValue = TestUtils.DefaultMappings.BytesToString(bytes);
+      dataBoth2Mqtt.lastStringValue = DefaultMappings.BytesToString(bytes);
     });
 
     checker = new TestChecker();
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Warnings.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Warnings.java
index 121843c..e860dfa 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Warnings.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/Warnings.java
@@ -1,9 +1,8 @@
 package org.jastadd.ragconnect.tests;
 
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import java.io.File;
 import java.io.IOException;
@@ -13,7 +12,7 @@ import java.util.Collections;
 import java.util.List;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.jastadd.ragconnect.tests.TestUtils.readFile;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.readFile;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 /**
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/list/AbstractListTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/list/AbstractListTest.java
index c22207d..d4a432f 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/list/AbstractListTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/list/AbstractListTest.java
@@ -1,8 +1,8 @@
 package org.jastadd.ragconnect.tests.list;
 
 import org.jastadd.ragconnect.tests.AbstractMqttTest;
-import org.jastadd.ragconnect.tests.TestUtils.IntList;
-import org.jastadd.ragconnect.tests.TestUtils.TestChecker;
+import org.jastadd.ragconnect.tests.utils.IntList;
+import org.jastadd.ragconnect.tests.utils.TestChecker;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
 
@@ -11,8 +11,8 @@ import java.nio.file.Paths;
 import java.util.List;
 import java.util.function.Function;
 
-import static org.jastadd.ragconnect.tests.TestUtils.IntList.list;
-import static org.jastadd.ragconnect.tests.TestUtils.testJaddContainReferenceToJackson;
+import static org.jastadd.ragconnect.tests.utils.IntList.list;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.testJaddContainReferenceToJackson;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
 /**
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/list/ListIncrementalTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/list/ListIncrementalTest.java
index 75010c8..1aabdc4 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/list/ListIncrementalTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/list/ListIncrementalTest.java
@@ -1,13 +1,13 @@
 package org.jastadd.ragconnect.tests.list;
 
 import listInc.ast.*;
-import org.jastadd.ragconnect.tests.TestUtils;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Tag;
 
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/list/ListManualTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/list/ListManualTest.java
index a0e9aa8..1b9aadc 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/list/ListManualTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/list/ListManualTest.java
@@ -4,12 +4,12 @@ import list.ast.MqttHandler;
 import list.ast.ReceiverRoot;
 import list.ast.Root;
 import list.ast.SenderRoot;
-import org.jastadd.ragconnect.tests.TestUtils;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/relation/RelationTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/relation/RelationTest.java
index 9d38f18..f4ebfc5 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/relation/RelationTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/relation/RelationTest.java
@@ -1,7 +1,7 @@
 package org.jastadd.ragconnect.tests.relation;
 
 import org.jastadd.ragconnect.tests.AbstractMqttTest;
-import org.jastadd.ragconnect.tests.TestUtils;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Tag;
 import relationInc.ast.*;
 
@@ -11,8 +11,9 @@ import java.util.concurrent.TimeUnit;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.groups.Tuple.tuple;
-import static org.jastadd.ragconnect.tests.TestUtils.TestChecker;
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
+
+import org.jastadd.ragconnect.tests.utils.TestChecker;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
 import static org.junit.jupiter.api.Assertions.*;
 
 /**
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/singleList/AbstractSingleListTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/singleList/AbstractSingleListTest.java
index 2cc90ef..f3b792d 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/singleList/AbstractSingleListTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/singleList/AbstractSingleListTest.java
@@ -1,7 +1,9 @@
 package org.jastadd.ragconnect.tests.singleList;
 
 import org.jastadd.ragconnect.tests.AbstractMqttTest;
-import org.jastadd.ragconnect.tests.TestUtils;
+import org.jastadd.ragconnect.tests.utils.IntList;
+import org.jastadd.ragconnect.tests.utils.TestChecker;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
 import singleList.ast.MqttHandler;
@@ -13,8 +15,8 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Function;
 
-import static org.jastadd.ragconnect.tests.TestUtils.*;
-import static org.jastadd.ragconnect.tests.TestUtils.IntList.list;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.*;
+import static org.jastadd.ragconnect.tests.utils.IntList.list;
 import static org.junit.jupiter.api.Assertions.*;
 
 /**
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/singleListVariant/AbstractSingleListVariantTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/singleListVariant/AbstractSingleListVariantTest.java
index f84cd79..c012845 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/singleListVariant/AbstractSingleListVariantTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/singleListVariant/AbstractSingleListVariantTest.java
@@ -2,8 +2,8 @@ package org.jastadd.ragconnect.tests.singleListVariant;
 
 import org.assertj.core.api.Assertions;
 import org.jastadd.ragconnect.tests.AbstractMqttTest;
-import org.jastadd.ragconnect.tests.TestUtils.IntList;
-import org.jastadd.ragconnect.tests.TestUtils.TestChecker;
+import org.jastadd.ragconnect.tests.utils.IntList;
+import org.jastadd.ragconnect.tests.utils.TestChecker;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
 
@@ -13,9 +13,9 @@ import java.util.List;
 import java.util.function.BiConsumer;
 
 import static java.lang.Math.abs;
-import static org.jastadd.ragconnect.tests.TestUtils.IntList.list;
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
-import static org.jastadd.ragconnect.tests.TestUtils.testJaddContainReferenceToJackson;
+import static org.jastadd.ragconnect.tests.utils.IntList.list;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.testJaddContainReferenceToJackson;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/singleListVariant/SingleListVariantIncrementalTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/singleListVariant/SingleListVariantIncrementalTest.java
index c1b37cc..1d74649 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/singleListVariant/SingleListVariantIncrementalTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/singleListVariant/SingleListVariantIncrementalTest.java
@@ -1,6 +1,6 @@
 package org.jastadd.ragconnect.tests.singleListVariant;
 
-import org.jastadd.ragconnect.tests.TestUtils;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Tag;
 import singleListVariantInc.ast.MqttHandler;
 import singleListVariantInc.ast.ReceiverRoot;
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/singleListVariant/SingleListVariantManualTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/singleListVariant/SingleListVariantManualTest.java
index 60238c8..907826d 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/singleListVariant/SingleListVariantManualTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/singleListVariant/SingleListVariantManualTest.java
@@ -1,6 +1,6 @@
 package org.jastadd.ragconnect.tests.singleListVariant;
 
-import org.jastadd.ragconnect.tests.TestUtils;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import singleListVariant.ast.*;
 
 import java.io.IOException;
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tokenValue/AbstractTokenValueSendTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tokenValue/AbstractTokenValueSendTest.java
index fcc3e8a..5d55b72 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tokenValue/AbstractTokenValueSendTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tokenValue/AbstractTokenValueSendTest.java
@@ -1,9 +1,9 @@
 package org.jastadd.ragconnect.tests.tokenValue;
 
 import org.jastadd.ragconnect.tests.AbstractMqttTest;
-import org.jastadd.ragconnect.tests.TestUtils;
-import org.jastadd.ragconnect.tests.TestUtils.TestChecker;
-import org.junit.jupiter.api.Tag;
+import org.jastadd.ragconnect.tests.utils.DefaultMappings;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
+import org.jastadd.ragconnect.tests.utils.TestChecker;
 import org.junit.jupiter.api.Test;
 import tokenValueSend.ast.MqttHandler;
 
@@ -11,8 +11,8 @@ import java.io.IOException;
 import java.nio.file.Paths;
 import java.util.concurrent.TimeUnit;
 
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
-import static org.jastadd.ragconnect.tests.TestUtils.testJaddContainReferenceToJackson;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.testJaddContainReferenceToJackson;
 import static org.junit.jupiter.api.Assertions.*;
 
 /**
@@ -68,20 +68,20 @@ public abstract class AbstractTokenValueSendTest extends AbstractMqttTest {
 
     handler.newConnection(TOPIC_SEND_ONE, bytes -> {
       dataOne.numberOfStringValues += 1;
-      dataOne.lastStringValue = TestUtils.DefaultMappings.BytesToString(bytes);
+      dataOne.lastStringValue = DefaultMappings.BytesToString(bytes);
     });
     handler.newConnection(TOPIC_SEND_TWO, bytes -> {
       dataTwo.numberOfStringValues += 1;
-      dataTwo.lastStringValue = TestUtils.DefaultMappings.BytesToString(bytes);
+      dataTwo.lastStringValue = DefaultMappings.BytesToString(bytes);
     });
 
     handler.newConnection(TOPIC_SEND_THREE_VALUE, bytes -> {
       dataThree.numberOfStringValues += 1;
-      dataThree.lastStringValue = TestUtils.DefaultMappings.BytesToString(bytes);
+      dataThree.lastStringValue = DefaultMappings.BytesToString(bytes);
     });
     handler.newConnection(TOPIC_SEND_THREE_OTHER, bytes -> {
       dataThreeOther.numberOfStringValues += 1;
-      dataThreeOther.lastStringValue = TestUtils.DefaultMappings.BytesToString(bytes);
+      dataThreeOther.lastStringValue = DefaultMappings.BytesToString(bytes);
     });
 
     connectModel();
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tokenValue/TokenValueSendIncrementalTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tokenValue/TokenValueSendIncrementalTest.java
index 9676b9c..bdb1ab9 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tokenValue/TokenValueSendIncrementalTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tokenValue/TokenValueSendIncrementalTest.java
@@ -6,7 +6,7 @@ import tokenValueSendInc.ast.*;
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 /**
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tokenValue/TokenValueSendManualTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tokenValue/TokenValueSendManualTest.java
index a24f8a8..ac13bfa 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tokenValue/TokenValueSendManualTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tokenValue/TokenValueSendManualTest.java
@@ -5,7 +5,7 @@ import tokenValueSend.ast.*;
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 /**
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tree/AbstractTreeTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tree/AbstractTreeTest.java
index 22cc2c0..c8f87c1 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tree/AbstractTreeTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tree/AbstractTreeTest.java
@@ -1,7 +1,7 @@
 package org.jastadd.ragconnect.tests.tree;
 
 import org.jastadd.ragconnect.tests.AbstractMqttTest;
-import org.jastadd.ragconnect.tests.TestUtils;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Tag;
 
 import java.io.IOException;
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tree/TreeIncrementalTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tree/TreeIncrementalTest.java
index 542d4a3..419e5a4 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tree/TreeIncrementalTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tree/TreeIncrementalTest.java
@@ -1,6 +1,6 @@
 package org.jastadd.ragconnect.tests.tree;
 
-import org.jastadd.ragconnect.tests.TestUtils;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
 import treeInc.ast.*;
@@ -10,8 +10,8 @@ import java.nio.file.Paths;
 import java.util.concurrent.TimeUnit;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
-import static org.jastadd.ragconnect.tests.TestUtils.testJaddContainReferenceToJackson;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.testJaddContainReferenceToJackson;
 import static org.junit.jupiter.api.Assertions.*;
 
 /**
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tree/TreeManualTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tree/TreeManualTest.java
index c48335f..c0845d5 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tree/TreeManualTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/tree/TreeManualTest.java
@@ -1,7 +1,6 @@
 package org.jastadd.ragconnect.tests.tree;
 
-import org.jastadd.ragconnect.tests.TestUtils;
-import org.junit.jupiter.api.Tag;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Test;
 import tree.ast.MqttHandler;
 import tree.ast.ReceiverRoot;
@@ -12,8 +11,8 @@ import java.io.IOException;
 import java.nio.file.Paths;
 import java.util.concurrent.TimeUnit;
 
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
-import static org.jastadd.ragconnect.tests.TestUtils.testJaddContainReferenceToJackson;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.testJaddContainReferenceToJackson;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 /**
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/treeAllowedTokens/AbstractTreeAllowedTokensTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/treeAllowedTokens/AbstractTreeAllowedTokensTest.java
index 7c29538..533d5d1 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/treeAllowedTokens/AbstractTreeAllowedTokensTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/treeAllowedTokens/AbstractTreeAllowedTokensTest.java
@@ -1,7 +1,8 @@
 package org.jastadd.ragconnect.tests.treeAllowedTokens;
 
 import org.jastadd.ragconnect.tests.AbstractMqttTest;
-import org.jastadd.ragconnect.tests.TestUtils;
+import org.jastadd.ragconnect.tests.utils.DefaultMappings;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Tag;
 
 import java.io.IOException;
@@ -183,19 +184,19 @@ public abstract class AbstractTreeAllowedTokensTest extends AbstractMqttTest {
   protected abstract void disconnectSend() throws IOException;
 
   protected void sendInput1WhenFalse(int value) {
-    publisher.publish(TOPIC_INPUT1FALSE, TestUtils.DefaultMappings.IntToBytes(value));
+    publisher.publish(TOPIC_INPUT1FALSE, DefaultMappings.IntToBytes(value));
   }
 
   protected void sendInput1WhenTrue(int value) {
-    publisher.publish(TOPIC_INPUT1TRUE, TestUtils.DefaultMappings.IntToBytes(value));
+    publisher.publish(TOPIC_INPUT1TRUE, DefaultMappings.IntToBytes(value));
   }
 
   protected void sendInput2(String value) {
-    publisher.publish(TOPIC_INPUT2, TestUtils.DefaultMappings.StringToBytes(value));
+    publisher.publish(TOPIC_INPUT2, DefaultMappings.StringToBytes(value));
   }
 
   protected void sendInput3(double value) {
-    publisher.publish(TOPIC_INPUT3, TestUtils.DefaultMappings.DoubleToBytes(value));
+    publisher.publish(TOPIC_INPUT3, DefaultMappings.DoubleToBytes(value));
   }
 
   protected abstract void setFlag(boolean value);
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/treeAllowedTokens/TreeAllowedTokensIncrementalTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/treeAllowedTokens/TreeAllowedTokensIncrementalTest.java
index d4cc6d5..7d6ab57 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/treeAllowedTokens/TreeAllowedTokensIncrementalTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/treeAllowedTokens/TreeAllowedTokensIncrementalTest.java
@@ -1,6 +1,6 @@
 package org.jastadd.ragconnect.tests.treeAllowedTokens;
 
-import org.jastadd.ragconnect.tests.TestUtils;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
 import treeAllowedTokensInc.ast.*;
@@ -9,8 +9,8 @@ import java.io.IOException;
 import java.nio.file.Paths;
 import java.util.concurrent.TimeUnit;
 
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
-import static org.jastadd.ragconnect.tests.TestUtils.testJaddContainReferenceToJackson;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.testJaddContainReferenceToJackson;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/treeAllowedTokens/TreeAllowedTokensManualTest.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/treeAllowedTokens/TreeAllowedTokensManualTest.java
index 96e0080..7479396 100644
--- a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/treeAllowedTokens/TreeAllowedTokensManualTest.java
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/treeAllowedTokens/TreeAllowedTokensManualTest.java
@@ -1,7 +1,6 @@
 package org.jastadd.ragconnect.tests.treeAllowedTokens;
 
-import org.jastadd.ragconnect.tests.TestUtils;
-import org.junit.jupiter.api.Tag;
+import org.jastadd.ragconnect.tests.utils.TestUtils;
 import org.junit.jupiter.api.Test;
 import treeAllowedTokens.ast.*;
 
@@ -9,8 +8,8 @@ import java.io.IOException;
 import java.nio.file.Paths;
 import java.util.concurrent.TimeUnit;
 
-import static org.jastadd.ragconnect.tests.TestUtils.mqttUri;
-import static org.jastadd.ragconnect.tests.TestUtils.testJaddContainReferenceToJackson;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.mqttUri;
+import static org.jastadd.ragconnect.tests.utils.TestUtils.testJaddContainReferenceToJackson;
 import static org.junit.jupiter.api.Assertions.*;
 
 /**
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/ChangeObserver.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/ChangeObserver.java
new file mode 100644
index 0000000..2b0dbef
--- /dev/null
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/ChangeObserver.java
@@ -0,0 +1,49 @@
+package org.jastadd.ragconnect.tests.utils;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.function.Supplier;
+
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+ * TODO: Add description.
+ *
+ * @author rschoene - Initial contribution
+ */
+public class ChangeObserver {
+  Map<Supplier<String>, String> callableToPrevious = new HashMap<>();
+  private Callable<Boolean> hasChanged;
+
+  @SafeVarargs
+  public final void init(Supplier<String>... suppliers) {
+    callableToPrevious.clear();
+    Arrays.stream(suppliers).forEach(callable -> callableToPrevious.put(callable, callable.get()));
+    hasChanged = () -> callableToPrevious.entrySet().stream()
+            .anyMatch(entry -> !entry.getKey().get().equals(entry.getValue()));
+  }
+
+  public void start() {
+    updatePrevious();
+  }
+
+  private void updatePrevious() {
+    callableToPrevious.keySet().forEach(callable -> callableToPrevious.put(callable, callable.get()));
+  }
+
+  public void awaitChange() {
+    TestUtils.awaitMqtt().until(hasChanged);
+    updatePrevious();
+  }
+
+  public boolean hasChanged() {
+    try {
+      return hasChanged.call();
+    } catch (Exception e) {
+      fail(e);
+      return false;
+    }
+  }
+}
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/DefaultMappings.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/DefaultMappings.java
new file mode 100644
index 0000000..81711cf
--- /dev/null
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/DefaultMappings.java
@@ -0,0 +1,246 @@
+package org.jastadd.ragconnect.tests.utils;
+
+import com.fasterxml.jackson.core.JsonEncoding;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonGenerator;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * TODO: Add description.
+ *
+ * @author rschoene - Initial contribution
+ */
+public class DefaultMappings {
+  @SuppressWarnings("rawtypes")
+  static class ReadNode extends defaultOnlyRead.ast.ASTNode {
+    public boolean DefaultBytesToBooleanMapping(byte[] input) throws Exception {
+      return _ragconnect__apply__DefaultBytesToBooleanMapping(input);
+    }
+
+    public int DefaultBytesToIntMapping(byte[] input) throws Exception {
+      return _ragconnect__apply__DefaultBytesToIntMapping(input);
+    }
+
+    public short DefaultBytesToShortMapping(byte[] input) throws Exception {
+      return _ragconnect__apply__DefaultBytesToShortMapping(input);
+    }
+
+    public long DefaultBytesToLongMapping(byte[] input) throws Exception {
+      return _ragconnect__apply__DefaultBytesToLongMapping(input);
+    }
+
+    public float DefaultBytesToFloatMapping(byte[] input) throws Exception {
+      return _ragconnect__apply__DefaultBytesToFloatMapping(input);
+    }
+
+    public double DefaultBytesToDoubleMapping(byte[] input) throws Exception {
+      return _ragconnect__apply__DefaultBytesToDoubleMapping(input);
+    }
+
+    public char DefaultBytesToCharMapping(byte[] input) throws Exception {
+      return _ragconnect__apply__DefaultBytesToCharMapping(input);
+    }
+
+    public String DefaultBytesToStringMapping(byte[] input) throws Exception {
+      return _ragconnect__apply__DefaultBytesToStringMapping(input);
+    }
+  }
+
+  @SuppressWarnings("rawtypes")
+  static class WriteNode extends defaultOnlyWrite.ast.ASTNode {
+    public byte[] DefaultBooleanToBytesMapping(boolean input) throws Exception {
+      return _ragconnect__apply__DefaultBooleanToBytesMapping(input);
+    }
+
+    public byte[] DefaultIntToBytesMapping(int input) throws Exception {
+      return _ragconnect__apply__DefaultIntToBytesMapping(input);
+    }
+
+    public byte[] DefaultShortToBytesMapping(short input) throws Exception {
+      return _ragconnect__apply__DefaultShortToBytesMapping(input);
+    }
+
+    public byte[] DefaultLongToBytesMapping(long input) throws Exception {
+      return _ragconnect__apply__DefaultLongToBytesMapping(input);
+    }
+
+    public byte[] DefaultFloatToBytesMapping(float input) throws Exception {
+      return _ragconnect__apply__DefaultFloatToBytesMapping(input);
+    }
+
+    public byte[] DefaultDoubleToBytesMapping(double input) throws Exception {
+      return _ragconnect__apply__DefaultDoubleToBytesMapping(input);
+    }
+
+    public byte[] DefaultCharToBytesMapping(char input) throws Exception {
+      return _ragconnect__apply__DefaultCharToBytesMapping(input);
+    }
+
+    public byte[] DefaultStringToBytesMapping(String input) throws Exception {
+      return _ragconnect__apply__DefaultStringToBytesMapping(input);
+    }
+  }
+
+  @FunctionalInterface
+  public interface SerializeFunction<E extends Throwable> {
+    void accept(JsonGenerator g, String fieldName) throws E;
+  }
+
+  static ReadNode readNode = new ReadNode();
+  static WriteNode writeNode = new WriteNode();
+
+  public static boolean BytesToBool(byte[] input) {
+    try {
+      return readNode.DefaultBytesToBooleanMapping(input);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return false;
+    }
+  }
+
+  public static int BytesToInt(byte[] input) {
+    try {
+      return readNode.DefaultBytesToIntMapping(input);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return 0;
+    }
+  }
+
+  public static short BytesToShort(byte[] input) {
+    try {
+      return readNode.DefaultBytesToShortMapping(input);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return 0;
+    }
+  }
+
+  public static long BytesToLong(byte[] input) {
+    try {
+      return readNode.DefaultBytesToLongMapping(input);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return 0;
+    }
+  }
+
+  public static float BytesToFloat(byte[] input) {
+    try {
+      return readNode.DefaultBytesToFloatMapping(input);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return 0;
+    }
+  }
+
+  public static double BytesToDouble(byte[] input) {
+    try {
+      return readNode.DefaultBytesToDoubleMapping(input);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return 0;
+    }
+  }
+
+  public static char BytesToChar(byte[] input) {
+    try {
+      return readNode.DefaultBytesToCharMapping(input);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return 0;
+    }
+  }
+
+  public static String BytesToString(byte[] input) {
+    try {
+      return readNode.DefaultBytesToStringMapping(input);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return null;
+    }
+  }
+
+  public static byte[] BoolToBytes(boolean input) {
+    try {
+      return writeNode.DefaultBooleanToBytesMapping(input);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return null;
+    }
+  }
+
+  public static byte[] IntToBytes(int input) {
+    try {
+      return writeNode.DefaultIntToBytesMapping(input);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return null;
+    }
+  }
+
+  public static byte[] ShortToBytes(short input) {
+    try {
+      return writeNode.DefaultShortToBytesMapping(input);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return null;
+    }
+  }
+
+  public static byte[] LongToBytes(long input) {
+    try {
+      return writeNode.DefaultLongToBytesMapping(input);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return null;
+    }
+  }
+
+  public static byte[] FloatToBytes(float input) {
+    try {
+      return writeNode.DefaultFloatToBytesMapping(input);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return null;
+    }
+  }
+
+  public static byte[] DoubleToBytes(double input) {
+    try {
+      return writeNode.DefaultDoubleToBytesMapping(input);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return null;
+    }
+  }
+
+  public static byte[] CharToBytes(char input) {
+    try {
+      return writeNode.DefaultCharToBytesMapping(input);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return null;
+    }
+  }
+
+  public static byte[] StringToBytes(String input) {
+    try {
+      return writeNode.DefaultStringToBytesMapping(input);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return null;
+    }
+  }
+
+  public static <E extends Throwable> byte[] TreeToBytes(SerializeFunction<E> serializeFunction) throws E, IOException {
+    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+    JsonFactory factory = new JsonFactory();
+    JsonGenerator generator = factory.createGenerator(outputStream, JsonEncoding.UTF8);
+    serializeFunction.accept(generator, null);
+    generator.flush();
+    return outputStream.toString().getBytes();
+  }
+}
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/IntList.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/IntList.java
new file mode 100644
index 0000000..7dba3a4
--- /dev/null
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/IntList.java
@@ -0,0 +1,31 @@
+package org.jastadd.ragconnect.tests.utils;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * TODO: Add description.
+ *
+ * @author rschoene - Initial contribution
+ */
+public class IntList {
+  private final List<Integer> integers;
+
+  public IntList(Integer... values) {
+    integers = Arrays.stream(values).filter(Objects::nonNull).collect(Collectors.toList());
+  }
+
+  public List<Integer> toList() {
+    return integers;
+  }
+
+  public List<Integer> toAbsList() {
+    return integers.stream().map(Math::abs).collect(Collectors.toList());
+  }
+
+  public static IntList list(Integer... values) {
+    return new IntList(values);
+  }
+}
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/TestChecker.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/TestChecker.java
new file mode 100644
index 0000000..ed54fb9
--- /dev/null
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/TestChecker.java
@@ -0,0 +1,222 @@
+package org.jastadd.ragconnect.tests.utils;
+
+import org.assertj.core.groups.Tuple;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+ * Lean checking of constraints in tests.
+ *
+ * @author rschoene - Initial contribution
+ */
+public class TestChecker {
+  private static final Logger logger = LoggerFactory.getLogger(TestChecker.class);
+  private final static String NUMBER_OF_VALUES = "numberOfValues";
+  public final ValuesToCompare<Object> objectValues = new ValuesToCompare<>(this);
+  public final ValuesToCompare<String> stringValues = new ValuesToCompare<>(this);
+  public final ValuesToCompare<Tuple> tupleValues = new ValuesToCompare<>(this);
+  public final IntegerValuesToCompare intValues = new IntegerValuesToCompare(this);
+  private boolean needManualWait = true;
+  private boolean useManualWait = true;
+
+  public TestChecker incNumberOfValues() {
+    return intValues.incNumberOfValues();
+  }
+
+  public TestChecker addToNumberOfValues(int increment) {
+    return intValues.addToNumberOfValues(increment);
+  }
+
+  public TestChecker setActualNumberOfValues(Callable<Integer> actual) {
+    return intValues.setActualNumberOfValues(actual);
+  }
+
+  public TestChecker alwaysWait() {
+    return setActualNumberOfValues(() -> 0);
+  }
+
+  public TestChecker put(String name, Object expected) {
+    return objectValues.put(name, expected);
+  }
+
+  public TestChecker setCheckForObject(String name, BiConsumer<String, Object> check) {
+    return objectValues.setCheck(name, check);
+  }
+
+  public TestChecker setActualString(String name, Callable<String> actual) {
+    return stringValues.setActual(name, actual);
+  }
+
+  public TestChecker setCheckForString(String name, BiConsumer<String, String> check) {
+    return stringValues.setCheck(name, check);
+  }
+
+  public TestChecker put(String name, String expected) {
+    return stringValues.put(name, expected);
+  }
+
+  public TestChecker setActualTuple(String name, Callable<Tuple> actual) {
+    return tupleValues.setActual(name, actual);
+  }
+
+  public TestChecker setCheckForTuple(String name, BiConsumer<String, Tuple> check) {
+    return tupleValues.setCheck(name, check);
+  }
+
+  public TestChecker put(String name, Tuple expected) {
+    return tupleValues.put(name, expected);
+  }
+
+  public TestChecker setActualInteger(String name, Callable<Integer> actual) {
+    return intValues.setActual(name, actual);
+  }
+
+  public TestChecker setCheckForInteger(String name, BiConsumer<String, Integer> check) {
+    return intValues.setCheck(name, check);
+  }
+
+  public TestChecker put(String name, Integer expected) {
+    return intValues.put(name, expected);
+  }
+
+  public TestChecker disableManualWait() {
+    useManualWait = false;
+    needManualWait = false;
+    return this;
+  }
+
+  public void check() {
+    if (needManualWait) {
+      try {
+        TestUtils.waitForMqtt();
+      } catch (InterruptedException e) {
+        fail(e);
+      }
+    }
+    intValues.get(NUMBER_OF_VALUES).checkAwait(NUMBER_OF_VALUES);
+
+    objectValues.forEach((name, aae) -> aae.check(name));
+    stringValues.forEach((name, aae) -> aae.check(name));
+    tupleValues.forEach((name, aae) -> aae.check(name));
+    intValues.forEach((name, aae) -> {
+      if (!name.equals(NUMBER_OF_VALUES)) {
+        aae.check(name);
+      }
+    });
+    needManualWait = useManualWait;
+  }
+
+  static class ActualAndExpected<T> {
+    Callable<T> actual;
+    T expected;
+    BiConsumer<String, T> customCheck;
+
+    ActualAndExpected(String key) {
+      expected = null;
+    }
+
+    void check(String name) {
+      if (customCheck != null) {
+        customCheck.accept(name, expected);
+        return;
+      }
+      if (actual == null) {
+        fail("No actual getter defined for " + name);
+      }
+      T actualValue = null;
+      try {
+        actualValue = this.actual.call();
+      } catch (Exception e) {
+        fail(e);
+      }
+      assertThat(actualValue).as(name).isEqualTo(expected);
+    }
+
+    void checkAwait(String name) {
+      if (customCheck != null) {
+        logger.warn("Custom check set for {}. Can't await for that.", name);
+        customCheck.accept(name, expected);
+        return;
+      }
+      if (actual == null) {
+        fail("No actual getter defined for " + name);
+      }
+      TestUtils.awaitMqtt().alias(name + " == " + expected).until(actual, Predicate.isEqual(expected));
+    }
+  }
+
+  static class ValuesToCompare<T> {
+    protected final Map<String, ActualAndExpected<T>> values = new HashMap<>();
+    protected final TestChecker parent;
+
+    ValuesToCompare(TestChecker parent) {
+      this.parent = parent;
+    }
+
+    public TestChecker setActual(String name, Callable<T> actual) {
+      _computeIfAbsent(name).actual = actual;
+      return parent;
+    }
+
+    public TestChecker setCheck(String name, BiConsumer<String, T> check) {
+      _computeIfAbsent(name).customCheck = check;
+      return parent;
+    }
+
+    public TestChecker put(String name, T expected) {
+      _computeIfAbsent(name).expected = expected;
+      return parent;
+    }
+
+    public TestChecker updateExpected(String name, Function<T, T> updater) {
+      ActualAndExpected<T> aae = _computeIfAbsent(name);
+      aae.expected = updater.apply(aae.expected);
+      return parent;
+    }
+
+    private ActualAndExpected<T> _computeIfAbsent(String name) {
+      return values.computeIfAbsent(name, ActualAndExpected::new);
+    }
+
+    ActualAndExpected<T> get(String name) {
+      return values.get(name);
+    }
+
+    void forEach(BiConsumer<? super String, ? super ActualAndExpected<T>> action) {
+      values.forEach(action);
+    }
+  }
+
+  static class IntegerValuesToCompare extends ValuesToCompare<Integer> {
+    IntegerValuesToCompare(TestChecker parent) {
+      super(parent);
+    }
+
+    public TestChecker incNumberOfValues() {
+      return addToNumberOfValues(1);
+    }
+
+    public TestChecker addToNumberOfValues(int increment) {
+      // if there is at least one call to this, we do not need to manually wait in the next check()
+      parent.needManualWait = false;
+      Integer currentExpected = values.computeIfAbsent(NUMBER_OF_VALUES, ActualAndExpected::new).expected;
+      return put(NUMBER_OF_VALUES, currentExpected + increment);
+    }
+
+    public TestChecker setActualNumberOfValues(Callable<Integer> actual) {
+      setActual(NUMBER_OF_VALUES, actual);
+      values.get(NUMBER_OF_VALUES).expected = 0;
+      return parent;
+    }
+  }
+}
diff --git a/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/TestUtils.java b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/TestUtils.java
new file mode 100644
index 0000000..c77192b
--- /dev/null
+++ b/ragconnect.tests/src/test/java/org/jastadd/ragconnect/tests/utils/TestUtils.java
@@ -0,0 +1,181 @@
+package org.jastadd.ragconnect.tests.utils;
+
+import org.awaitility.Awaitility;
+import org.awaitility.core.ConditionFactory;
+import org.jastadd.ragconnect.compiler.Compiler;
+import org.junit.jupiter.api.Assertions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+ * Utility methods for tests.
+ *
+ * @author rschoene - Initial contribution
+ */
+public class TestUtils {
+
+  private static final Logger logger = LoggerFactory.getLogger(TestUtils.class);
+  public static final double DELTA = 0.001d;
+  public static final String INPUT_DIRECTORY_PREFIX = "./src/test/01-input/";
+  public static final String OUTPUT_DIRECTORY_PREFIX = "./src/test/02-after-ragconnect/";
+
+  public static boolean isCi() {
+    return System.getenv("GITLAB_CI") != null;
+  }
+
+  public static String getMqttHost() {
+    if (isCi()) {
+      // we are in the CI, so use "mqtt" as host
+      return "mqtt";
+    } {
+      // else assume a locally running mqtt broker
+      return "localhost";
+    }
+  }
+
+  public static String mqttUri(String path) {
+    return "mqtt://" + getMqttHost() + "/" + path;
+  }
+
+  public static String restUri(String path, int port) {
+    return "rest://localhost:" + port + "/" + path;
+  }
+
+  public static String javaUri(String path) {
+    return "java://localhost/" + path;
+  }
+
+  public static int getMqttDefaultPort() {
+    return 1883;
+  }
+
+  public static Path runCompiler(String grammarFile, Iterable<String> connectFiles, String rootNode, String outputDirectory, int expectedReturnValue, String... additionalArguments) {
+
+    assertThat(connectFiles).isNotEmpty();
+
+    Path outPath = Paths.get(OUTPUT_DIRECTORY_PREFIX)
+        .resolve(outputDirectory)
+        .resolve("Compiler.out");
+    ensureCreated(outPath.getParent());
+
+    try {
+      logger.debug("user.dir: {}", System.getProperty("user.dir"));
+      List<String> args = new ArrayList<>() {{
+        add("--o=" + OUTPUT_DIRECTORY_PREFIX + outputDirectory);
+        add("--rootNode=" + rootNode);
+        add("--verbose");
+        add(INPUT_DIRECTORY_PREFIX + grammarFile);
+      }};
+      connectFiles.forEach(connectFile -> args.add(INPUT_DIRECTORY_PREFIX + connectFile));
+      args.addAll(Arrays.asList(additionalArguments));
+
+      int returnValue = exec(Compiler.class, args.toArray(new String[0]), outPath.toFile());
+      Assertions.assertEquals(expectedReturnValue, returnValue, "RagConnect did not return with value " + expectedReturnValue);
+    } catch (IOException | InterruptedException e) {
+      fail(e);
+    }
+    return outPath;
+  }
+
+  public static <T> String prettyPrint(Iterable<T> aList, Function<T, String> elementPrinter) {
+    StringJoiner sj = new StringJoiner(", ", "[", "]");
+    aList.forEach(element -> sj.add(elementPrinter.apply(element)));
+    return sj.toString();
+  }
+
+  public static void assertLinesMatch(String directory, String expectedName, String out) throws IOException {
+    Path expectedPath = Paths.get(TestUtils.INPUT_DIRECTORY_PREFIX)
+            .resolve(directory)
+            .resolve(expectedName + ".expected");
+    String expected = readFile(expectedPath, Charset.defaultCharset());
+    List<String> outList = Arrays.asList(out.split("\n"));
+    Collections.sort(outList);
+    List<String> expectedList = Arrays.stream(expected.split("\n"))
+            .sorted()
+            .filter(s -> !s.isEmpty() && !s.startsWith("//"))
+            .collect(Collectors.toList());
+
+    Assertions.assertLinesMatch(expectedList, outList);
+  }
+
+  private static void ensureCreated(Path directory) {
+    File directoryFile = directory.toFile();
+    if (directoryFile.exists() && directoryFile.isDirectory()) {
+      return;
+    }
+    assertTrue(directoryFile.mkdirs());
+  }
+
+  public static int exec(Class<?> klass, String[] args, File err) throws IOException,
+      InterruptedException {
+    String javaHome = System.getProperty("java.home");
+    String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
+    String classpath = System.getProperty("java.class.path");
+    String className = klass.getName();
+
+    String[] newArgs = new String[args.length + 4];
+    newArgs[0] = javaBin;
+    newArgs[1] = "-cp";
+    newArgs[2] = classpath;
+    newArgs[3] = className;
+    System.arraycopy(args, 0, newArgs, 4, args.length);
+
+    ProcessBuilder builder = new ProcessBuilder(newArgs);
+//    builder.redirectOutput(err);
+    builder.redirectError(err);
+
+    Process process = builder.start();
+    process.waitFor();
+    return process.exitValue();
+  }
+
+  public static void testJaddContainReferenceToJackson(Path path, boolean shouldContain) {
+    try {
+      String content = Files.readString(path);
+      boolean actualContain = content.contains("com.fasterxml.jackson.databind.ObjectMapper");
+      if (actualContain && !shouldContain) {
+        fail(path + " should not depend on jackson library, but does");
+      }
+      if (!actualContain && shouldContain) {
+        fail(path + " does not depend on jackson library");
+      }
+    } catch (IOException e) {
+      fail(e);
+    }
+  }
+
+  public static String readFile(Path path, Charset encoding)
+      throws IOException {
+    byte[] encoded = Files.readAllBytes(path);
+    return new String(encoded, encoding);
+  }
+
+  public static void waitForMqtt() throws InterruptedException {
+    TimeUnit.MILLISECONDS.sleep(1500);
+  }
+
+  public static ConditionFactory awaitMqtt() {
+    return Awaitility.await().atMost(1500, TimeUnit.MILLISECONDS);
+  }
+
+  static <T_Event, T_ASTNode> void logEvent(T_Event event, T_ASTNode node, String attribute, Object params, Object value) {
+    logger.info("event: {}, node: {}, attribute: {}, params: {}, value: {}",
+            event, node, attribute, params, value);
+  }
+
+}
-- 
GitLab