diff --git a/ros2rag.tests/build.gradle b/ros2rag.tests/build.gradle
index 4c7b77325d42f51dfbca73da3da2c16a4498fa4d..3357c81de76caa277188c3f953da52403d1194bb 100644
--- a/ros2rag.tests/build.gradle
+++ b/ros2rag.tests/build.gradle
@@ -177,6 +177,37 @@ task compileRead1Write2Test(type: RelastTest) {
 test.dependsOn compileRead1Write2Test
 compileRead1Write2Test.dependsOn preprocessRead1Write2Test
 
+// --- Test: read2write1 ---
+task preprocessRead2Write1Test(type: JavaExec, group: 'verification') {
+    doFirst {
+        delete 'src/test/02-after-ros2rag/read2write1/Grammar.relast',
+                'src/test/02-after-ros2rag/read2write1/MqttUpdater.java',
+                'src/test/02-after-ros2rag/read2write1/ROS2RAG.jadd'
+    }
+
+    classpath = sourceSets.main.runtimeClasspath
+    main = 'org.jastadd.ros2rag.compiler.Compiler'
+    args '--outputDir=src/test/02-after-ros2rag/read2write1',
+            '--inputGrammar=src/test/01-input/read2write1/Example.relast',
+            '--inputRos2Rag=src/test/01-input/read2write1/Example.ros2rag',
+            '--rootNode=A', '--verbose',
+            '--logReads', '--logWrites'
+}
+
+task compileRead2Write1Test(type: RelastTest) {
+    useJastAddNames = true
+    jastAddList = 'JastAddList'
+    relastFiles 'src/test/02-after-ros2rag/read2write1/Grammar.relast'
+    grammarName = 'src/test/03-after-relast/read2write1/read2write1'
+    packageName = 'read2write1.ast'
+    moreInputFiles 'src/test/01-input/read2write1/Example.jadd',
+            'src/test/02-after-ros2rag/read2write1/MqttUpdater.jadd',
+            'src/test/02-after-ros2rag/read2write1/ROS2RAG.jadd'
+}
+
+test.dependsOn compileRead2Write1Test
+compileRead2Write1Test.dependsOn preprocessRead2Write1Test
+
 clean {
     delete 'src/test/02-after-ros2rag/*/', 'src/test/03-after-relast/*/'
 }
diff --git a/ros2rag.tests/src/test/01-input/read2write1/Example.jadd b/ros2rag.tests/src/test/01-input/read2write1/Example.jadd
new file mode 100644
index 0000000000000000000000000000000000000000..4d31f1a6441311469f8f93cd150e6c8bb353877e
--- /dev/null
+++ b/ros2rag.tests/src/test/01-input/read2write1/Example.jadd
@@ -0,0 +1,11 @@
+aspect Computation{
+  // OnSameNonterminal
+  syn int OnSameNonterminal.getOutInteger() = Integer.parseInt(getInput1() + getInput2());
+
+  // OnDifferentNonterminal
+  syn int TheOther.getOutInteger() = Integer.parseInt(input1() + input2());
+  inh String TheOther.input1();
+  eq OnDifferentNonterminal.getTheOther().input1() = getInput1();
+  inh String TheOther.input2();
+  eq OnDifferentNonterminal.getTheOther().input2() = getInput2();
+}
diff --git a/ros2rag.tests/src/test/01-input/read2write1/Example.relast b/ros2rag.tests/src/test/01-input/read2write1/Example.relast
new file mode 100644
index 0000000000000000000000000000000000000000..afe0125760afe222c830f383536f6e2f97c8f656
--- /dev/null
+++ b/ros2rag.tests/src/test/01-input/read2write1/Example.relast
@@ -0,0 +1,4 @@
+A ::= OnSameNonterminal OnDifferentNonterminal ;
+OnSameNonterminal ::= <Input1:String> <Input2:String> /<OutInteger:int>/ ;
+OnDifferentNonterminal ::= <Input1:String> <Input2:String> TheOther* ;
+TheOther ::= /<OutInteger:int>/ ;
diff --git a/ros2rag.tests/src/test/01-input/read2write1/Example.ros2rag b/ros2rag.tests/src/test/01-input/read2write1/Example.ros2rag
new file mode 100644
index 0000000000000000000000000000000000000000..4575a5b547366d8c9737d5c8478e1a4fb821e9a6
--- /dev/null
+++ b/ros2rag.tests/src/test/01-input/read2write1/Example.ros2rag
@@ -0,0 +1,18 @@
+// --- update definitions ---
+// OnSameNonterminal
+read OnSameNonterminal.Input1;
+read OnSameNonterminal.Input2;
+write OnSameNonterminal.OutInteger;
+
+// OnDifferentNonterminal
+read OnDifferentNonterminal.Input1;
+read OnDifferentNonterminal.Input2;
+write TheOther.OutInteger;
+
+// --- dependency definitions ---
+// OnSameNonterminal
+OnSameNonterminal.OutInteger canDependOn OnSameNonterminal.Input1 as Int1Dependency;
+OnSameNonterminal.OutInteger canDependOn OnSameNonterminal.Input2 as Int2Dependency;
+// OnDifferentNonterminal
+TheOther.OutInteger canDependOn OnDifferentNonterminal.Input1 as Int1Dependency;
+TheOther.OutInteger canDependOn OnDifferentNonterminal.Input2 as Int2Dependency;
diff --git a/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/Read2Write1Test.java b/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/Read2Write1Test.java
new file mode 100644
index 0000000000000000000000000000000000000000..a094b671f21c3bf168ebec37a829ec981f45b5d1
--- /dev/null
+++ b/ros2rag.tests/src/test/java/org/jastadd/ros2rag/tests/Read2Write1Test.java
@@ -0,0 +1,241 @@
+package org.jastadd.ros2rag.tests;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+import read2write1.ast.*;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test case "read-1-write-2".
+ *
+ * @author rschoene - Initial contribution
+ */
+public class Read2Write1Test extends AbstractMqttTest {
+
+  private static final String TOPIC_SAME_READ1 = "same/read1";
+  private static final String TOPIC_SAME_READ2 = "same/read2";
+  private static final String TOPIC_SAME_WRITE_INT = "same/write/int";
+  private static final String TOPIC_DIFFERENT_READ1 = "different/read1";
+  private static final String TOPIC_DIFFERENT_READ2 = "different/read2";
+  private static final String TOPIC_DIFFERENT_WRITE1_INT = "different/write1/int";
+  private static final String TOPIC_DIFFERENT_WRITE2_INT = "different/write2/int";
+  private static final String INITIAL_VALUE = "0";
+
+  private MqttUpdater handler;
+  private A model;
+  private OnSameNonterminal onSameNonterminal;
+  private OnDifferentNonterminal onDifferentNonterminal;
+  private TheOther other1;
+  private TheOther other2;
+
+  private ReceiverData dataSame;
+  private ReceiverData dataOther1;
+  private ReceiverData dataOther2;
+
+  @AfterEach
+  public void closeConnections() {
+    if (handler != null) {
+      handler.close();
+    }
+    if (model != null) {
+      model.MqttCloseConnections();
+    }
+  }
+
+  @Test
+  public void buildModel() {
+    createModel();
+  }
+
+  @Test
+  public void communicateSendInitialValue() throws IOException, InterruptedException {
+    createModel();
+    setupReceiverAndConnect(true);
+
+    // check initial value
+    TimeUnit.SECONDS.sleep(2);
+    checkData(1, Integer.parseInt(INITIAL_VALUE + INITIAL_VALUE),
+        1, Integer.parseInt(INITIAL_VALUE + INITIAL_VALUE));
+
+    // set new value
+    sendData(true, "2", true, "3");
+
+    // check new value. same: 2, 0. different: 3, 0.
+    TimeUnit.SECONDS.sleep(2);
+    checkData(2, 20,
+        2, 30);
+
+    // set new value
+    sendData(false, "4", false, "4");
+
+    // check new value. same: 2, 4. different: 3, 4.
+    TimeUnit.SECONDS.sleep(2);
+    checkData(3, 24,
+        3, 34);
+
+    // set new value only for same
+    setDataOnlySame(true, "77");
+
+    // check new value. same: 77, 4. different: 3, 4.
+    TimeUnit.SECONDS.sleep(2);
+    checkData(4, 774,
+        3, 34);
+  }
+
+  private String prefixed(String s) {
+    return "prefix" + s;
+  }
+
+  @Test
+  public void communicateOnlyUpdatedValue() throws IOException, InterruptedException {
+    createModel();
+    setupReceiverAndConnect(false);
+
+    // check initial value
+    TimeUnit.SECONDS.sleep(2);
+    checkData(0, null,
+        0, null);
+
+    // set new value
+    sendData(true, "2", true, "3");
+
+    // check new value. same: 2, 0. different: 3, 0.
+    TimeUnit.SECONDS.sleep(2);
+    checkData(1, 20,
+        1, 30);
+
+    // set new value
+    sendData(false, "4", false, "4");
+
+    // check new value. same: 2, 4. different: 3, 4.
+    TimeUnit.SECONDS.sleep(2);
+    checkData(2, 24,
+        2, 34);
+
+    // set new value only for same
+    setDataOnlySame(true, "77");
+
+    // check new value. same: 77, 4. different: 3, 4.
+    TimeUnit.SECONDS.sleep(2);
+    checkData(3, 774,
+        2, 34);
+  }
+
+  private void createModel() {
+    // Setting value for Input without dependencies does not trigger any updates
+    model = new A();
+
+    onSameNonterminal = new OnSameNonterminal();
+    model.setOnSameNonterminal(onSameNonterminal);
+    onSameNonterminal.setInput1(INITIAL_VALUE);
+    onSameNonterminal.setInput2(INITIAL_VALUE);
+
+    onDifferentNonterminal = new OnDifferentNonterminal();
+    other1 = new TheOther();
+    other2 = new TheOther();
+    onDifferentNonterminal.addTheOther(other1);
+    onDifferentNonterminal.addTheOther(other2);
+    model.setOnDifferentNonterminal(onDifferentNonterminal);
+    onDifferentNonterminal.setInput1(INITIAL_VALUE);
+    onDifferentNonterminal.setInput2(INITIAL_VALUE);
+  }
+
+  private void setupReceiverAndConnect(boolean writeCurrentValue) throws IOException {
+    model.MqttSetHost(TestUtils.getMqttHost());
+    assertTrue(model.MqttWaitUntilReady(2, TimeUnit.SECONDS));
+
+    handler = new MqttUpdater().dontSendWelcomeMessage().setHost(TestUtils.getMqttHost());
+    assertTrue(handler.waitUntilReady(2, TimeUnit.SECONDS));
+
+    onSameNonterminal.addInt1Dependency(onSameNonterminal);
+    onSameNonterminal.addInt2Dependency(onSameNonterminal);
+    other1.addInt1Dependency(onDifferentNonterminal);
+    other1.addInt2Dependency(onDifferentNonterminal);
+    other2.addInt1Dependency(onDifferentNonterminal);
+    other2.addInt2Dependency(onDifferentNonterminal);
+
+    dataSame = new Read2Write1Test.ReceiverData();
+    dataOther1 = new Read2Write1Test.ReceiverData();
+    dataOther2 = new Read2Write1Test.ReceiverData();
+
+    handler.newConnection(TOPIC_SAME_WRITE_INT, bytes -> {
+      dataSame.numberOfIntValues += 1;
+      dataSame.lastIntValue = java.nio.ByteBuffer.wrap(bytes).getInt();
+    });
+
+    handler.newConnection(TOPIC_DIFFERENT_WRITE1_INT, bytes -> {
+      dataOther1.numberOfIntValues += 1;
+      dataOther1.lastIntValue = java.nio.ByteBuffer.wrap(bytes).getInt();
+    });
+
+    handler.newConnection(TOPIC_DIFFERENT_WRITE2_INT, bytes -> {
+      dataOther2.numberOfIntValues += 1;
+      dataOther2.lastIntValue = java.nio.ByteBuffer.wrap(bytes).getInt();
+    });
+
+    onSameNonterminal.connectInput1(TOPIC_SAME_READ1);
+    onSameNonterminal.connectInput2(TOPIC_SAME_READ2);
+    onSameNonterminal.connectOutInteger(TOPIC_SAME_WRITE_INT, writeCurrentValue);
+
+    onDifferentNonterminal.connectInput1(TOPIC_DIFFERENT_READ1);
+    onDifferentNonterminal.connectInput2(TOPIC_DIFFERENT_READ2);
+    other1.connectOutInteger(TOPIC_DIFFERENT_WRITE1_INT, writeCurrentValue);
+    other2.connectOutInteger(TOPIC_DIFFERENT_WRITE2_INT, writeCurrentValue);
+  }
+
+  private void sendData(boolean useSameInput1, String inputSame,
+                        boolean useDifferentInput1, String inputDifferent) {
+    handler.publish(useSameInput1 ? TOPIC_SAME_READ1 : TOPIC_SAME_READ2,
+        inputSame.getBytes());
+    handler.publish(useDifferentInput1 ? TOPIC_DIFFERENT_READ1 : TOPIC_DIFFERENT_READ2,
+        inputDifferent.getBytes());
+  }
+
+  private void setDataOnlySame(boolean useSameInput1, String inputSame) {
+    handler.publish(useSameInput1 ? TOPIC_SAME_READ1 : TOPIC_DIFFERENT_READ2,
+        inputSame.getBytes());
+  }
+
+  private void checkData(int numberOfSameValues, Integer lastSameIntValue,
+                         int numberOfDifferentValues, Integer lastDifferentIntValue) {
+    /* the value "-2" is never used in the test, so a test will always fail comparing to this value
+     especially, it is not the initial value */
+    ReceiverData expectedDataSame = ReceiverData.of(
+        numberOfSameValues,
+        lastSameIntValue != null ? lastSameIntValue : -2
+    );
+    compareData(expectedDataSame, dataSame);
+    ReceiverData expectedDataDifferent = ReceiverData.of(
+        numberOfDifferentValues,
+        lastDifferentIntValue != null ? lastDifferentIntValue : -2
+    );
+    compareData(expectedDataDifferent, dataOther1);
+    compareData(expectedDataDifferent, dataOther2);
+  }
+
+  private void compareData(ReceiverData expectedData,
+                         ReceiverData actual) {
+    assertEquals(expectedData.numberOfIntValues, actual.numberOfIntValues);
+    if (expectedData.numberOfIntValues > 0) {
+      assertEquals(expectedData.lastIntValue, actual.lastIntValue);
+    }
+  }
+
+  private static class ReceiverData {
+    int lastIntValue;
+    int numberOfIntValues = 0;
+
+    static ReceiverData of(int numberOfValues, int lastIntValue) {
+      ReceiverData result = new ReceiverData();
+      result.lastIntValue = lastIntValue;
+      result.numberOfIntValues = numberOfValues;
+      return result;
+    }
+  }
+
+}